Compare commits
7 Commits
a719c73c50
...
2b878ae784
Author | SHA1 | Date |
---|---|---|
|
2b878ae784 | |
|
451b241460 | |
|
c8d2ee5408 | |
|
4b91ab5667 | |
|
7767b38221 | |
|
c27fa632a2 | |
|
81da536e8e |
|
@ -14,12 +14,13 @@ enum EntitySpawnSelection {
|
|||
TOGGLE_TILE = 0,
|
||||
TOGGLE_ONEWAY,
|
||||
TOGGLE_LADDER,
|
||||
TOGGLE_SPIKE,
|
||||
SPAWN_CRATE,
|
||||
SPAWN_METAL_CRATE,
|
||||
SPAWN_BOULDER,
|
||||
};
|
||||
|
||||
#define MAX_SPAWN_TYPE 6
|
||||
#define MAX_SPAWN_TYPE 7
|
||||
static unsigned int current_spawn_selection = 0;
|
||||
|
||||
static inline unsigned int get_tile_idx(int x, int y, const TileGrid_t* tilemap)
|
||||
|
@ -68,6 +69,13 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
{
|
||||
DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, ORANGE);
|
||||
}
|
||||
else if (tilemap.tiles[i].tile_type == SPIKES)
|
||||
{
|
||||
DrawRectangle(
|
||||
x + tilemap.tiles[i].offset.x, y + tilemap.tiles[i].offset.y,
|
||||
tilemap.tiles[i].size.x, tilemap.tiles[i].size.y, RED
|
||||
);
|
||||
}
|
||||
|
||||
if (tilemap.tiles[i].water_level > 0)
|
||||
{
|
||||
|
@ -317,6 +325,17 @@ static void toggle_block_system(Scene_t* scene)
|
|||
tilemap.tiles[down_tile].solid = (tilemap.tiles[tile_idx].tile_type != LADDER)? ONE_WAY : NOT_SOLID;
|
||||
}
|
||||
break;
|
||||
case TOGGLE_SPIKE:
|
||||
if (tilemap.tiles[tile_idx].tile_type == SPIKES)
|
||||
{
|
||||
tilemap.tiles[tile_idx].tile_type = EMPTY_TILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
tilemap.tiles[tile_idx].tile_type = SPIKES;
|
||||
}
|
||||
tilemap.tiles[tile_idx].solid = NOT_SOLID;
|
||||
break;
|
||||
case SPAWN_CRATE:
|
||||
spawn_crate(scene, tile_idx, false);
|
||||
break;
|
||||
|
@ -327,6 +346,34 @@ static void toggle_block_system(Scene_t* scene)
|
|||
spawn_boulder(scene, tile_idx);
|
||||
break;
|
||||
}
|
||||
if (tilemap.tiles[tile_idx].tile_type == SPIKES)
|
||||
{
|
||||
if (tile_idx - tilemap.width >= 0 && tilemap.tiles[tile_idx-tilemap.width].tile_type == SOLID_TILE)
|
||||
{
|
||||
tilemap.tiles[tile_idx].offset = (Vector2){0,0};
|
||||
tilemap.tiles[tile_idx].size = (Vector2){32,16};
|
||||
}
|
||||
else if (tile_idx % tilemap.width != 0 && tile_idx > 0 && tilemap.tiles[tile_idx-1].tile_type == SOLID_TILE)
|
||||
{
|
||||
tilemap.tiles[tile_idx].offset = (Vector2){0,0};
|
||||
tilemap.tiles[tile_idx].size = (Vector2){16,32};
|
||||
}
|
||||
else if (tile_idx % tilemap.width + 1 != 0 && tile_idx < MAX_N_TILES - 1 && tilemap.tiles[tile_idx+1].tile_type == SOLID_TILE)
|
||||
{
|
||||
tilemap.tiles[tile_idx].offset = (Vector2){16,0};
|
||||
tilemap.tiles[tile_idx].size = (Vector2){16,32};
|
||||
}
|
||||
else
|
||||
{
|
||||
tilemap.tiles[tile_idx].offset = (Vector2){0,16};
|
||||
tilemap.tiles[tile_idx].size = (Vector2){32,16};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tilemap.tiles[tile_idx].offset = (Vector2){0,0};
|
||||
tilemap.tiles[tile_idx].size = (Vector2){32,32};
|
||||
}
|
||||
last_tile_idx = tile_idx;
|
||||
}
|
||||
}
|
||||
|
@ -431,6 +478,7 @@ void init_level_scene(LevelScene_t* scene)
|
|||
sc_array_add(&scene->scene.systems, &update_tilemap_system);
|
||||
sc_array_add(&scene->scene.systems, &hitbox_update_system);
|
||||
sc_array_add(&scene->scene.systems, &player_crushing_system);
|
||||
sc_array_add(&scene->scene.systems, &player_spike_collision_system);
|
||||
sc_array_add(&scene->scene.systems, &state_transition_update_system);
|
||||
sc_array_add(&scene->scene.systems, &player_ground_air_transition_system);
|
||||
sc_array_add(&scene->scene.systems, &sprite_animation_system);
|
||||
|
@ -462,6 +510,7 @@ void init_level_scene(LevelScene_t* scene)
|
|||
all_tiles[i].solid = NOT_SOLID;
|
||||
all_tiles[i].tile_type = EMPTY_TILE;
|
||||
sc_map_init_64v(&all_tiles[i].entities_set, 16, 0);
|
||||
all_tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE};
|
||||
}
|
||||
for (size_t i = 0; i < scene->data.tilemap.width; ++i)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap)
|
||||
{
|
||||
// No Overlap
|
||||
if (l1.y < l2.x || l2.y < l1.x) return 0;
|
||||
if (l1.y <= l2.x || l2.y <= l1.x) return 0;
|
||||
|
||||
if (l1.x >= l2.x && l1.y <= l2.y)
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap)
|
|||
}
|
||||
//Partial overlap
|
||||
// x is p1, y is p2
|
||||
*overlap = (l2.y >= l1.y)? l2.x - l1.y - 1 : l2.y - l1.x + 1;
|
||||
*overlap = (l2.y > l1.y)? l2.x - l1.y : l2.y - l1.x;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -25,15 +25,15 @@ uint8_t find_AABB_overlap(const Vector2 tl1, const Vector2 sz1, const Vector2 tl
|
|||
Vector2 l1, l2;
|
||||
uint8_t overlap_x, overlap_y;
|
||||
l1.x = tl1.x;
|
||||
l1.y = tl1.x + sz1.x - 1;
|
||||
l1.y = tl1.x + sz1.x;
|
||||
l2.x = tl2.x;
|
||||
l2.y = tl2.x + sz2.x - 1;
|
||||
l2.y = tl2.x + sz2.x;
|
||||
|
||||
overlap_x = find_1D_overlap(l1, l2, &overlap->x);
|
||||
l1.x = tl1.y;
|
||||
l1.y = tl1.y + sz1.y - 1;
|
||||
l1.y = tl1.y + sz1.y;
|
||||
l2.x = tl2.y;
|
||||
l2.y = tl2.y + sz2.y - 1;
|
||||
l2.y = tl2.y + sz2.y;
|
||||
overlap_y = find_1D_overlap(l1, l2, &overlap->y);
|
||||
|
||||
if (overlap_x == 2 && overlap_y == 2) return 2;
|
||||
|
@ -49,3 +49,45 @@ bool point_in_AABB(Vector2 point, Rectangle box)
|
|||
&& point.y < box.y + box.height
|
||||
);
|
||||
}
|
||||
|
||||
bool line_in_AABB(Vector2 p1, Vector2 p2, Rectangle box)
|
||||
{
|
||||
float A = p2.y - p1.y;
|
||||
float B = p1.x - p2.x;
|
||||
float C = (p2.x * p1.y) - (p1.x * p2.y);
|
||||
|
||||
Vector2 corners[3] =
|
||||
{
|
||||
{box.x + box.width - 1, box.y},
|
||||
{box.x + box.width - 1, box.y + box.height - 1},
|
||||
{box.x, box.y + box.height - 1},
|
||||
};
|
||||
|
||||
float F = (A * box.x + B * box.y + C);
|
||||
uint8_t last_mode = 0;
|
||||
if (fabs(F) < 1e-3)
|
||||
{
|
||||
last_mode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_mode = (F > 0) ? 1 : 2;
|
||||
}
|
||||
for (uint8_t i = 0; i < 3; ++i)
|
||||
{
|
||||
|
||||
F = (A * corners[i].x + B * corners[i].y + C);
|
||||
uint8_t mode = 0;
|
||||
if (fabs(F) < 1e-3)
|
||||
{
|
||||
mode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = (F > 0) ? 1 : 2;
|
||||
}
|
||||
if (mode != last_mode) return true;
|
||||
last_mode = mode;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -6,4 +6,5 @@
|
|||
uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap);
|
||||
uint8_t find_AABB_overlap(const Vector2 tl1, const Vector2 sz1, const Vector2 tl2, const Vector2 sz2, Vector2* overlap);
|
||||
bool point_in_AABB(Vector2 point, Rectangle box);
|
||||
bool line_in_AABB(Vector2 p1, Vector2 p2, Rectangle box);
|
||||
#endif // __AABB_H
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "constants.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static const Vector2 TILE_SZ = {TILE_SIZE, TILE_SIZE};
|
||||
static const Vector2 GRAVITY = {0, GRAV_ACCEL};
|
||||
static const Vector2 UPTHRUST = {0, -GRAV_ACCEL * 1.1};
|
||||
typedef enum AnchorPoint {
|
||||
|
@ -60,7 +59,9 @@ static uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, boo
|
|||
find_AABB_overlap(
|
||||
(Vector2){ent->bbox.x, ent->bbox.y},
|
||||
(Vector2){ent->bbox.width, ent->bbox.height},
|
||||
(Vector2){tile_x * TILE_SIZE, tile_y * TILE_SIZE}, TILE_SZ, &overlap
|
||||
(Vector2){tile_x * TILE_SIZE + grid->tiles[tile_idx].offset.x, tile_y * TILE_SIZE + grid->tiles[tile_idx].offset.y},
|
||||
grid->tiles[tile_idx].size,
|
||||
&overlap
|
||||
);
|
||||
|
||||
//For one-way platform, check for vectical collision, only return true for up direction
|
||||
|
@ -95,6 +96,62 @@ static uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, boo
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool check_oneway)
|
||||
{
|
||||
Vector2 p1 = {ent->bbox.x, ent->bbox.y};
|
||||
Vector2 p2 = {ent->bbox.x + ent->bbox.width - 1, ent->bbox.y + ent->bbox.height - 1};
|
||||
for(unsigned int tile_y = ent->area.tile_y1; tile_y <= ent->area.tile_y2; tile_y++)
|
||||
{
|
||||
if (tile_y >= grid->height) return 0;
|
||||
for(unsigned int tile_x = ent->area.tile_x1; tile_x <= ent->area.tile_x2; tile_x++)
|
||||
{
|
||||
if (tile_x >= grid->width) return 0;
|
||||
unsigned int tile_idx = tile_y*grid->width + tile_x;
|
||||
if (grid->tiles[tile_idx].solid == SOLID) return 1;
|
||||
|
||||
if (check_oneway && grid->tiles[tile_idx].solid == ONE_WAY)
|
||||
{
|
||||
Rectangle tile_rec = {
|
||||
.x = tile_x * TILE_SIZE + grid->tiles[tile_idx].offset.x,
|
||||
.y = tile_y * TILE_SIZE + grid->tiles[tile_idx].offset.y,
|
||||
.width = grid->tiles[tile_idx].size.x,
|
||||
.height = grid->tiles[tile_idx].size.y
|
||||
};
|
||||
bool collide = line_in_AABB(p1, p2, tile_rec);
|
||||
|
||||
//For one-way platform, check for vectical collision, only return true for up direction
|
||||
if (collide && ent->prev_bbox.y + ent->prev_bbox.height - 1 < tile_y * TILE_SIZE) return 1;
|
||||
}
|
||||
|
||||
Entity_t* p_other_ent;
|
||||
sc_map_foreach_value(&grid->tiles[tile_idx].entities_set, p_other_ent)
|
||||
{
|
||||
if (ent->p_ent->m_id == p_other_ent->m_id) continue;
|
||||
if (!ent->p_ent->m_alive) continue;
|
||||
CTransform_t *p_ctransform = get_component(p_other_ent, CTRANSFORM_COMP_T);
|
||||
CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T);
|
||||
if (p_bbox == NULL || p_ctransform == NULL) continue;
|
||||
//if (p_bbox->solid && !p_bbox->fragile)
|
||||
if (p_bbox->solid)
|
||||
{
|
||||
Rectangle box = {
|
||||
.x = p_ctransform->position.x,
|
||||
.y = p_ctransform->position.y,
|
||||
.width = p_bbox->size.x,
|
||||
.height = p_bbox->size.y,
|
||||
};
|
||||
if ( line_in_AABB(p1, p2, box) )
|
||||
{
|
||||
return (p_bbox->fragile) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// TODO: This should be a point collision check, not an AABB check
|
||||
static bool check_collision_offset(
|
||||
Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz,
|
||||
|
@ -241,14 +298,19 @@ collision_end:
|
|||
|
||||
static uint8_t check_bbox_edges(
|
||||
TileGrid_t* tilemap,
|
||||
Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbox
|
||||
Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbox,
|
||||
int8_t len_reduction
|
||||
)
|
||||
{
|
||||
uint8_t detected = 0;
|
||||
|
||||
bbox.x -= 2 * len_reduction;
|
||||
bbox.y -= 2 * len_reduction;
|
||||
|
||||
CollideEntity_t ent =
|
||||
{
|
||||
.p_ent = p_ent,
|
||||
.bbox = (Rectangle){pos.x - 1, pos.y, bbox.x, bbox.y},
|
||||
.bbox = (Rectangle){pos.x - 1, pos.y + len_reduction, 1, bbox.y},
|
||||
.prev_bbox = (Rectangle){pos.x, pos.y, bbox.x, bbox.y},
|
||||
.area = (TileArea_t){
|
||||
.tile_x1 = (pos.x - 1) / TILE_SIZE,
|
||||
|
@ -261,28 +323,30 @@ static uint8_t check_bbox_edges(
|
|||
|
||||
// TODO: Handle one-way platform
|
||||
// Left
|
||||
detected |= (check_collision(&ent, tilemap, false) ? 1 : 0) << 3;
|
||||
detected |= (check_collision_line(&ent, tilemap, false) ? 1 : 0) << 3;
|
||||
|
||||
//Right
|
||||
ent.bbox.x += 2; // 2 to account for the previous subtraction
|
||||
ent.bbox.x = pos.x + bbox.x; // 2 to account for the previous subtraction
|
||||
ent.area.tile_x1 = (pos.x + bbox.x) / TILE_SIZE;
|
||||
ent.area.tile_x2 = ent.area.tile_x1;
|
||||
detected |= (check_collision(&ent, tilemap, false) ? 1 : 0) << 2;
|
||||
detected |= (check_collision_line(&ent, tilemap, false) ? 1 : 0) << 2;
|
||||
|
||||
// Up
|
||||
ent.bbox.x -= 2;
|
||||
ent.bbox.y--;
|
||||
ent.bbox.x = pos.x + len_reduction;
|
||||
ent.bbox.y = pos.y - 1;
|
||||
ent.bbox.width = bbox.x;
|
||||
ent.bbox.height = 1;
|
||||
ent.area.tile_x1 = (pos.x) / TILE_SIZE,
|
||||
ent.area.tile_x2 = (pos.x + bbox.x - 1) / TILE_SIZE,
|
||||
ent.area.tile_y1 = (pos.y - 1) / TILE_SIZE,
|
||||
ent.area.tile_y2 = ent.area.tile_y1;
|
||||
detected |= (check_collision(&ent, tilemap, false) ? 1 : 0) << 1;
|
||||
detected |= (check_collision_line(&ent, tilemap, false) ? 1 : 0) << 1;
|
||||
|
||||
// Down
|
||||
ent.bbox.y += 2;
|
||||
ent.bbox.y = pos.y + bbox.y;
|
||||
ent.area.tile_y1 = (pos.y + bbox.y) / TILE_SIZE,
|
||||
ent.area.tile_y2 = ent.area.tile_y1;
|
||||
detected |= (check_collision(&ent, tilemap, true) ? 1 : 0);
|
||||
detected |= (check_collision_line(&ent, tilemap, true) ? 1 : 0);
|
||||
return detected;
|
||||
}
|
||||
|
||||
|
@ -613,60 +677,61 @@ void player_bbox_update_system(Scene_t* scene)
|
|||
void player_crushing_system(Scene_t* scene)
|
||||
{
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
TileGrid_t tilemap = data->tilemap;
|
||||
|
||||
Entity_t* p_player;
|
||||
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player)
|
||||
{
|
||||
CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T);
|
||||
CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T);
|
||||
CollideEntity_t ent =
|
||||
{
|
||||
.p_ent = p_player,
|
||||
.bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, p_bbox->size.x, p_bbox->size.y},
|
||||
.prev_bbox = (Rectangle){p_ctransform->prev_velocity.x, p_ctransform->prev_position.y, p_bbox->size.x, p_bbox->size.y},
|
||||
.area = (TileArea_t){
|
||||
.tile_x1 = (p_ctransform->position.x) / TILE_SIZE,
|
||||
.tile_y1 = (p_ctransform->position.y) / TILE_SIZE,
|
||||
.tile_x2 = (p_ctransform->position.x) / TILE_SIZE,
|
||||
.tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
|
||||
},
|
||||
};
|
||||
|
||||
// Mostly identical to edge check function
|
||||
// Except we want collision instead of just touching
|
||||
uint8_t detected = 0;
|
||||
// Left
|
||||
detected |= (check_collision(&ent, &tilemap, false) ? 1 : 0);
|
||||
uint8_t edges = check_bbox_edges(
|
||||
&data->tilemap, p_player,
|
||||
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, 2
|
||||
);
|
||||
|
||||
//Right
|
||||
ent.area.tile_x1 = (p_ctransform->position.x + p_bbox->size.x - 1) / TILE_SIZE;
|
||||
ent.area.tile_x2 = ent.area.tile_x1;
|
||||
detected |= (check_collision(&ent, &tilemap, false) ? 1 : 0) << 1;
|
||||
|
||||
if (detected == 0b11)
|
||||
if ((edges & 0b1100) == 0b1100 || (edges & 0b0011) == 0b0011)
|
||||
{
|
||||
p_player->m_alive = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
detected = 0;
|
||||
// Up
|
||||
ent.area.tile_x1 = (p_ctransform->position.x) / TILE_SIZE,
|
||||
ent.area.tile_y1 = (p_ctransform->position.y - 1) / TILE_SIZE,
|
||||
ent.area.tile_y2 = ent.area.tile_y1;
|
||||
detected |= (check_collision(&ent, &tilemap, false) ? 1 : 0) << 1;
|
||||
|
||||
// Down
|
||||
ent.area.tile_y1 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
|
||||
ent.area.tile_y2 = ent.area.tile_y1;
|
||||
detected |= (check_collision(&ent, &tilemap, true) ? 1 : 0);
|
||||
|
||||
//if (check_collision(&ent, &tilemap, false) == 1)
|
||||
if (detected == 0b11)
|
||||
void player_spike_collision_system(Scene_t* scene)
|
||||
{
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
TileGrid_t tilemap = data->tilemap;
|
||||
Entity_t* p_player;
|
||||
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player)
|
||||
{
|
||||
CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T);
|
||||
CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T);
|
||||
unsigned int tile_x1 = (p_ctransform->position.x) / TILE_SIZE;
|
||||
unsigned int tile_y1 = (p_ctransform->position.y) / TILE_SIZE;
|
||||
unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x - 1) / TILE_SIZE;
|
||||
unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE;
|
||||
Vector2 overlap;
|
||||
for (unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
|
||||
{
|
||||
p_player->m_alive = false;
|
||||
return;
|
||||
for (unsigned int tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
|
||||
{
|
||||
unsigned int tile_idx = tile_y * tilemap.width + tile_x;
|
||||
if(tilemap.tiles[tile_idx].tile_type == SPIKES)
|
||||
{
|
||||
if (find_AABB_overlap(
|
||||
p_ctransform->position, p_bbox->size,
|
||||
(Vector2){
|
||||
tile_x * TILE_SIZE + tilemap.tiles[tile_idx].offset.x,
|
||||
tile_y * TILE_SIZE + tilemap.tiles[tile_idx].offset.y
|
||||
},
|
||||
tilemap.tiles[tile_idx].size,
|
||||
&overlap))
|
||||
{
|
||||
p_player->m_alive = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -704,12 +769,12 @@ void tile_collision_system(Scene_t* scene)
|
|||
if(tilemap.tiles[tile_idx].tile_type != EMPTY_TILE)
|
||||
{
|
||||
Vector2 other;
|
||||
other.x = (tile_idx % tilemap.width) * TILE_SIZE;
|
||||
other.y = (tile_idx / tilemap.width) * TILE_SIZE; // Precision loss is intentional
|
||||
other.x = (tile_idx % tilemap.width) * TILE_SIZE + tilemap.tiles[tile_idx].offset.x;
|
||||
other.y = (tile_idx / tilemap.width) * TILE_SIZE + tilemap.tiles[tile_idx].offset.y; // Precision loss is intentional
|
||||
|
||||
check_collision_and_move(
|
||||
&tilemap, p_ent,
|
||||
&other, TILE_SZ, tilemap.tiles[tile_idx].solid
|
||||
&other, tilemap.tiles[tile_idx].size, tilemap.tiles[tile_idx].solid
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -742,7 +807,7 @@ void tile_collision_system(Scene_t* scene)
|
|||
// Post movement edge check to zero out velocity
|
||||
uint8_t edges = check_bbox_edges(
|
||||
&data->tilemap, p_ent,
|
||||
p_ctransform->position, p_ctransform->prev_position, p_bbox->size
|
||||
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, 0
|
||||
);
|
||||
if (edges & (1<<3))
|
||||
{
|
||||
|
@ -868,7 +933,7 @@ void global_external_forces_system(Scene_t* scene)
|
|||
// Zero out acceleration for contacts with sturdy entites and tiles
|
||||
uint8_t edges = check_bbox_edges(
|
||||
&data->tilemap, p_ent,
|
||||
p_ctransform->position, p_ctransform->prev_position, p_bbox->size
|
||||
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, 0
|
||||
);
|
||||
if (edges & (1<<3))
|
||||
{
|
||||
|
|
|
@ -22,4 +22,5 @@ void boulder_destroy_wooden_tile_system(Scene_t* scene);
|
|||
void camera_update_system(Scene_t* scene);
|
||||
void player_dir_reset_system(Scene_t* scene);
|
||||
void player_respawn_system(Scene_t* scene);
|
||||
void player_spike_collision_system(Scene_t* scene);
|
||||
#endif // __GAME_SYSTEMS_H
|
||||
|
|
|
@ -15,9 +15,10 @@ typedef enum TileType {
|
|||
EMPTY_TILE = 0,
|
||||
SOLID_TILE,
|
||||
ONEWAY_TILE,
|
||||
LADDER
|
||||
LADDER,
|
||||
SPIKES,
|
||||
} TileType_t;
|
||||
#define MAX_TILE_TYPES 4
|
||||
#define MAX_TILE_TYPES 5
|
||||
typedef enum SolidType
|
||||
{
|
||||
NOT_SOLID = 0,
|
||||
|
@ -31,6 +32,8 @@ typedef struct Tile {
|
|||
SolidType_t solid;
|
||||
unsigned int water_level;
|
||||
struct sc_map_64v entities_set;
|
||||
Vector2 offset;
|
||||
Vector2 size;
|
||||
}Tile_t;
|
||||
|
||||
typedef struct TileGrid {
|
||||
|
|
|
@ -6,6 +6,44 @@
|
|||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
static void test_line_AABB(void **state)
|
||||
{
|
||||
(void) state;
|
||||
|
||||
Vector2 p1 = {0, 0};
|
||||
Vector2 p2 = {20, 20};
|
||||
|
||||
Rectangle box = {5, 0, 10, 20};
|
||||
assert_true(line_in_AABB(p1, p2, box));
|
||||
|
||||
p1.y = 20;
|
||||
assert_false(line_in_AABB(p1, p2, box));
|
||||
|
||||
p1.y = 19;
|
||||
p2 = (Vector2){19, 19};
|
||||
assert_true(line_in_AABB(p1, p2, box));
|
||||
|
||||
p1.y = 0;
|
||||
p2.y = 0;
|
||||
assert_true(line_in_AABB(p1, p2, box));
|
||||
|
||||
p1 = (Vector2){5, 0};
|
||||
p2 = (Vector2){5, 10};
|
||||
assert_true(line_in_AABB(p1, p2, box));
|
||||
|
||||
p1 = (Vector2){14, 0};
|
||||
p2 = (Vector2){14, 10};
|
||||
assert_true(line_in_AABB(p1, p2, box));
|
||||
|
||||
p1 = (Vector2){15, 0};
|
||||
p2 = (Vector2){15, 10};
|
||||
assert_false(line_in_AABB(p1, p2, box));
|
||||
|
||||
p1 = (Vector2){0, 30};
|
||||
p2 = (Vector2){6, 35};
|
||||
assert_false(line_in_AABB(p1, p2, box));
|
||||
}
|
||||
|
||||
static void test_point_AABB(void **state)
|
||||
{
|
||||
(void) state;
|
||||
|
@ -64,16 +102,14 @@ static void test_1D_overlap(void **state)
|
|||
assert_int_equal(find_1D_overlap(a, b, &overlap), 0);
|
||||
|
||||
a.y = 6;
|
||||
assert_int_equal(find_1D_overlap(a, b, &overlap), 0);
|
||||
assert_int_equal(find_1D_overlap(b, a, &overlap), 0);
|
||||
|
||||
a.y = 7;
|
||||
assert_int_equal(find_1D_overlap(a, b, &overlap), 1);
|
||||
assert_float_equal(overlap, -1, 1e-5);
|
||||
assert_int_equal(find_1D_overlap(b, a, &overlap), 1);
|
||||
assert_float_equal(overlap, 1, 1e-5);
|
||||
|
||||
a.y = 7;
|
||||
assert_int_equal(find_1D_overlap(a, b, &overlap), 1);
|
||||
assert_float_equal(overlap, -2, 1e-5);
|
||||
assert_int_equal(find_1D_overlap(b, a, &overlap), 1);
|
||||
assert_float_equal(overlap, 2, 1e-5);
|
||||
|
||||
a.x = 7;
|
||||
a.y = 9;
|
||||
|
@ -86,6 +122,7 @@ int main(void)
|
|||
cmocka_unit_test(test_1D_overlap),
|
||||
cmocka_unit_test(test_AABB_overlap),
|
||||
cmocka_unit_test(test_point_AABB),
|
||||
cmocka_unit_test(test_line_AABB),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
|
|
Loading…
Reference in New Issue