add rotation
This commit is contained in:
parent
99916d9ab7
commit
1f8aa8e55c
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,2 @@
|
||||
build/
|
||||
build/
|
||||
.vscode/
|
5
Makefile
5
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
|
||||
|
117
src/main.cpp
117
src/main.cpp
@ -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
46
src/types.hpp
Normal 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;
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user