collisions happen properly now
This commit is contained in:
@@ -31,8 +31,8 @@ static const char **OBSTACLE_CRAWL_FRAMES[] = { OBSTACLE_CRAWL1_FRAME, OBSTACLE_
|
||||
// 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_LEFT_OFFSET = 3;
|
||||
static const int OBSTACLE_CRAWL1_COLLISION_RIGHT_OFFSET = 3;
|
||||
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_TOP_OFFSET = 4; // first 4 rows are just empty ('.')
|
||||
// collision box height = bottom 2 rows
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// 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"
|
||||
@@ -18,9 +17,13 @@ struct Obstacle {
|
||||
inline bool check_collision(const CharacterPosition& player,
|
||||
MovementType movement,
|
||||
const Obstacle& obs) {
|
||||
int player_x = player.x;
|
||||
int player_y = (VIEW_HEIGHT - player.y) - CHARACTER_WALK_FRAME_HEIGHT;
|
||||
int box_x = 0, box_w = 0, box_h = 0;
|
||||
|
||||
// Player is given in bottom-based world coordinates (0 = bottom line)
|
||||
const int player_x = player.x;
|
||||
const int player_bottom = player.y;
|
||||
int box_x = 0;
|
||||
int box_w = 0;
|
||||
int box_h = 0;
|
||||
|
||||
switch (movement) {
|
||||
case MovementType::Walk:
|
||||
@@ -46,19 +49,18 @@ inline bool check_collision(const CharacterPosition& player,
|
||||
}
|
||||
|
||||
// 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;
|
||||
const int player_left = box_x;
|
||||
const int player_right = player_left + box_w;
|
||||
const int player_top = player_bottom + 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;
|
||||
const int obs_left = obs.x;
|
||||
const int obs_right = obs.x + obs.width;
|
||||
const int obs_bottom = obs.y;
|
||||
const int obs_top = obs_bottom + 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;
|
||||
bool vertical = player_bottom < obs_top && player_top > obs_bottom;
|
||||
return horizontal && vertical;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,19 @@ inline int spawn_obstacle(CrawlObstacleType type, int x_start) {
|
||||
|
||||
obstacle_pool[i].data.width = (type == CrawlObstacleType::Crawl1) ? OBSTACLE_CRAWL1_COLLISION_WIDTH : OBSTACLE_CRAWL2_COLLISION_WIDTH;
|
||||
obstacle_pool[i].data.height = (type == CrawlObstacleType::Crawl1) ? OBSTACLE_CRAWL1_COLLISION_HEIGHT : OBSTACLE_CRAWL2_COLLISION_HEIGHT;
|
||||
obstacle_pool[i].data.y = 0;
|
||||
|
||||
// Default Y so that the SPRITE touches the top of the screen.
|
||||
// We store Y as the bottom of the COLLISION BOX in bottom-based world coords.
|
||||
int top_offset = 0;
|
||||
if (type == CrawlObstacleType::Crawl1) {
|
||||
top_offset = OBSTACLE_CRAWL1_COLLISION_TOP_OFFSET;
|
||||
} else {
|
||||
top_offset = 0;
|
||||
}
|
||||
const int i_bottom_of_collision = top_offset + obstacle_pool[i].data.height - 1;
|
||||
// Top of screen in world coords is VIEW_HEIGHT - 1
|
||||
const int collision_bottom_world_y = (VIEW_HEIGHT - 1) - i_bottom_of_collision;
|
||||
obstacle_pool[i].data.y = collision_bottom_world_y;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -71,27 +71,8 @@ private:
|
||||
int spawn_index_;
|
||||
|
||||
static void draw_clipped_obstacle(const MovingObstacle &obs,
|
||||
const char **frame,
|
||||
int frame_height) {
|
||||
int x = obs.data.x;
|
||||
int y = obs.data.y;
|
||||
int w = obs.data.width;
|
||||
|
||||
for (int r = 0; r < frame_height; ++r) {
|
||||
int left = x;
|
||||
int right = x + w;
|
||||
if (right <= 0 || left >= VIEW_WIDTH)
|
||||
continue;
|
||||
|
||||
int vis_left = clamp_min(left, 0);
|
||||
int vis_right = clamp_max(right, VIEW_WIDTH);
|
||||
int start = vis_left - left;
|
||||
int count = vis_right - vis_left;
|
||||
if (count <= 0)
|
||||
continue;
|
||||
|
||||
const char *row = frame[r] + start;
|
||||
printf("\033[%d;%dH%.*s", y + r + 1, vis_left + 1, count, row);
|
||||
}
|
||||
const char ** /*frame*/,
|
||||
int /*frame_height*/) {
|
||||
draw_obstacle(obs.data.x, obs.data.y, obs.type);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -122,12 +122,12 @@ void render_loop(int speed) {
|
||||
obstacle_pool[i].data.y,
|
||||
obstacle_pool[i].type);
|
||||
|
||||
if (check_collision(draw_pos, frame.movement, obstacle_pool[i].data)) {
|
||||
printf("\033[2J\033[H"); // clear screen & home cursor
|
||||
printf("GAME OVER\r\n");
|
||||
game_over = true;
|
||||
break;
|
||||
}
|
||||
if (check_collision(pos, frame.movement, obstacle_pool[i].data)) {
|
||||
printf("\033[2J\033[H");
|
||||
printf("GAME OVER\r\n");
|
||||
game_over = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (game_over)
|
||||
|
||||
@@ -4,28 +4,53 @@
|
||||
#include "../assets/background_frame.h"
|
||||
#include <cstdio>
|
||||
|
||||
// Draw a single obstacle ASCII sprite at (x, y) where y is ground‑based (0 = bottom)
|
||||
// Draws an obstacle using bottom‑based world coordinates.
|
||||
// x = left edge of the collision box in world space
|
||||
// y = bottom edge of the collision box in world space (0 = ground)
|
||||
void draw_obstacle(int x, int y, CrawlObstacleType type) {
|
||||
const char **obstacle = nullptr;
|
||||
int obstacle_height = 0;
|
||||
const char **obstacle_frame = nullptr;
|
||||
int frame_total_height = 0;
|
||||
|
||||
// Collision‑model parameters for this obstacle
|
||||
int collision_top_offset = 0; // rows from visual top to top of collision box
|
||||
int collision_height = 0; // rows tall
|
||||
int collision_left_offset = 0; // columns from visual left to collision left
|
||||
|
||||
switch (type) {
|
||||
case CrawlObstacleType::Crawl1:
|
||||
obstacle = OBSTACLE_CRAWL1_FRAME;
|
||||
obstacle_height = OBSTACLE_CRAWL1_FRAME_HEIGHT;
|
||||
obstacle_frame = OBSTACLE_CRAWL1_FRAME;
|
||||
frame_total_height = OBSTACLE_CRAWL1_FRAME_HEIGHT;
|
||||
collision_top_offset = OBSTACLE_CRAWL1_COLLISION_TOP_OFFSET;
|
||||
collision_height = OBSTACLE_CRAWL1_COLLISION_HEIGHT;
|
||||
collision_left_offset = OBSTACLE_CRAWL1_COLLISION_LEFT_OFFSET;
|
||||
break;
|
||||
|
||||
case CrawlObstacleType::Crawl2:
|
||||
obstacle = OBSTACLE_CRAWL2_FRAME;
|
||||
obstacle_height = OBSTACLE_CRAWL2_FRAME_HEIGHT;
|
||||
obstacle_frame = OBSTACLE_CRAWL2_FRAME;
|
||||
frame_total_height = OBSTACLE_CRAWL2_FRAME_HEIGHT;
|
||||
collision_top_offset = 0;
|
||||
collision_height = OBSTACLE_CRAWL2_COLLISION_HEIGHT;
|
||||
collision_left_offset = OBSTACLE_CRAWL2_COLLISION_LEFT_OFFSET;
|
||||
break;
|
||||
|
||||
default:
|
||||
return; // in case of invalid type
|
||||
return; // no rendering for invalid type
|
||||
}
|
||||
|
||||
for (int i = 0; i < obstacle_height; i++) {
|
||||
printf("\033[%d;%dH%s", y + i + 1, x + 1, obstacle[i]);
|
||||
// Convert bottom‑based (world) coordinates to screen coordinates.
|
||||
// Y of the collision bottom is given; translate to where to start drawing the visual frame.
|
||||
const int frame_row_index_bottom = collision_top_offset + collision_height - 1;
|
||||
const int frame_top_world_y = y + frame_row_index_bottom;
|
||||
const int frame_top_screen_row = VIEW_HEIGHT - frame_top_world_y;
|
||||
|
||||
// X of the collision box is given; shift left to the visual frame's starting column.
|
||||
const int frame_screen_x = x - collision_left_offset;
|
||||
|
||||
for (int i = 0; i < frame_total_height; i++) {
|
||||
const int screen_row = frame_top_screen_row + i;
|
||||
if (screen_row < 1 || screen_row > VIEW_HEIGHT) continue;
|
||||
printf("\033[%d;%dH%s", screen_row, frame_screen_x + 1, obstacle_frame[i]);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user