add main.cpp and Makefile
This commit is contained in:
parent
7db9f1fa89
commit
8d33ba71ff
38
Makefile
Normal file
38
Makefile
Normal file
@ -0,0 +1,38 @@
|
||||
# Compiler and flags
|
||||
CPPC = g++
|
||||
CPPC_FLAGS = -std=c++23 -s -O3 -Wall -Wextra -lSDL3 -lSDL3_image
|
||||
# Debug flags:
|
||||
#CPPC_FLAGS = $(CPPC_FLAGS) -ggdb
|
||||
|
||||
|
||||
SRC_PATH := src
|
||||
OBJ_PATH := build/obj
|
||||
BIN_PATH := build/bin
|
||||
|
||||
|
||||
SRC_FILES := $(shell find $(SRC_PATH) -name '*.cpp')
|
||||
# Generate corresponding object file paths by replacing src/ with build/obj/
|
||||
OBJ_FILES := $(patsubst $(SRC_PATH)/%.cpp,$(OBJ_PATH)/%.o,$(SRC_FILES))
|
||||
|
||||
|
||||
|
||||
all: make-build-dir $(BIN_PATH)/naval_swarm
|
||||
|
||||
|
||||
make-build-dir:
|
||||
mkdir -p $(OBJ_PATH)
|
||||
mkdir -p $(BIN_PATH)
|
||||
|
||||
|
||||
$(BIN_PATH)/naval_swarm: $(OBJ_FILES)
|
||||
$(CPPC) $(CPPC_FLAGS) $^ -o $@
|
||||
|
||||
|
||||
$(OBJ_PATH)/%.o: $(SRC_PATH)/%.cpp
|
||||
$(CPPC) $(CPPC_FLAGS) -c $< -o $@
|
||||
|
||||
|
||||
clean:
|
||||
rm -fr build
|
||||
|
||||
.PHONY: all clean make-build-dir
|
154
src/main.cpp
Normal file
154
src/main.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
|
||||
constexpr int SCREEN_WIDTH = 800;
|
||||
constexpr int SCREEN_HEIGHT = 600;
|
||||
constexpr int WORLD_WIDTH = 1600;
|
||||
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;
|
||||
float speed = 250.0f;
|
||||
};
|
||||
|
||||
struct Camera {
|
||||
SDL_FRect view = {0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT};
|
||||
bool followPlayer = true;
|
||||
float speed = 500.0f;
|
||||
float smoothness = 0.1f;
|
||||
};
|
||||
|
||||
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/spritesheet.png");
|
||||
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};
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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
|
||||
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;
|
||||
|
||||
// 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;
|
||||
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;
|
||||
camera.view.y += camMoveY * camera.speed * deltaTime;
|
||||
}
|
||||
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
SDL_FRect srcFRect;
|
||||
SDL_RectToFRect(&player.animation.frames[player.animation.currentFrame], &srcFRect);
|
||||
SDL_FRect destRect = {
|
||||
player.position.x - camera.view.x,
|
||||
player.position.y - camera.view.y,
|
||||
player.position.w,
|
||||
player.position.h
|
||||
};
|
||||
SDL_RenderTextureRotated(renderer, player.texture, &srcFRect, &destRect, 0.0, nullptr, SDL_FLIP_NONE);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
// Frame timing
|
||||
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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user