add rotation

This commit is contained in:
PoliEcho 2025-02-15 12:29:44 +01:00
parent 99916d9ab7
commit 1f8aa8e55c
4 changed files with 119 additions and 52 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
build/
build/
.vscode/

View File

@ -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

View File

@ -1,5 +1,6 @@
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#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;

46
src/types.hpp Normal file
View File

@ -0,0 +1,46 @@
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <iostream>
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;
}
};