206 lines
6.5 KiB
C++
206 lines
6.5 KiB
C++
#include "types.hpp"
|
|
#include <SDL3/SDL.h>
|
|
#include <SDL3_image/SDL_image.h>
|
|
#include <cmath>
|
|
|
|
#define destroyer_width 58
|
|
#define destroyer_height 512
|
|
|
|
int main() {
|
|
SDL_Init(SDL_INIT_VIDEO);
|
|
SDL_Window *window =
|
|
SDL_CreateWindow("Naval Swarm", SCREEN_WIDTH, SCREEN_HEIGHT, 0);
|
|
SDL_Renderer *renderer = SDL_CreateRenderer(window, "gpu,vulcan");
|
|
|
|
// Load textures
|
|
SDL_Texture *spriteSheet = IMG_LoadTexture(renderer, "assets/destroyer.svg");
|
|
SDL_Texture *bgTexture = IMG_LoadTexture(renderer, "assets/background.png");
|
|
|
|
// Initialize player
|
|
Entity destroyer;
|
|
destroyer.texture = spriteSheet;
|
|
destroyer.set_offset(destroyer_width / 2, destroyer_height / 2);
|
|
destroyer.position() = {WORLD_WIDTH / 2.0f, WORLD_HEIGHT / 2.0f, 58.0f,
|
|
512.0f};
|
|
destroyer.srcRect = {0, 0, destroyer_width,
|
|
destroyer_height}; // Static source rectangle
|
|
destroyer.angle = 0;
|
|
|
|
// Initialize camera
|
|
Camera camera;
|
|
bool running = true;
|
|
Uint64 lastFrameTime = SDL_GetTicksNS();
|
|
float deltaTime = 0.0f;
|
|
|
|
while (running) {
|
|
const Uint64 frameStart = SDL_GetTicksNS();
|
|
|
|
// Event handling
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event)) {
|
|
if (event.type == SDL_EVENT_QUIT)
|
|
running = false;
|
|
if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
|
|
// Check specific button (e.g., left mouse button)
|
|
if (event.button.button == SDL_BUTTON_LEFT) {
|
|
printf("Left mouse clicked at (%.1f, %.1f)\nCamera position: (%.1f, "
|
|
"%.1f)\nTarget position: (%.1f, %.1f)\n",
|
|
event.button.x, event.button.y, camera.view.x, camera.view.y,
|
|
camera.view.x + event.button.x,
|
|
camera.view.y + event.button.y);
|
|
destroyer.Tposition.x = camera.view.x + event.button.x;
|
|
destroyer.Tposition.y = camera.view.y + event.button.y;
|
|
destroyer.gotoT = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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)) {
|
|
camera.followPlayer = !camera.followPlayer;
|
|
lastToggle = SDL_GetTicks();
|
|
}
|
|
|
|
// Player movement
|
|
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;
|
|
}
|
|
}
|
|
|
|
float step = destroyer.speed * deltaTime;
|
|
destroyer.position().x += (float)moveX * step;
|
|
destroyer.position().y += (float)moveY * step;
|
|
|
|
if (destroyer.gotoT) {
|
|
float dx = destroyer.Tposition.x - destroyer.position().x;
|
|
float dy = destroyer.Tposition.y - destroyer.position().y;
|
|
|
|
destroyer.angle = std::atan2(dy, dx) * 180 / M_PI;
|
|
|
|
float distance = std::sqrt(dx * dx + dy * dy);
|
|
if (distance > 0) {
|
|
dx /= distance;
|
|
dy /= distance;
|
|
|
|
if (distance <= step) {
|
|
destroyer.position().x = destroyer.Tposition.x;
|
|
destroyer.position().y = destroyer.Tposition.y;
|
|
} else {
|
|
destroyer.position().x += dx * step;
|
|
destroyer.position().y += dy * step;
|
|
}
|
|
|
|
} else {
|
|
destroyer.gotoT = false;
|
|
}
|
|
}
|
|
|
|
// Camera movement
|
|
if (camera.followPlayer) {
|
|
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 {
|
|
float camMoveX = keystate[SDL_SCANCODE_D] - keystate[SDL_SCANCODE_A];
|
|
float camMoveY = keystate[SDL_SCANCODE_S] - keystate[SDL_SCANCODE_W];
|
|
camera.view.x += camMoveX * camera.speed * deltaTime;
|
|
camera.view.y += camMoveY * camera.speed * deltaTime;
|
|
}
|
|
|
|
// World bounds
|
|
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 HERE
|
|
|
|
// Rendering
|
|
SDL_SetRenderDrawColor(renderer, 30, 30, 45, 255);
|
|
SDL_RenderClear(renderer);
|
|
|
|
// Draw background
|
|
if (bgTexture) {
|
|
SDL_FRect bgDest = {-camera.view.x, -camera.view.y, WORLD_WIDTH,
|
|
WORLD_HEIGHT};
|
|
SDL_RenderTexture(renderer, bgTexture, NULL, &bgDest);
|
|
}
|
|
|
|
// Draw player (simplified without animation)
|
|
SDL_FRect srcFRect;
|
|
SDL_RectToFRect(&destroyer.srcRect, &srcFRect);
|
|
SDL_FRect destRect = {destroyer.position().x - camera.view.x,
|
|
destroyer.position().y - camera.view.y,
|
|
destroyer.position().w, destroyer.position().h};
|
|
SDL_RenderTextureRotated(renderer, destroyer.texture, &srcFRect, &destRect,
|
|
destroyer.angle, nullptr, SDL_FLIP_NONE);
|
|
|
|
SDL_RenderPresent(renderer);
|
|
|
|
// Frame timing (unchanged)
|
|
const Uint64 frameTime = SDL_GetTicksNS() - frameStart;
|
|
if (frameTime < TARGET_FRAME_TIME_NS) {
|
|
const Uint64 sleepTime = TARGET_FRAME_TIME_NS - frameTime;
|
|
SDL_DelayNS(sleepTime - 2'000'000);
|
|
while (SDL_GetTicksNS() - frameStart < TARGET_FRAME_TIME_NS) {
|
|
}
|
|
}
|
|
|
|
deltaTime = (SDL_GetTicksNS() - lastFrameTime) / 1e9f;
|
|
lastFrameTime = SDL_GetTicksNS();
|
|
}
|
|
|
|
// Cleanup
|
|
SDL_DestroyTexture(spriteSheet);
|
|
SDL_DestroyTexture(bgTexture);
|
|
SDL_DestroyRenderer(renderer);
|
|
SDL_DestroyWindow(window);
|
|
SDL_Quit();
|
|
return 0;
|
|
}
|