diff --git a/.gitignore b/.gitignore index d163863..01f9cb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -build/ \ No newline at end of file +build/ +.vscode/ \ No newline at end of file diff --git a/Makefile b/Makefile index 9435041..81bcfc1 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,8 @@ # Compiler and flags CPPC = g++ -CPPC_FLAGS = -std=c++23 -s -O3 -Wall -Wextra -lSDL3 -lSDL3_image +#CPPC_FLAGS = -std=c++23 -s -O3 -Wall -Wextra -lSDL3 -lSDL3_image # Debug flags: -#CPPC_FLAGS = $(CPPC_FLAGS) -ggdb - +CPPC_FLAGS = -std=c++23 -ggdb -Wall -Wextra -lSDL3 -lSDL3_image SRC_PATH := src OBJ_PATH := build/obj diff --git a/src/main.cpp b/src/main.cpp index c266001..cda331e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include #include +#include "types.hpp" constexpr int SCREEN_WIDTH = 800; constexpr int SCREEN_HEIGHT = 600; @@ -8,18 +9,12 @@ constexpr int WORLD_HEIGHT = 1200; constexpr int TARGET_FPS = 60; constexpr Uint64 TARGET_FRAME_TIME_NS = 1'000'000'000 / TARGET_FPS; -struct Animation { - SDL_Rect frames[4]; - int currentFrame = 0; - Uint32 frameDuration = 100; - Uint32 lastFrameTime = 0; -}; - struct Entity { SDL_FRect position; SDL_Texture* texture; - Animation animation; + SDL_Rect srcRect; float speed = 250.0f; + Angle360 Angle; }; struct Camera { @@ -35,16 +30,15 @@ int main() { SDL_Renderer* renderer = SDL_CreateRenderer(window, "gpu,vulcan"); // Load textures - SDL_Texture* spriteSheet = IMG_LoadTexture(renderer, "assets/spritesheet.png"); + SDL_Texture* spriteSheet = IMG_LoadTexture(renderer, "assets/destroyer.svg"); SDL_Texture* bgTexture = IMG_LoadTexture(renderer, "assets/background.png"); - + // Initialize player - Entity player; - player.texture = spriteSheet; - player.position = {WORLD_WIDTH/2.0f, WORLD_HEIGHT/2.0f, 64.0f, 64.0f}; - for(int i = 0; i < 4; i++) { - player.animation.frames[i] = {i * 64, 0, 64, 64}; - } + Entity destroyer; + destroyer.texture = spriteSheet; + destroyer.position = {WORLD_WIDTH/2.0f, WORLD_HEIGHT/2.0f, 58.0f, 512.0f}; + destroyer.srcRect = {0, 0, 58, 512}; // Static source rectangle + destroyer.Angle = 0; // Initialize camera Camera camera; @@ -54,7 +48,7 @@ int main() { while (running) { const Uint64 frameStart = SDL_GetTicksNS(); - + // Event handling SDL_Event event; while (SDL_PollEvent(&event)) { @@ -63,7 +57,7 @@ int main() { // Input handling const bool* keystate = SDL_GetKeyboardState(NULL); - + // Toggle camera mode with C key static Uint32 lastToggle = 0; if (keystate[SDL_SCANCODE_C] && (SDL_GetTicks() - lastToggle > 200)) { @@ -72,20 +66,56 @@ int main() { } // Player movement - float moveX = keystate[SDL_SCANCODE_RIGHT] - keystate[SDL_SCANCODE_LEFT]; - float moveY = keystate[SDL_SCANCODE_DOWN] - keystate[SDL_SCANCODE_UP]; - player.position.x += moveX * player.speed * deltaTime; - player.position.y += moveY * player.speed * deltaTime; + int moveX = keystate[SDL_SCANCODE_RIGHT] - keystate[SDL_SCANCODE_LEFT]; + int moveY = keystate[SDL_SCANCODE_DOWN] - keystate[SDL_SCANCODE_UP]; + + // There is propably more eficient way to do this + switch (moveX) { + case 1: + switch (moveY) { + case 1: + destroyer.Angle = 135; + break; + case -1: + destroyer.Angle = 45; + break; + default: + destroyer.Angle = 90; + } + break; + case -1: + switch (moveY) { + case 1: + destroyer.Angle = 225; + break; + case -1: + destroyer.Angle = 315; + break; + default: + destroyer.Angle = 270; + } + break; + default: + switch (moveY) { + case 1: + destroyer.Angle = 180; + break; + case -1: + destroyer.Angle = 0; + break; + } + } + + destroyer.position.x += (float)moveX * destroyer.speed * deltaTime; + destroyer.position.y += (float)moveY * destroyer.speed * deltaTime; // Camera movement if (camera.followPlayer) { - // Smooth follow - float targetX = player.position.x + player.position.w/2 - camera.view.w/2; - float targetY = player.position.y + player.position.h/2 - camera.view.h/2; + float targetX = destroyer.position.x + destroyer.position.w/2 - camera.view.w/2; + float targetY = destroyer.position.y + destroyer.position.h/2 - camera.view.h/2; camera.view.x += (targetX - camera.view.x) * camera.smoothness; camera.view.y += (targetY - camera.view.y) * camera.smoothness; } else { - // Manual camera control with IJKL float camMoveX = keystate[SDL_SCANCODE_L] - keystate[SDL_SCANCODE_J]; float camMoveY = keystate[SDL_SCANCODE_K] - keystate[SDL_SCANCODE_I]; camera.view.x += camMoveX * camera.speed * deltaTime; @@ -93,21 +123,12 @@ int main() { } // World bounds - player.position.x = SDL_clamp(player.position.x, 0.0f, WORLD_WIDTH - player.position.w); - player.position.y = SDL_clamp(player.position.y, 0.0f, WORLD_HEIGHT - player.position.h); + destroyer.position.x = SDL_clamp(destroyer.position.x, 0.0f, WORLD_WIDTH - destroyer.position.w); + destroyer.position.y = SDL_clamp(destroyer.position.y, 0.0f, WORLD_HEIGHT - destroyer.position.h); camera.view.x = SDL_clamp(camera.view.x, 0.0f, WORLD_WIDTH - camera.view.w); camera.view.y = SDL_clamp(camera.view.y, 0.0f, WORLD_HEIGHT - camera.view.h); - - // Animation update - if (moveX != 0 || moveY != 0) { - Uint32 now = SDL_GetTicks(); - if (now - player.animation.lastFrameTime > player.animation.frameDuration) { - player.animation.currentFrame = (player.animation.currentFrame + 1) % 4; - player.animation.lastFrameTime = now; - } - } else { - player.animation.currentFrame = 0; - } + + //ANIMATION HERE // Rendering SDL_SetRenderDrawColor(renderer, 30, 30, 45, 255); @@ -119,20 +140,20 @@ int main() { SDL_RenderTexture(renderer, bgTexture, NULL, &bgDest); } - // Draw player + // Draw player (simplified without animation) SDL_FRect srcFRect; - SDL_RectToFRect(&player.animation.frames[player.animation.currentFrame], &srcFRect); + SDL_RectToFRect(&destroyer.srcRect, &srcFRect); SDL_FRect destRect = { - player.position.x - camera.view.x, - player.position.y - camera.view.y, - player.position.w, - player.position.h + destroyer.position.x - camera.view.x, + destroyer.position.y - camera.view.y, + destroyer.position.w, + destroyer.position.h }; - SDL_RenderTextureRotated(renderer, player.texture, &srcFRect, &destRect, 0.0, nullptr, SDL_FLIP_NONE); - + SDL_RenderTextureRotated(renderer, destroyer.texture, &srcFRect, &destRect, destroyer.Angle, nullptr, SDL_FLIP_NONE); + SDL_RenderPresent(renderer); - // Frame timing + // Frame timing (unchanged) const Uint64 frameTime = SDL_GetTicksNS() - frameStart; if (frameTime < TARGET_FRAME_TIME_NS) { const Uint64 sleepTime = TARGET_FRAME_TIME_NS - frameTime; diff --git a/src/types.hpp b/src/types.hpp new file mode 100644 index 0000000..6d99151 --- /dev/null +++ b/src/types.hpp @@ -0,0 +1,46 @@ +#include +#include +#include + +struct Angle360 { + private: + int value{0}; + + void normalize() { + value %= 360; + if (value < 0) value += 360; // Handle negative values + } + + public: + // Constructor + Angle360(int val = 0) : value(val) { normalize(); } + + // Assignment operator + Angle360& operator=(int val) { + value = val; + normalize(); + return *this; + } + + // Compound assignment + Angle360& operator+=(int rhs) { + value += rhs; + normalize(); + return *this; + } + + Angle360& operator-=(int rhs) { + value -= rhs; + normalize(); + return *this; + } + + // Type conversion + operator int() const { return value; } + + // Stream output + friend std::ostream& operator<<(std::ostream& os, const Angle360& a) { + return os << a.value; + } + }; + \ No newline at end of file