diff --git a/semestralka1/src/assets/obstacle_crawl_frames.h b/semestralka1/src/assets/obstacle_crawl_frames.h new file mode 100644 index 0000000..d818847 --- /dev/null +++ b/semestralka1/src/assets/obstacle_crawl_frames.h @@ -0,0 +1,37 @@ +// src/assets/obstacle_crawl_frames.h +#pragma once +#include + +// Crawl obstacle for CRAWL1 (2 lines tall) +static const char *OBSTACLE_CRAWL1_FRAME[] = { + "#######", + "#######" +}; + +// Crawl obstacle for CRAWL2 (4 lines tall) +static const char *OBSTACLE_CRAWL2_FRAME[] = { + "########", + "########", + "########", + "########" +}; + +enum class CrawlObstacleType { Crawl1 = 0, Crawl2, COUNT }; + +static const char **OBSTACLE_CRAWL_FRAMES[] = { OBSTACLE_CRAWL1_FRAME, OBSTACLE_CRAWL2_FRAME }; + +// Crawl1 dimensions and collision +static const int OBSTACLE_CRAWL1_FRAME_HEIGHT = sizeof(OBSTACLE_CRAWL1_FRAME) / sizeof(OBSTACLE_CRAWL1_FRAME[0]); +static const int OBSTACLE_CRAWL1_FRAME_WIDTH = std::strlen(OBSTACLE_CRAWL1_FRAME[0]); +static const int OBSTACLE_CRAWL1_COLLISION_LEFT_OFFSET = 0; +static const int OBSTACLE_CRAWL1_COLLISION_RIGHT_OFFSET = 0; +static const int OBSTACLE_CRAWL1_COLLISION_WIDTH = OBSTACLE_CRAWL1_FRAME_WIDTH - (OBSTACLE_CRAWL1_COLLISION_LEFT_OFFSET + OBSTACLE_CRAWL1_COLLISION_RIGHT_OFFSET); +static const int OBSTACLE_CRAWL1_COLLISION_HEIGHT = OBSTACLE_CRAWL1_FRAME_HEIGHT; + +// Crawl2 dimensions and collision +static const int OBSTACLE_CRAWL2_FRAME_HEIGHT = sizeof(OBSTACLE_CRAWL2_FRAME) / sizeof(OBSTACLE_CRAWL2_FRAME[0]); +static const int OBSTACLE_CRAWL2_FRAME_WIDTH = std::strlen(OBSTACLE_CRAWL2_FRAME[0]); +static const int OBSTACLE_CRAWL2_COLLISION_LEFT_OFFSET = 0; +static const int OBSTACLE_CRAWL2_COLLISION_RIGHT_OFFSET = 0; +static const int OBSTACLE_CRAWL2_COLLISION_WIDTH = OBSTACLE_CRAWL2_FRAME_WIDTH - (OBSTACLE_CRAWL2_COLLISION_LEFT_OFFSET + OBSTACLE_CRAWL2_COLLISION_RIGHT_OFFSET); +static const int OBSTACLE_CRAWL2_COLLISION_HEIGHT = OBSTACLE_CRAWL2_FRAME_HEIGHT; diff --git a/semestralka1/src/game/collision.h b/semestralka1/src/game/collision.h new file mode 100644 index 0000000..ac5c712 --- /dev/null +++ b/semestralka1/src/game/collision.h @@ -0,0 +1,64 @@ +// src/game/collision.h +#pragma once +#include "../render/player_positioning.h" +#include "../render/player.h" +#include "../assets/character_walk_frames.h" +#include "../assets/character_run_frames.h" +#include "../assets/character_crawl_frames.h" + +// Simple obstacle representation +struct Obstacle { + int x; + int y; + int width; + int height; +}; + +// Axis-aligned bounding-box collision +inline bool check_collision(const CharacterPosition& player, + MovementType movement, + const Obstacle& obs) { + int player_x = player.x; + int player_y = player.y; + int box_x = 0, box_w = 0, box_h = 0; + + switch (movement) { + case MovementType::Walk: + box_x = player_x + CHARACTER_WALK_COLLISION_LEFT_OFFSET; + box_w = CHARACTER_WALK_COLLISION_WIDTH; + box_h = CHARACTER_WALK_FRAME_HEIGHT; + break; + case MovementType::Run: + box_x = player_x + CHARACTER_RUN_COLLISION_LEFT_OFFSET; + box_w = CHARACTER_RUN_COLLISION_WIDTH; + box_h = CHARACTER_RUN_COLLISION_HEIGHT; + break; + case MovementType::Crawl1: + box_x = player_x + CHARACTER_CRAWL1_COLLISION_LEFT_OFFSET; + box_w = CHARACTER_CRAWL1_COLLISION_WIDTH; + box_h = CHARACTER_CRAWL1_COLLISION_HEIGHT; + break; + case MovementType::Crawl2: + box_x = player_x + CHARACTER_CRAWL2_COLLISION_LEFT_OFFSET; + box_w = CHARACTER_CRAWL2_COLLISION_WIDTH; + box_h = CHARACTER_CRAWL2_COLLISION_HEIGHT; + break; + } + + // Player's bounding box + int player_left = box_x; + int player_right = player_left + box_w; + int player_top = player_y; + int player_bottom = player_top + box_h; + + // Obstacle bounding box + int obs_left = obs.x; + int obs_right = obs.x + obs.width; + int obs_top = obs.y; + int obs_bottom = obs.y + obs.height; + + // Simple overlap check + bool horizontal = player_left < obs_right && player_right > obs_left; + bool vertical = player_top < obs_bottom && player_bottom > obs_top; + return horizontal && vertical; +} diff --git a/semestralka1/src/game/obstacle_manager.h b/semestralka1/src/game/obstacle_manager.h new file mode 100644 index 0000000..10e20be --- /dev/null +++ b/semestralka1/src/game/obstacle_manager.h @@ -0,0 +1,45 @@ +// src/game/obstacle_manager.h +#pragma once +#include "../game/collision.h" +#include "../assets/obstacle_crawl_frames.h" + +// One movable obstacle +struct MovingObstacle { + Obstacle data; + CrawlObstacleType type; + bool active; +}; + +// Fixed obstacle pool +constexpr int MAX_OBSTACLES = 6; +static MovingObstacle obstacle_pool[MAX_OBSTACLES]; + +// Create / reset obstacle in one slot +inline void spawn_obstacle(CrawlObstacleType type, int x_start) { + for (int i = 0; i < MAX_OBSTACLES; i++) { + if (!obstacle_pool[i].active) { + obstacle_pool[i].active = true; + obstacle_pool[i].type = type; + obstacle_pool[i].data.x = x_start; + obstacle_pool[i].data.y = 0; // hangs from ceiling + if (type == CrawlObstacleType::Crawl1) { + obstacle_pool[i].data.width = OBSTACLE_CRAWL1_COLLISION_WIDTH; + obstacle_pool[i].data.height = OBSTACLE_CRAWL1_COLLISION_HEIGHT; + } else { + obstacle_pool[i].data.width = OBSTACLE_CRAWL2_COLLISION_WIDTH; + obstacle_pool[i].data.height = OBSTACLE_CRAWL2_COLLISION_HEIGHT; + } + break; + } + } +} + +// Update X positions; mark inactive if offscreen +inline void update_obstacles(int shift_speed) { + for (int i = 0; i < MAX_OBSTACLES; i++) { + if (!obstacle_pool[i].active) continue; + obstacle_pool[i].data.x -= shift_speed; + if (obstacle_pool[i].data.x + obstacle_pool[i].data.width < 0) + obstacle_pool[i].active = false; + } +}