Compare commits
8 Commits
87c6b5abdf
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| d24f097223 | |||
| d3cb22a278 | |||
| efecc44a52 | |||
| 4dd53284ca | |||
| 32dd6dfce7 | |||
| 99e637fc8b | |||
| 73a7be3f43 | |||
| 2dfcc72343 |
+10
-10
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"ships": [
|
||||
{
|
||||
"destroyer": {
|
||||
"texture": "assets/entities/ships/destroyer.svg",
|
||||
"width": 58,
|
||||
"height": 512
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
"ship": {
|
||||
"destroyer": {
|
||||
"texture": "assets/entities/ships/destroyer.svg",
|
||||
"width": 58,
|
||||
"height": 512,
|
||||
"speed": 250
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
#ifndef RESET
|
||||
|
||||
#define RESET "\033[0m"
|
||||
#define BLACK "\033[30m" /* Black */
|
||||
#define RED "\033[31m" /* Red */
|
||||
#define GREEN "\033[32m" /* Green */
|
||||
#define YELLOW "\033[33m" /* Yellow */
|
||||
#define BLUE "\033[34m" /* Blue */
|
||||
#define MAGENTA "\033[35m" /* Magenta */
|
||||
#define CYAN "\033[36m" /* Cyan */
|
||||
#define WHITE "\033[37m" /* White */
|
||||
#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */
|
||||
#define BOLDRED "\033[1m\033[31m" /* Bold Red */
|
||||
#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */
|
||||
#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
|
||||
#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
|
||||
#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
|
||||
#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
|
||||
#define BOLDWHITE "\033[1m\033[37m" /* Bold White */
|
||||
|
||||
#endif
|
||||
+11
-5
@@ -1,7 +1,13 @@
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
constexpr int SCREEN_WIDTH = 800;
|
||||
constexpr int SCREEN_HEIGHT = 600;
|
||||
constexpr int WORLD_WIDTH = 1600;
|
||||
constexpr int WORLD_HEIGHT = 1200;
|
||||
|
||||
#ifndef CONST_NS
|
||||
#define CONST_NS
|
||||
|
||||
constexpr int SCREEN_WIDTH = 1600;
|
||||
constexpr int SCREEN_HEIGHT = 1200;
|
||||
constexpr int WORLD_WIDTH = 20000;
|
||||
constexpr int WORLD_HEIGHT = 200000;
|
||||
constexpr int TARGET_FPS = 60;
|
||||
constexpr Uint64 TARGET_FRAME_TIME_NS = 1'000'000'000 / TARGET_FPS;
|
||||
constexpr Uint64 TARGET_FRAME_TIME_NS = 1'000'000'000 / TARGET_FPS;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
#include <errno.h>
|
||||
#include <csignal>
|
||||
#include "color.h"
|
||||
#include <iostream>
|
||||
#include "exitcleanup.hpp"
|
||||
#include "types.hpp"
|
||||
#include "main.hpp"
|
||||
|
||||
void SignalHandler(int code) {
|
||||
switch (code) {
|
||||
case SIGTERM:
|
||||
std::cerr << "\nreceived SIGTERM exiting...\n";
|
||||
break;
|
||||
case SIGINT:
|
||||
std::cerr << "\nreceived SIGINT exiting...\n";
|
||||
break;
|
||||
case SIGQUIT:
|
||||
std::cerr << "\nreceived SIGQUIT exiting...\n";
|
||||
break;
|
||||
case SIGHUP:
|
||||
std::cerr << "\nreceived SIGHUP exiting...\n";
|
||||
break;
|
||||
|
||||
case SIGSEGV:
|
||||
std::cerr << "\nreceived SIGSEGV(segmentaiton fault) exiting...\nIf this "
|
||||
"repeats please report it as a bug\n";
|
||||
break;
|
||||
}
|
||||
try {
|
||||
GeneralCleanUp(code);
|
||||
} catch(...) {
|
||||
std::cerr << RED"[ERROR]" << RESET" general cleanup error\n";
|
||||
exit(errno);
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralCleanUp(int code) {
|
||||
|
||||
for(Entity *entity : loaded_entities) {
|
||||
try {
|
||||
SDL_DestroyTexture(entity->texture);
|
||||
} catch(...) {
|
||||
std::cerr << RED"[ERROR]" << RESET" failed to destroy texture of entity\nentity address:" << YELLOW << entity << RESET"\n";
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
SDL_DestroyWindow(main_sdl_session.window);
|
||||
} catch(...) {
|
||||
std::cerr << RED"[ERROR]" << RESET" failed to destroy window\n";
|
||||
}
|
||||
try{
|
||||
SDL_DestroyRenderer(main_sdl_session.renderer);
|
||||
} catch(...) {
|
||||
std::cerr << RED"[ERROR]" << RESET" failed to destroy renderer\n";
|
||||
}
|
||||
try {
|
||||
SDL_Quit();
|
||||
} catch (...) {
|
||||
std::cerr << RED"[ERROR]" << RESET" failed to quit sdl\n";
|
||||
}
|
||||
exit(code);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef EC_NS
|
||||
#define EC_NS
|
||||
void GeneralCleanUp(int code = 0);
|
||||
#endif
|
||||
@@ -1,23 +0,0 @@
|
||||
#include "types.hpp"
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
void load_entity(Entity &entity, std::string type, std::string name) {
|
||||
try {
|
||||
std::ifstream entitiesF("assets/entities.json");
|
||||
json entities = json::parse(entitiesF);
|
||||
|
||||
} catch (const json::parse_error &e) {
|
||||
std::cerr << "Parse error: " << e.what() << "\n";
|
||||
exit(1);
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "Error: " << e.what() << "\n";
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "init.hpp"
|
||||
#include "color.h"
|
||||
#include "main.hpp"
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
void init_entity(Entity &entity, SDL_Renderer *renderer, std::string type,
|
||||
std::string name) {
|
||||
json entities;
|
||||
try {
|
||||
std::ifstream entitiesF("./assets/entities.json");
|
||||
entities = json::parse(entitiesF);
|
||||
|
||||
} catch (const json::parse_error &e) {
|
||||
std::cerr << "Parse error: " << e.what() << "\n";
|
||||
exit(1);
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "Error: " << e.what() << "\n";
|
||||
exit(2);
|
||||
}
|
||||
|
||||
loaded_entities.push_back(&entity);
|
||||
std::clog << entities[type];
|
||||
|
||||
entity.texture = IMG_LoadTexture(
|
||||
renderer, entities[type][name]["texture"].get<std::string>().c_str());
|
||||
|
||||
if (entity.texture == NULL) {
|
||||
std::cerr << "\n" << RED "[ERROR]" << RESET " failed to load texture\n";
|
||||
exit(ENOENT);
|
||||
}
|
||||
|
||||
entity.srcRect = {0, 0, entities[type][name]["width"].get<int>(),
|
||||
entities[type][name]["height"].get<int>()};
|
||||
|
||||
entity.speed = entities[type][name]["speed"].get<float>();
|
||||
|
||||
entity.gotoT = false;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "types.hpp"
|
||||
|
||||
#ifndef IN_NS
|
||||
#define IN_NS
|
||||
|
||||
void init_entity(Entity &entity, SDL_Renderer *renderer,std::string type, std::string name);
|
||||
|
||||
#endif
|
||||
+85
-44
@@ -1,30 +1,37 @@
|
||||
#include "exitcleanup.hpp"
|
||||
#include "init.hpp"
|
||||
#include "types.hpp"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
#include <cmath>
|
||||
#include <csignal>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
|
||||
#define destroyer_width 58
|
||||
#define destroyer_height 512
|
||||
std::vector<Entity *> loaded_entities;
|
||||
sdl_session main_sdl_session;
|
||||
|
||||
int main() {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_Window *window =
|
||||
|
||||
main_sdl_session.window =
|
||||
SDL_CreateWindow("Naval Swarm", SCREEN_WIDTH, SCREEN_HEIGHT, 0);
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(window, "gpu,vulcan");
|
||||
SDL_Renderer *renderer =
|
||||
SDL_CreateRenderer(main_sdl_session.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;
|
||||
|
||||
init_entity(destroyer, renderer, "ship", "destroyer");
|
||||
|
||||
destroyer.position = {WORLD_WIDTH / 2.0f, WORLD_HEIGHT / 2.0f,
|
||||
static_cast<float>(destroyer.srcRect.w),
|
||||
static_cast<float>(destroyer.srcRect.h)};
|
||||
|
||||
// Initialize camera
|
||||
Camera camera;
|
||||
@@ -32,22 +39,40 @@ int main() {
|
||||
Uint64 lastFrameTime = SDL_GetTicksNS();
|
||||
float deltaTime = 0.0f;
|
||||
|
||||
time_t start_time = std::time(nullptr);
|
||||
|
||||
while (running) {
|
||||
const Uint64 frameStart = SDL_GetTicksNS();
|
||||
|
||||
|
||||
// Event handling
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_EVENT_QUIT)
|
||||
if (event.type == SDL_EVENT_QUIT) {
|
||||
running = false;
|
||||
}
|
||||
if (event.type == SDL_EVENT_MOUSE_WHEEL) {
|
||||
float zoom_factor = (event.wheel.y > 0) ? 0.9f : 1.1f;
|
||||
camera.view.w *= zoom_factor;
|
||||
camera.view.h *= zoom_factor;
|
||||
|
||||
// Zoom towards mouse position
|
||||
SDL_FPoint mouse_world_pos = {
|
||||
camera.view.x + event.wheel.mouse_x,
|
||||
camera.view.y + event.wheel.mouse_y
|
||||
};
|
||||
|
||||
camera.view.x = mouse_world_pos.x - (event.wheel.mouse_x * zoom_factor);
|
||||
camera.view.y = mouse_world_pos.y - (event.wheel.mouse_y * zoom_factor);
|
||||
}
|
||||
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);
|
||||
std::clog << "Left mouse clicked at ("
|
||||
<< std::fixed << std::setprecision(1) << event.button.x << ", " << event.button.y << ")\n"
|
||||
<< "Camera position: (" << camera.view.x << ", " << camera.view.y << ")\n"
|
||||
<< "Target position: (" << (camera.view.x + event.button.x) << ", "
|
||||
<< (camera.view.y + event.button.y) << ")\ntime since start: " << (std::time(nullptr) - start_time) << "\n";
|
||||
destroyer.Tposition.x = camera.view.x + event.button.x;
|
||||
destroyer.Tposition.y = camera.view.y + event.button.y;
|
||||
destroyer.gotoT = true;
|
||||
@@ -65,6 +90,16 @@ int main() {
|
||||
lastToggle = SDL_GetTicks();
|
||||
}
|
||||
|
||||
//DEBUG
|
||||
if (keystate[SDL_SCANCODE_B] && (SDL_GetTicks() - lastToggle > 200)) {
|
||||
std::clog << "x: " << destroyer.position.x << " y: " << destroyer.position.y << "\n";
|
||||
}
|
||||
if (keystate[SDL_SCANCODE_O] && (SDL_GetTicks() - lastToggle > 200)) {
|
||||
|
||||
destroyer.position.x = 0;
|
||||
destroyer.position.y = 0;
|
||||
}
|
||||
|
||||
// Player movement
|
||||
int moveX = keystate[SDL_SCANCODE_RIGHT] - keystate[SDL_SCANCODE_LEFT];
|
||||
int moveY = keystate[SDL_SCANCODE_DOWN] - keystate[SDL_SCANCODE_UP];
|
||||
@@ -107,14 +142,16 @@ int main() {
|
||||
}
|
||||
|
||||
float step = destroyer.speed * deltaTime;
|
||||
destroyer.position().x += (float)moveX * step;
|
||||
destroyer.position().y += (float)moveY * step;
|
||||
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;
|
||||
float dx = destroyer.Tposition.x - destroyer.Central_position().x;
|
||||
float dy = destroyer.Tposition.y - destroyer.Central_position().y;
|
||||
|
||||
destroyer.angle = std::atan2(dy, dx) * 180 / M_PI;
|
||||
if(dx != 0 && dy != 0) {
|
||||
destroyer.angle = std::atan2(dy, dx) * 180 / M_PI + 90;
|
||||
}
|
||||
|
||||
float distance = std::sqrt(dx * dx + dy * dy);
|
||||
if (distance > 0) {
|
||||
@@ -122,11 +159,12 @@ int main() {
|
||||
dy /= distance;
|
||||
|
||||
if (distance <= step) {
|
||||
destroyer.position().x = destroyer.Tposition.x;
|
||||
destroyer.position().y = destroyer.Tposition.y;
|
||||
destroyer.Central_position(destroyer.Tposition.x,
|
||||
destroyer.Tposition.y);
|
||||
|
||||
} else {
|
||||
destroyer.position().x += dx * step;
|
||||
destroyer.position().y += dy * step;
|
||||
destroyer.position.x += dx * step;
|
||||
destroyer.position.y += dy * step;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -134,12 +172,15 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Camera movement
|
||||
// Camera handling
|
||||
camera.view.w = SCREEN_WIDTH / camera.zoom;
|
||||
camera.view.h = SCREEN_HEIGHT / camera.zoom;
|
||||
|
||||
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;
|
||||
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 {
|
||||
@@ -150,13 +191,15 @@ int main() {
|
||||
}
|
||||
|
||||
// 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);
|
||||
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.w = SDL_clamp(camera.view.w, SCREEN_WIDTH * camera.zoom, SCREEN_WIDTH * 4.0f);
|
||||
camera.view.h = SDL_clamp(camera.view.h,SCREEN_HEIGHT * camera.zoom,SCREEN_HEIGHT * 4.0f);
|
||||
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);
|
||||
camera.view.y = SDL_clamp(camera.view.y, 0.0f, WORLD_HEIGHT - camera.view.h);
|
||||
|
||||
// ANIMATION HERE
|
||||
|
||||
@@ -174,9 +217,9 @@ int main() {
|
||||
// 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_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);
|
||||
|
||||
@@ -196,10 +239,8 @@ int main() {
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
SDL_DestroyTexture(spriteSheet);
|
||||
SDL_DestroyTexture(bgTexture);
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
GeneralCleanUp();
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <vector>
|
||||
#include "types.hpp"
|
||||
|
||||
#ifndef MAIN_NS
|
||||
#define MAIN_NS
|
||||
|
||||
extern std::vector<Entity*> loaded_entities;
|
||||
extern sdl_session main_sdl_session;
|
||||
|
||||
#endif
|
||||
+58
-31
@@ -2,36 +2,41 @@
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <cmath>
|
||||
|
||||
struct Angle360 {
|
||||
#ifndef TYPES_NS
|
||||
#define TYPES_NS
|
||||
|
||||
struct Angle {
|
||||
private:
|
||||
int value{0};
|
||||
float value{0};
|
||||
|
||||
void normalize() {
|
||||
value %= 360;
|
||||
value = std::fmod(value, 360);
|
||||
if (value < 0)
|
||||
value += 360; // Handle negative values
|
||||
}
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Angle360(int val = 0) : value(val) { normalize(); }
|
||||
Angle(int val = 0) : value(val) { normalize(); }
|
||||
|
||||
// Assignment operator
|
||||
Angle360 &operator=(int val) {
|
||||
Angle &operator=(int val) {
|
||||
value = val;
|
||||
normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compound assignment
|
||||
Angle360 &operator+=(int rhs) {
|
||||
Angle &operator+=(int rhs) {
|
||||
value += rhs;
|
||||
normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Angle360 &operator-=(int rhs) {
|
||||
Angle &operator-=(int rhs) {
|
||||
value -= rhs;
|
||||
normalize();
|
||||
return *this;
|
||||
@@ -41,42 +46,64 @@ public:
|
||||
operator int() const { return value; }
|
||||
|
||||
// Stream output
|
||||
friend std::ostream &operator<<(std::ostream &os, const Angle360 &a) {
|
||||
friend std::ostream &operator<<(std::ostream &os, const Angle &a) {
|
||||
return os << a.value;
|
||||
}
|
||||
};
|
||||
|
||||
struct basic_cords {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct Entity {
|
||||
private:
|
||||
SDL_FRect m_position;
|
||||
SDL_FPoint m_offset{0, 0}; // Default offset
|
||||
|
||||
public:
|
||||
// Direct access reference with auto-sync
|
||||
SDL_FRect &position() { return m_position; }
|
||||
const SDL_FRect &position() const { return m_position; }
|
||||
|
||||
// Computed central position (always fresh)
|
||||
SDL_FRect Central_position() const {
|
||||
return {m_position.x + m_offset.x, m_position.y + m_offset.y, m_position.w,
|
||||
m_position.h};
|
||||
}
|
||||
|
||||
// Set offset values
|
||||
void set_offset(float x, float y) { m_offset = {x, y}; }
|
||||
|
||||
// --- Existing members ---
|
||||
SDL_FRect position;
|
||||
SDL_FRect Tposition;
|
||||
bool gotoT;
|
||||
bool gotoT = false;
|
||||
SDL_Texture *texture;
|
||||
SDL_Rect srcRect;
|
||||
float speed = 250.0f;
|
||||
Angle360 angle;
|
||||
float speed;
|
||||
Angle angle = 0;
|
||||
|
||||
basic_cords Central_position(std::optional<float> x = std::nullopt,
|
||||
std::optional<float> y = std::nullopt) {
|
||||
if (x != std::nullopt) {
|
||||
position.x = *x - position.w / 2;
|
||||
}
|
||||
if (y != std::nullopt) {
|
||||
position.y = *y - position.h / 2;
|
||||
}
|
||||
|
||||
return {position.x + position.w / 2, position.y + position.h / 2};
|
||||
}
|
||||
};
|
||||
|
||||
struct Camera {
|
||||
SDL_FRect view = {0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT};
|
||||
|
||||
basic_cords Center_of_view(std::optional<float> x = std::nullopt,
|
||||
std::optional<float> y = std::nullopt) {
|
||||
if (x != std::nullopt) {
|
||||
view.x = *x - view.w / 2;
|
||||
}
|
||||
if (y != std::nullopt) {
|
||||
view.y = *y - view.h / 2;
|
||||
}
|
||||
|
||||
return {view.x + view.w / 2, view.y + view.h / 2};
|
||||
}
|
||||
|
||||
bool followPlayer = false;
|
||||
float speed = 500.0f;
|
||||
float smoothness = 0.1f;
|
||||
};
|
||||
float zoom = 1.0f;
|
||||
float minZoom = 0.5f;
|
||||
float maxZoom = 3.0f;
|
||||
float zoomSpeed = 0.1f;
|
||||
};
|
||||
|
||||
struct sdl_session {
|
||||
SDL_Window *window;
|
||||
SDL_Renderer *renderer;
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user