Compare commits
No commits in common. "b5790ef00bab75b4b37890ad0aa61b3943d848fd" and "a719c73c5040b4063ab0eb3dddd2204951523487" have entirely different histories.
b5790ef00b
...
a719c73c50
|
@ -14,13 +14,12 @@ enum EntitySpawnSelection {
|
||||||
TOGGLE_TILE = 0,
|
TOGGLE_TILE = 0,
|
||||||
TOGGLE_ONEWAY,
|
TOGGLE_ONEWAY,
|
||||||
TOGGLE_LADDER,
|
TOGGLE_LADDER,
|
||||||
TOGGLE_SPIKE,
|
|
||||||
SPAWN_CRATE,
|
SPAWN_CRATE,
|
||||||
SPAWN_METAL_CRATE,
|
SPAWN_METAL_CRATE,
|
||||||
SPAWN_BOULDER,
|
SPAWN_BOULDER,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_SPAWN_TYPE 7
|
#define MAX_SPAWN_TYPE 6
|
||||||
static unsigned int current_spawn_selection = 0;
|
static unsigned int current_spawn_selection = 0;
|
||||||
|
|
||||||
static inline unsigned int get_tile_idx(int x, int y, const TileGrid_t* tilemap)
|
static inline unsigned int get_tile_idx(int x, int y, const TileGrid_t* tilemap)
|
||||||
|
@ -36,21 +35,6 @@ static inline unsigned int get_tile_idx(int x, int y, const TileGrid_t* tilemap)
|
||||||
return MAX_N_TILES;
|
return MAX_N_TILES;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* get_spawn_selection_string(enum EntitySpawnSelection sel)
|
|
||||||
{
|
|
||||||
switch(sel)
|
|
||||||
{
|
|
||||||
case TOGGLE_TILE: return "solid tile";
|
|
||||||
case TOGGLE_ONEWAY: return "wooden tile";
|
|
||||||
case TOGGLE_LADDER: return "ladder";
|
|
||||||
case TOGGLE_SPIKE: return "spike";
|
|
||||||
case SPAWN_CRATE: return "wooden crate";
|
|
||||||
case SPAWN_METAL_CRATE: return "metal crate";
|
|
||||||
case SPAWN_BOULDER: return "boulder";
|
|
||||||
default: return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void level_scene_render_func(Scene_t* scene)
|
static void level_scene_render_func(Scene_t* scene)
|
||||||
{
|
{
|
||||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||||
|
@ -84,13 +68,6 @@ static void level_scene_render_func(Scene_t* scene)
|
||||||
{
|
{
|
||||||
DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, ORANGE);
|
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)
|
if (tilemap.tiles[i].water_level > 0)
|
||||||
{
|
{
|
||||||
|
@ -98,12 +75,6 @@ static void level_scene_render_func(Scene_t* scene)
|
||||||
Color water_colour = ColorAlpha(BLUE, 0.5);
|
Color water_colour = ColorAlpha(BLUE, 0.5);
|
||||||
DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, water_colour);
|
DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, water_colour);
|
||||||
}
|
}
|
||||||
if (tilemap.tiles[i].moveable)
|
|
||||||
{
|
|
||||||
// Draw water tile
|
|
||||||
Color water_colour = ColorAlpha(GREEN, 0.2);
|
|
||||||
DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, water_colour);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[64] = {0};
|
char buffer[64] = {0};
|
||||||
|
@ -239,7 +210,7 @@ static void level_scene_render_func(Scene_t* scene)
|
||||||
sprintf(buffer, "Ladder: %u", p_pstate->ladder_state);
|
sprintf(buffer, "Ladder: %u", p_pstate->ladder_state);
|
||||||
DrawText(buffer, gui_x, 150, 12, BLACK);
|
DrawText(buffer, gui_x, 150, 12, BLACK);
|
||||||
}
|
}
|
||||||
sprintf(buffer, "Spawn Entity: %s", get_spawn_selection_string(current_spawn_selection));
|
sprintf(buffer, "Spawn Entity: %u", current_spawn_selection);
|
||||||
DrawText(buffer, gui_x, 240, 12, BLACK);
|
DrawText(buffer, gui_x, 240, 12, BLACK);
|
||||||
sprintf(buffer, "Number of Entities: %u", sc_map_size_64v(&scene->ent_manager.entities));
|
sprintf(buffer, "Number of Entities: %u", sc_map_size_64v(&scene->ent_manager.entities));
|
||||||
DrawText(buffer, gui_x, 270, 12, BLACK);
|
DrawText(buffer, gui_x, 270, 12, BLACK);
|
||||||
|
@ -346,17 +317,6 @@ static void toggle_block_system(Scene_t* scene)
|
||||||
tilemap.tiles[down_tile].solid = (tilemap.tiles[tile_idx].tile_type != LADDER)? ONE_WAY : NOT_SOLID;
|
tilemap.tiles[down_tile].solid = (tilemap.tiles[tile_idx].tile_type != LADDER)? ONE_WAY : NOT_SOLID;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case SPAWN_CRATE:
|
||||||
spawn_crate(scene, tile_idx, false);
|
spawn_crate(scene, tile_idx, false);
|
||||||
break;
|
break;
|
||||||
|
@ -367,45 +327,7 @@ static void toggle_block_system(Scene_t* scene)
|
||||||
spawn_boulder(scene, tile_idx);
|
spawn_boulder(scene, tile_idx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tilemap.tiles[tile_idx].tile_type == SPIKES)
|
|
||||||
{
|
|
||||||
// Priority: Down, Up, Left, Right
|
|
||||||
if (tile_idx + tilemap.width < MAX_N_TILES && tilemap.tiles[tile_idx + tilemap.width].tile_type == SOLID_TILE)
|
|
||||||
{
|
|
||||||
tilemap.tiles[tile_idx].offset = (Vector2){0,16};
|
|
||||||
tilemap.tiles[tile_idx].size = (Vector2){32,16};
|
|
||||||
}
|
|
||||||
else 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 && 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 + 1) % tilemap.width != 0 && 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;
|
last_tile_idx = tile_idx;
|
||||||
tilemap.tiles[tile_idx].moveable = (
|
|
||||||
tilemap.tiles[tile_idx].tile_type == EMPTY_TILE
|
|
||||||
|| tilemap.tiles[tile_idx].tile_type == SPIKES
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON))
|
else if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON))
|
||||||
|
@ -509,7 +431,6 @@ void init_level_scene(LevelScene_t* scene)
|
||||||
sc_array_add(&scene->scene.systems, &update_tilemap_system);
|
sc_array_add(&scene->scene.systems, &update_tilemap_system);
|
||||||
sc_array_add(&scene->scene.systems, &hitbox_update_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_crushing_system);
|
||||||
sc_array_add(&scene->scene.systems, &spike_collision_system);
|
|
||||||
sc_array_add(&scene->scene.systems, &state_transition_update_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, &player_ground_air_transition_system);
|
||||||
sc_array_add(&scene->scene.systems, &sprite_animation_system);
|
sc_array_add(&scene->scene.systems, &sprite_animation_system);
|
||||||
|
@ -540,16 +461,13 @@ void init_level_scene(LevelScene_t* scene)
|
||||||
{
|
{
|
||||||
all_tiles[i].solid = NOT_SOLID;
|
all_tiles[i].solid = NOT_SOLID;
|
||||||
all_tiles[i].tile_type = EMPTY_TILE;
|
all_tiles[i].tile_type = EMPTY_TILE;
|
||||||
all_tiles[i].moveable = true;
|
|
||||||
sc_map_init_64v(&all_tiles[i].entities_set, 16, 0);
|
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)
|
for (size_t i = 0; i < scene->data.tilemap.width; ++i)
|
||||||
{
|
{
|
||||||
unsigned int tile_idx = (scene->data.tilemap.height - 1) * scene->data.tilemap.width + i;
|
unsigned int tile_idx = (scene->data.tilemap.height - 1) * scene->data.tilemap.width + i;
|
||||||
all_tiles[tile_idx].solid = SOLID; // for testing
|
all_tiles[tile_idx].solid = SOLID; // for testing
|
||||||
all_tiles[tile_idx].tile_type = SOLID_TILE; // for testing
|
all_tiles[tile_idx].tile_type = SOLID_TILE; // for testing
|
||||||
all_tiles[tile_idx].moveable = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create_player(&scene->scene.ent_manager, &scene->scene.engine->assets);
|
create_player(&scene->scene.ent_manager, &scene->scene.engine->assets);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap)
|
uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap)
|
||||||
{
|
{
|
||||||
// No 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)
|
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
|
//Partial overlap
|
||||||
// x is p1, y is p2
|
// x is p1, y is p2
|
||||||
*overlap = (l2.y > l1.y)? l2.x - l1.y : l2.y - l1.x;
|
*overlap = (l2.y >= l1.y)? l2.x - l1.y - 1 : l2.y - l1.x + 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,15 +25,15 @@ uint8_t find_AABB_overlap(const Vector2 tl1, const Vector2 sz1, const Vector2 tl
|
||||||
Vector2 l1, l2;
|
Vector2 l1, l2;
|
||||||
uint8_t overlap_x, overlap_y;
|
uint8_t overlap_x, overlap_y;
|
||||||
l1.x = tl1.x;
|
l1.x = tl1.x;
|
||||||
l1.y = tl1.x + sz1.x;
|
l1.y = tl1.x + sz1.x - 1;
|
||||||
l2.x = tl2.x;
|
l2.x = tl2.x;
|
||||||
l2.y = tl2.x + sz2.x;
|
l2.y = tl2.x + sz2.x - 1;
|
||||||
|
|
||||||
overlap_x = find_1D_overlap(l1, l2, &overlap->x);
|
overlap_x = find_1D_overlap(l1, l2, &overlap->x);
|
||||||
l1.x = tl1.y;
|
l1.x = tl1.y;
|
||||||
l1.y = tl1.y + sz1.y;
|
l1.y = tl1.y + sz1.y - 1;
|
||||||
l2.x = tl2.y;
|
l2.x = tl2.y;
|
||||||
l2.y = tl2.y + sz2.y;
|
l2.y = tl2.y + sz2.y - 1;
|
||||||
overlap_y = find_1D_overlap(l1, l2, &overlap->y);
|
overlap_y = find_1D_overlap(l1, l2, &overlap->y);
|
||||||
|
|
||||||
if (overlap_x == 2 && overlap_y == 2) return 2;
|
if (overlap_x == 2 && overlap_y == 2) return 2;
|
||||||
|
@ -49,68 +49,3 @@ bool point_in_AABB(Vector2 point, Rectangle box)
|
||||||
&& point.y < box.y + box.height
|
&& 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, box.y},
|
|
||||||
{box.x + box.width, box.y + box.height},
|
|
||||||
{box.x, box.y + box.height},
|
|
||||||
};
|
|
||||||
|
|
||||||
float F = (A * box.x + B * box.y + C);
|
|
||||||
|
|
||||||
bool collide = false;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
collide = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
last_mode = mode;
|
|
||||||
}
|
|
||||||
if (!collide) return false;
|
|
||||||
|
|
||||||
//Projection check
|
|
||||||
Vector2 overlap = {0};
|
|
||||||
Vector2 l1, l2;
|
|
||||||
l1.x = p1.x;
|
|
||||||
l1.y = p2.x;
|
|
||||||
l2.x = box.x;
|
|
||||||
l2.y = box.x + box.width;
|
|
||||||
|
|
||||||
find_1D_overlap(l1, l2, &overlap.x);
|
|
||||||
l1.x = p1.y;
|
|
||||||
l1.y = p2.y;
|
|
||||||
l2.x = box.y;
|
|
||||||
l2.y = box.y + box.height;
|
|
||||||
find_1D_overlap(l1, l2, &overlap.y);
|
|
||||||
|
|
||||||
return (overlap.x != 0 && overlap.y != 0);
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,5 +6,4 @@
|
||||||
uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap);
|
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);
|
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 point_in_AABB(Vector2 point, Rectangle box);
|
||||||
bool line_in_AABB(Vector2 p1, Vector2 p2, Rectangle box);
|
|
||||||
#endif // __AABB_H
|
#endif // __AABB_H
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static const Vector2 TILE_SZ = {TILE_SIZE, TILE_SIZE};
|
||||||
static const Vector2 GRAVITY = {0, GRAV_ACCEL};
|
static const Vector2 GRAVITY = {0, GRAV_ACCEL};
|
||||||
static const Vector2 UPTHRUST = {0, -GRAV_ACCEL * 1.1};
|
static const Vector2 UPTHRUST = {0, -GRAV_ACCEL * 1.1};
|
||||||
typedef enum AnchorPoint {
|
typedef enum AnchorPoint {
|
||||||
|
@ -51,30 +52,15 @@ static uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, boo
|
||||||
{
|
{
|
||||||
if (tile_x >= grid->width) return 0;
|
if (tile_x >= grid->width) return 0;
|
||||||
unsigned int tile_idx = tile_y*grid->width + tile_x;
|
unsigned int tile_idx = tile_y*grid->width + tile_x;
|
||||||
|
if (grid->tiles[tile_idx].solid == SOLID) return 1;
|
||||||
|
|
||||||
Vector2 overlap;
|
Vector2 overlap;
|
||||||
if (grid->tiles[tile_idx].solid == SOLID)
|
|
||||||
{
|
|
||||||
if (find_AABB_overlap(
|
|
||||||
(Vector2){ent->bbox.x, ent->bbox.y},
|
|
||||||
(Vector2){ent->bbox.width, ent->bbox.height},
|
|
||||||
(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
|
|
||||||
))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_oneway && grid->tiles[tile_idx].solid == ONE_WAY)
|
if (check_oneway && grid->tiles[tile_idx].solid == ONE_WAY)
|
||||||
{
|
{
|
||||||
find_AABB_overlap(
|
find_AABB_overlap(
|
||||||
(Vector2){ent->bbox.x, ent->bbox.y},
|
(Vector2){ent->bbox.x, ent->bbox.y},
|
||||||
(Vector2){ent->bbox.width, ent->bbox.height},
|
(Vector2){ent->bbox.width, ent->bbox.height},
|
||||||
(Vector2){tile_x * TILE_SIZE + grid->tiles[tile_idx].offset.x, tile_y * TILE_SIZE + grid->tiles[tile_idx].offset.y},
|
(Vector2){tile_x * TILE_SIZE, tile_y * TILE_SIZE}, TILE_SZ, &overlap
|
||||||
grid->tiles[tile_idx].size,
|
|
||||||
&overlap
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//For one-way platform, check for vectical collision, only return true for up direction
|
//For one-way platform, check for vectical collision, only return true for up direction
|
||||||
|
@ -109,71 +95,6 @@ static uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, boo
|
||||||
return 0;
|
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)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
};
|
|
||||||
if ( line_in_AABB(p1, p2, tile_rec) ) 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
|
// TODO: This should be a point collision check, not an AABB check
|
||||||
static bool check_collision_offset(
|
static bool check_collision_offset(
|
||||||
Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz,
|
Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz,
|
||||||
|
@ -263,7 +184,7 @@ static bool check_collision_and_move(
|
||||||
&& (p_ct->prev_position.y + p_bbox->size.y - 1 < other_pos->y))
|
&& (p_ct->prev_position.y + p_bbox->size.y - 1 < other_pos->y))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//if (!check_collision_offset(ent, p_ct->position, p_bbox->size, tilemap, offset))
|
//if (!check_collision_at(ent, p_ct->position, p_bbox->size, tilemap, offset))
|
||||||
{
|
{
|
||||||
p_ct->position = Vector2Add(p_ct->position, offset);
|
p_ct->position = Vector2Add(p_ct->position, offset);
|
||||||
}
|
}
|
||||||
|
@ -320,60 +241,48 @@ collision_end:
|
||||||
|
|
||||||
static uint8_t check_bbox_edges(
|
static uint8_t check_bbox_edges(
|
||||||
TileGrid_t* tilemap,
|
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
|
||||||
bool ignore_fragile
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint8_t detected = 0;
|
uint8_t detected = 0;
|
||||||
|
|
||||||
// Too lazy to adjust the tile area to check, so just make a big one
|
|
||||||
CollideEntity_t ent =
|
CollideEntity_t ent =
|
||||||
{
|
{
|
||||||
.p_ent = p_ent,
|
.p_ent = p_ent,
|
||||||
.bbox = (Rectangle){pos.x - 1, pos.y, 1, bbox.y},
|
.bbox = (Rectangle){pos.x - 1, pos.y, bbox.x, bbox.y},
|
||||||
.prev_bbox = (Rectangle){pos.x, pos.y, bbox.x, bbox.y},
|
.prev_bbox = (Rectangle){pos.x, pos.y, bbox.x, bbox.y},
|
||||||
.area = (TileArea_t){
|
.area = (TileArea_t){
|
||||||
.tile_x1 = (pos.x - 1) / TILE_SIZE,
|
.tile_x1 = (pos.x - 1) / TILE_SIZE,
|
||||||
.tile_y1 = (pos.y - 1) / TILE_SIZE,
|
.tile_y1 = (pos.y) / TILE_SIZE,
|
||||||
.tile_x2 = (pos.x + bbox.x) / TILE_SIZE,
|
.tile_x2 = (pos.x - 1) / TILE_SIZE,
|
||||||
.tile_y2 = (pos.y + bbox.y) / TILE_SIZE,
|
.tile_y2 = (pos.y + bbox.y - 1) / TILE_SIZE,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Handle one-way platform
|
||||||
// Left
|
// Left
|
||||||
uint8_t collide_type = check_collision_line(&ent, tilemap, false);
|
detected |= (check_collision(&ent, tilemap, false) ? 1 : 0) << 3;
|
||||||
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
|
||||||
{
|
|
||||||
detected |= 1 << 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Right
|
//Right
|
||||||
ent.bbox.x = pos.x + bbox.x + 1; // 2 to account for the previous subtraction
|
ent.bbox.x += 2; // 2 to account for the previous subtraction
|
||||||
collide_type = check_collision_line(&ent, tilemap, false);
|
ent.area.tile_x1 = (pos.x + bbox.x) / TILE_SIZE;
|
||||||
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
ent.area.tile_x2 = ent.area.tile_x1;
|
||||||
{
|
detected |= (check_collision(&ent, tilemap, false) ? 1 : 0) << 2;
|
||||||
detected |= 1 << 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Up
|
// Up
|
||||||
ent.bbox.x = pos.x;
|
ent.bbox.x -= 2;
|
||||||
ent.bbox.y = pos.y - 1;
|
ent.bbox.y--;
|
||||||
ent.bbox.width = bbox.x;
|
ent.area.tile_x1 = (pos.x) / TILE_SIZE,
|
||||||
ent.bbox.height = 1;
|
ent.area.tile_x2 = (pos.x + bbox.x - 1) / TILE_SIZE,
|
||||||
collide_type = check_collision_line(&ent, tilemap, false);
|
ent.area.tile_y1 = (pos.y - 1) / TILE_SIZE,
|
||||||
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
ent.area.tile_y2 = ent.area.tile_y1;
|
||||||
{
|
detected |= (check_collision(&ent, tilemap, false) ? 1 : 0) << 1;
|
||||||
detected |= 1 << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Down
|
// Down
|
||||||
ent.bbox.y = pos.y + bbox.y + 1;
|
ent.bbox.y += 2;
|
||||||
collide_type = check_collision_line(&ent, tilemap, true);
|
ent.area.tile_y1 = (pos.y + bbox.y) / TILE_SIZE,
|
||||||
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
ent.area.tile_y2 = ent.area.tile_y1;
|
||||||
{
|
detected |= (check_collision(&ent, tilemap, true) ? 1 : 0);
|
||||||
detected |= 1;
|
|
||||||
}
|
|
||||||
return detected;
|
return detected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,145 +613,60 @@ void player_bbox_update_system(Scene_t* scene)
|
||||||
void player_crushing_system(Scene_t* scene)
|
void player_crushing_system(Scene_t* scene)
|
||||||
{
|
{
|
||||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||||
|
TileGrid_t tilemap = data->tilemap;
|
||||||
|
|
||||||
Entity_t* p_player;
|
Entity_t* p_player;
|
||||||
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], 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);
|
CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T);
|
||||||
CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T);
|
CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T);
|
||||||
|
CollideEntity_t ent =
|
||||||
uint8_t edges = check_bbox_edges(
|
|
||||||
&data->tilemap, p_player,
|
|
||||||
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, true
|
|
||||||
);
|
|
||||||
|
|
||||||
// There is a second check for to ensure that there is an solid entity/tile overlapping the player bbox
|
|
||||||
// This is to prevent crushing by perfectly fitting in a gap (imagine a size 32 player in between two tiles)
|
|
||||||
// or any scenario where the edge check is just fringing, not overlapping
|
|
||||||
if ((edges & 0b0011) == 0b0011)
|
|
||||||
{
|
{
|
||||||
uint8_t collide = 0;
|
.p_ent = p_player,
|
||||||
CollideEntity_t ent =
|
.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},
|
||||||
.p_ent = p_player,
|
.area = (TileArea_t){
|
||||||
.bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, p_bbox->size.x, 1},
|
.tile_x1 = (p_ctransform->position.x) / TILE_SIZE,
|
||||||
.prev_bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, p_bbox->size.x, p_bbox->size.y},
|
.tile_y1 = (p_ctransform->position.y) / TILE_SIZE,
|
||||||
.area = (TileArea_t){
|
.tile_x2 = (p_ctransform->position.x) / TILE_SIZE,
|
||||||
.tile_x1 = (p_ctransform->position.x) / TILE_SIZE,
|
.tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
|
||||||
.tile_y1 = (p_ctransform->position.y) / TILE_SIZE,
|
},
|
||||||
.tile_x2 = (p_ctransform->position.x + p_bbox->size.x - 1) / TILE_SIZE,
|
};
|
||||||
.tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t collide_type = check_collision_line(&ent, &data->tilemap, false);
|
|
||||||
if (collide_type == 1)
|
|
||||||
{
|
|
||||||
collide |= 1 << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ent.bbox.y = p_ctransform->position.y + p_bbox->size.y;
|
|
||||||
collide_type = check_collision_line(&ent, &data->tilemap, true);
|
|
||||||
if (collide_type == 1)
|
|
||||||
{
|
|
||||||
collide |= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (collide != 0)
|
// Mostly identical to edge check function
|
||||||
{
|
// Except we want collision instead of just touching
|
||||||
p_player->m_alive = false;
|
uint8_t detected = 0;
|
||||||
return;
|
// Left
|
||||||
}
|
detected |= (check_collision(&ent, &tilemap, false) ? 1 : 0);
|
||||||
|
|
||||||
|
//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)
|
||||||
|
{
|
||||||
|
p_player->m_alive = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((edges & 0b1100) == 0b1100)
|
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)
|
||||||
{
|
{
|
||||||
uint8_t collide = 0;
|
p_player->m_alive = false;
|
||||||
CollideEntity_t ent =
|
return;
|
||||||
{
|
|
||||||
.p_ent = p_player,
|
|
||||||
.bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, 1, p_bbox->size.y},
|
|
||||||
.prev_bbox = (Rectangle){p_ctransform->position.x, p_ctransform->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 + p_bbox->size.x - 1) / TILE_SIZE,
|
|
||||||
.tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Left
|
|
||||||
uint8_t collide_type = check_collision_line(&ent, &data->tilemap, false);
|
|
||||||
if (collide_type == 1)
|
|
||||||
{
|
|
||||||
collide |= 1 << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Right
|
|
||||||
ent.bbox.x = p_ctransform->position.x + p_bbox->size.x; // 2 to account for the previous subtraction
|
|
||||||
collide_type = check_collision_line(&ent, &data->tilemap, false);
|
|
||||||
if (collide_type == 1)
|
|
||||||
{
|
|
||||||
collide |= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (collide != 0)
|
|
||||||
{
|
|
||||||
p_player->m_alive = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void 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;
|
|
||||||
CBBox_t* p_bbox;
|
|
||||||
unsigned int ent_idx;
|
|
||||||
sc_map_foreach(&scene->ent_manager.component_map[CBBOX_COMP_T], ent_idx, p_bbox)
|
|
||||||
{
|
|
||||||
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
|
|
||||||
CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_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++)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
uint8_t collide = 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);
|
|
||||||
|
|
||||||
if (collide)
|
|
||||||
{
|
|
||||||
if (p_ent->m_tag == PLAYER_ENT_TAG)
|
|
||||||
{
|
|
||||||
p_ent->m_alive = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tilemap.tiles[tile_idx].tile_type = EMPTY_TILE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -867,8 +691,8 @@ void tile_collision_system(Scene_t* scene)
|
||||||
// exclude self
|
// exclude self
|
||||||
// This has an extra pixel when gathering potential collision, just to avoid missing any
|
// This has an extra pixel when gathering potential collision, just to avoid missing any
|
||||||
// This is only done here, collision methods do not have this
|
// This is only done here, collision methods do not have this
|
||||||
unsigned int tile_x1 = (p_ctransform->position.x - 1) / TILE_SIZE;
|
unsigned int tile_x1 = (p_ctransform->position.x) / TILE_SIZE;
|
||||||
unsigned int tile_y1 = (p_ctransform->position.y - 1) / TILE_SIZE;
|
unsigned int tile_y1 = (p_ctransform->position.y) / TILE_SIZE;
|
||||||
unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x) / TILE_SIZE;
|
unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x) / TILE_SIZE;
|
||||||
unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE;
|
unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE;
|
||||||
|
|
||||||
|
@ -880,12 +704,12 @@ void tile_collision_system(Scene_t* scene)
|
||||||
if(tilemap.tiles[tile_idx].tile_type != EMPTY_TILE)
|
if(tilemap.tiles[tile_idx].tile_type != EMPTY_TILE)
|
||||||
{
|
{
|
||||||
Vector2 other;
|
Vector2 other;
|
||||||
other.x = (tile_idx % tilemap.width) * TILE_SIZE + tilemap.tiles[tile_idx].offset.x;
|
other.x = (tile_idx % tilemap.width) * TILE_SIZE;
|
||||||
other.y = (tile_idx / tilemap.width) * TILE_SIZE + tilemap.tiles[tile_idx].offset.y; // Precision loss is intentional
|
other.y = (tile_idx / tilemap.width) * TILE_SIZE; // Precision loss is intentional
|
||||||
|
|
||||||
check_collision_and_move(
|
check_collision_and_move(
|
||||||
&tilemap, p_ent,
|
&tilemap, p_ent,
|
||||||
&other, tilemap.tiles[tile_idx].size, tilemap.tiles[tile_idx].solid
|
&other, TILE_SZ, tilemap.tiles[tile_idx].solid
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -918,7 +742,7 @@ void tile_collision_system(Scene_t* scene)
|
||||||
// Post movement edge check to zero out velocity
|
// Post movement edge check to zero out velocity
|
||||||
uint8_t edges = check_bbox_edges(
|
uint8_t edges = check_bbox_edges(
|
||||||
&data->tilemap, p_ent,
|
&data->tilemap, p_ent,
|
||||||
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, false
|
p_ctransform->position, p_ctransform->prev_position, p_bbox->size
|
||||||
);
|
);
|
||||||
if (edges & (1<<3))
|
if (edges & (1<<3))
|
||||||
{
|
{
|
||||||
|
@ -1044,7 +868,7 @@ void global_external_forces_system(Scene_t* scene)
|
||||||
// Zero out acceleration for contacts with sturdy entites and tiles
|
// Zero out acceleration for contacts with sturdy entites and tiles
|
||||||
uint8_t edges = check_bbox_edges(
|
uint8_t edges = check_bbox_edges(
|
||||||
&data->tilemap, p_ent,
|
&data->tilemap, p_ent,
|
||||||
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, false
|
p_ctransform->position, p_ctransform->prev_position, p_bbox->size
|
||||||
);
|
);
|
||||||
if (edges & (1<<3))
|
if (edges & (1<<3))
|
||||||
{
|
{
|
||||||
|
@ -1146,7 +970,10 @@ void moveable_update_system(Scene_t* scene)
|
||||||
{
|
{
|
||||||
unsigned int tile_idx1 = tile_y * tilemap.width + tile_x;
|
unsigned int tile_idx1 = tile_y * tilemap.width + tile_x;
|
||||||
unsigned int tile_idx2 = tile_y2 * tilemap.width + tile_x;
|
unsigned int tile_idx2 = tile_y2 * tilemap.width + tile_x;
|
||||||
if ( tilemap.tiles[tile_idx1].moveable && tilemap.tiles[tile_idx2].moveable )
|
if (
|
||||||
|
tilemap.tiles[tile_idx1].tile_type == EMPTY_TILE
|
||||||
|
&& tilemap.tiles[tile_idx2].tile_type == EMPTY_TILE
|
||||||
|
)
|
||||||
{
|
{
|
||||||
bool any_solid = false;
|
bool any_solid = false;
|
||||||
unsigned int idx_to_check;
|
unsigned int idx_to_check;
|
||||||
|
@ -1175,7 +1002,9 @@ void moveable_update_system(Scene_t* scene)
|
||||||
{
|
{
|
||||||
unsigned int tile_idx1 = tile_y * tilemap.width + tile_x;
|
unsigned int tile_idx1 = tile_y * tilemap.width + tile_x;
|
||||||
unsigned int tile_idx2 = tile_y2 * tilemap.width + tile_x;
|
unsigned int tile_idx2 = tile_y2 * tilemap.width + tile_x;
|
||||||
if ( tilemap.tiles[tile_idx1].moveable && tilemap.tiles[tile_idx2].moveable )
|
if (tilemap.tiles[tile_idx1].tile_type == EMPTY_TILE
|
||||||
|
&& tilemap.tiles[tile_idx2].tile_type == EMPTY_TILE
|
||||||
|
)
|
||||||
{
|
{
|
||||||
bool any_solid = false;
|
bool any_solid = false;
|
||||||
unsigned int idx_to_check;
|
unsigned int idx_to_check;
|
||||||
|
@ -1286,7 +1115,7 @@ void player_pushing_system(Scene_t* scene)
|
||||||
{
|
{
|
||||||
unsigned int target_tile_idx = tile_y * tilemap.width + tile_x;
|
unsigned int target_tile_idx = tile_y * tilemap.width + tile_x;
|
||||||
if (
|
if (
|
||||||
tilemap.tiles[target_tile_idx].moveable
|
tilemap.tiles[target_tile_idx].tile_type == EMPTY_TILE
|
||||||
&& sc_map_size_64v(&tilemap.tiles[target_tile_idx].entities_set) == 0
|
&& sc_map_size_64v(&tilemap.tiles[target_tile_idx].entities_set) == 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -1629,18 +1458,15 @@ void boulder_destroy_wooden_tile_system(Scene_t* scene)
|
||||||
{
|
{
|
||||||
tilemap.tiles[tile_idx].tile_type = EMPTY_TILE;
|
tilemap.tiles[tile_idx].tile_type = EMPTY_TILE;
|
||||||
tilemap.tiles[tile_idx].solid = NOT_SOLID;
|
tilemap.tiles[tile_idx].solid = NOT_SOLID;
|
||||||
tilemap.tiles[tile_idx].moveable = true;
|
|
||||||
if (tile_x > 0 && tilemap.tiles[tile_idx - 1].tile_type == ONEWAY_TILE)
|
if (tile_x > 0 && tilemap.tiles[tile_idx - 1].tile_type == ONEWAY_TILE)
|
||||||
{
|
{
|
||||||
tilemap.tiles[tile_idx - 1].tile_type = EMPTY_TILE;
|
tilemap.tiles[tile_idx - 1].tile_type = EMPTY_TILE;
|
||||||
tilemap.tiles[tile_idx - 1].solid = NOT_SOLID;
|
tilemap.tiles[tile_idx - 1].solid = NOT_SOLID;
|
||||||
tilemap.tiles[tile_idx - 1].moveable = true;
|
|
||||||
}
|
}
|
||||||
if (tile_x < tilemap.width && tilemap.tiles[tile_idx + 1].tile_type == ONEWAY_TILE)
|
if (tile_x < tilemap.width && tilemap.tiles[tile_idx + 1].tile_type == ONEWAY_TILE)
|
||||||
{
|
{
|
||||||
tilemap.tiles[tile_idx + 1].tile_type = EMPTY_TILE;
|
tilemap.tiles[tile_idx + 1].tile_type = EMPTY_TILE;
|
||||||
tilemap.tiles[tile_idx + 1].solid = NOT_SOLID;
|
tilemap.tiles[tile_idx + 1].solid = NOT_SOLID;
|
||||||
tilemap.tiles[tile_idx + 1].moveable = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,5 +22,4 @@ void boulder_destroy_wooden_tile_system(Scene_t* scene);
|
||||||
void camera_update_system(Scene_t* scene);
|
void camera_update_system(Scene_t* scene);
|
||||||
void player_dir_reset_system(Scene_t* scene);
|
void player_dir_reset_system(Scene_t* scene);
|
||||||
void player_respawn_system(Scene_t* scene);
|
void player_respawn_system(Scene_t* scene);
|
||||||
void spike_collision_system(Scene_t* scene);
|
|
||||||
#endif // __GAME_SYSTEMS_H
|
#endif // __GAME_SYSTEMS_H
|
||||||
|
|
|
@ -15,10 +15,9 @@ typedef enum TileType {
|
||||||
EMPTY_TILE = 0,
|
EMPTY_TILE = 0,
|
||||||
SOLID_TILE,
|
SOLID_TILE,
|
||||||
ONEWAY_TILE,
|
ONEWAY_TILE,
|
||||||
LADDER,
|
LADDER
|
||||||
SPIKES,
|
|
||||||
} TileType_t;
|
} TileType_t;
|
||||||
#define MAX_TILE_TYPES 5
|
#define MAX_TILE_TYPES 4
|
||||||
typedef enum SolidType
|
typedef enum SolidType
|
||||||
{
|
{
|
||||||
NOT_SOLID = 0,
|
NOT_SOLID = 0,
|
||||||
|
@ -32,9 +31,6 @@ typedef struct Tile {
|
||||||
SolidType_t solid;
|
SolidType_t solid;
|
||||||
unsigned int water_level;
|
unsigned int water_level;
|
||||||
struct sc_map_64v entities_set;
|
struct sc_map_64v entities_set;
|
||||||
Vector2 offset;
|
|
||||||
Vector2 size;
|
|
||||||
bool moveable;
|
|
||||||
}Tile_t;
|
}Tile_t;
|
||||||
|
|
||||||
typedef struct TileGrid {
|
typedef struct TileGrid {
|
||||||
|
|
|
@ -6,44 +6,6 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <cmocka.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)
|
static void test_point_AABB(void **state)
|
||||||
{
|
{
|
||||||
(void) state;
|
(void) state;
|
||||||
|
@ -102,14 +64,16 @@ static void test_1D_overlap(void **state)
|
||||||
assert_int_equal(find_1D_overlap(a, b, &overlap), 0);
|
assert_int_equal(find_1D_overlap(a, b, &overlap), 0);
|
||||||
|
|
||||||
a.y = 6;
|
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_int_equal(find_1D_overlap(a, b, &overlap), 1);
|
||||||
assert_float_equal(overlap, -1, 1e-5);
|
assert_float_equal(overlap, -1, 1e-5);
|
||||||
assert_int_equal(find_1D_overlap(b, a, &overlap), 1);
|
assert_int_equal(find_1D_overlap(b, a, &overlap), 1);
|
||||||
assert_float_equal(overlap, 1, 1e-5);
|
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.x = 7;
|
||||||
a.y = 9;
|
a.y = 9;
|
||||||
|
@ -122,7 +86,6 @@ int main(void)
|
||||||
cmocka_unit_test(test_1D_overlap),
|
cmocka_unit_test(test_1D_overlap),
|
||||||
cmocka_unit_test(test_AABB_overlap),
|
cmocka_unit_test(test_AABB_overlap),
|
||||||
cmocka_unit_test(test_point_AABB),
|
cmocka_unit_test(test_point_AABB),
|
||||||
cmocka_unit_test(test_line_AABB),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
|
Loading…
Reference in New Issue