Place position field into Entity

Position is so commonly used that placing it into Entity from the
CTransform components reduces the reference to CTransform.

Void Particle proved that it made development much easier.
scene_man
En Yi 2024-04-22 22:15:21 +08:00
parent 402d6f658e
commit a2c061c5e8
9 changed files with 239 additions and 273 deletions

View File

@ -45,7 +45,6 @@ typedef struct _CBBox_t {
typedef struct _CTransform_t {
Vector2 prev_position;
Vector2 prev_velocity;
Vector2 position;
Vector2 velocity;
Vector2 accel;
Vector2 fric_coeff;
@ -233,6 +232,7 @@ static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y)
struct Entity {
Vector2 spawn_pos;
Vector2 position;
unsigned long m_id;
unsigned int m_tag;
unsigned long components[N_COMPONENTS];

View File

@ -65,9 +65,8 @@ uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, bool check
{
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 == NULL) continue;
//if (p_bbox->solid && !p_bbox->fragile)
if (p_bbox->solid)
{
@ -75,7 +74,7 @@ uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, bool check
find_AABB_overlap(
(Vector2){ent->bbox.x, ent->bbox.y},
(Vector2){ent->bbox.width, ent->bbox.height},
p_ctransform->position, p_bbox->size, &overlap
p_other_ent->position, p_bbox->size, &overlap
)
)
{
@ -134,14 +133,13 @@ uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool
{
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 == NULL) continue;
if (p_bbox->solid)
{
Rectangle box = {
.x = p_ctransform->position.x,
.y = p_ctransform->position.y,
.x = p_other_ent->position.x,
.y = p_other_ent->position.y,
.width = p_bbox->size.x,
.height = p_bbox->size.y,
};

View File

@ -136,7 +136,7 @@ static void level_scene_render_func(Scene_t* scene)
CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T);
CMovementState_t* p_mstate = get_component(p_ent, CMOVEMENTSTATE_T);
sprintf(buffer, "Pos: %.3f\n %.3f", p_ct->position.x, p_ct->position.y);
sprintf(buffer, "Pos: %.3f\n %.3f", p_ent->position.x, p_ent->position.y);
DrawText(buffer, gui_x, gui_y, 12, BLACK);
sprintf(buffer, "Vel: %.3f\n %.3f", p_ct->velocity.x, p_ct->velocity.y);
DrawText(buffer, gui_x + 80, gui_y, 12, BLACK);
@ -290,7 +290,6 @@ static void render_editor_game_scene(Scene_t* scene)
char buffer[64] = {0};
sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
{
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
// Draw the spawn point
@ -303,10 +302,10 @@ static void render_editor_game_scene(Scene_t* scene)
Vector2 box_size = {0};
if (p_bbox != NULL) box_size = p_bbox->size;
if (
p_ct->position.x + box_size.x < min.x * tilemap.tile_size
|| p_ct->position.x > max.x * tilemap.tile_size
|| p_ct->position.y + box_size.y < min.y * tilemap.tile_size
|| p_ct->position.y > max.y * tilemap.tile_size
p_ent->position.x + box_size.x < min.x * tilemap.tile_size
|| p_ent->position.x > max.x * tilemap.tile_size
|| p_ent->position.y + box_size.y < min.y * tilemap.tile_size
|| p_ent->position.y > max.y * tilemap.tile_size
) continue;
Color colour;
@ -336,11 +335,11 @@ static void render_editor_game_scene(Scene_t* scene)
{
if (p_ent->m_tag == BOULDER_ENT_TAG)
{
DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, colour);
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, colour);
}
else
{
DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour);
DrawRectangle(p_ent->position.x, p_ent->position.y, p_bbox->size.x, p_bbox->size.y, colour);
}
if (p_ent->m_tag == CRATES_ENT_TAG)
@ -352,42 +351,42 @@ static void render_editor_game_scene(Scene_t* scene)
{
case CONTAINER_LEFT_ARROW:
DrawLine(
p_ct->position.x,
p_ct->position.y + p_bbox->half_size.y,
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x,
p_ent->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y,
BLACK
);
break;
case CONTAINER_RIGHT_ARROW:
DrawLine(
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ct->position.x + p_bbox->size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->size.x,
p_ent->position.y + p_bbox->half_size.y,
BLACK
);
break;
case CONTAINER_UP_ARROW:
DrawLine(
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y,
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y,
BLACK
);
break;
case CONTAINER_DOWN_ARROW:
DrawLine(
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->size.y,
BLACK
);
break;
case CONTAINER_BOMB:
DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
break;
default:
break;
@ -403,8 +402,8 @@ static void render_editor_game_scene(Scene_t* scene)
for (uint8_t i = 0;i < p_hitbox->n_boxes; ++i)
{
Rectangle rec = {
.x = p_ct->position.x + p_hitbox->boxes[i].x,
.y = p_ct->position.y + p_hitbox->boxes[i].y,
.x = p_ent->position.x + p_hitbox->boxes[i].x,
.y = p_ent->position.y + p_hitbox->boxes[i].y,
.width = p_hitbox->boxes[i].width,
.height = p_hitbox->boxes[i].height,
};
@ -414,8 +413,8 @@ static void render_editor_game_scene(Scene_t* scene)
if (p_hurtbox != NULL)
{
Rectangle rec = {
.x = p_ct->position.x + p_hurtbox->offset.x,
.y = p_ct->position.y + p_hurtbox->offset.y,
.x = p_ent->position.x + p_hurtbox->offset.x,
.y = p_ent->position.y + p_hurtbox->offset.y,
.width = p_hurtbox->size.x,
.height = p_hurtbox->size.y,
};
@ -427,7 +426,7 @@ static void render_editor_game_scene(Scene_t* scene)
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
if (spr.sprite != NULL)
{
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
Vector2 pos = Vector2Add(p_ent->position, spr.offset);
draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x);
}
}
@ -435,8 +434,7 @@ static void render_editor_game_scene(Scene_t* scene)
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_ent)
{
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
DrawCircleV(p_ct->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN);
DrawCircleV(p_ent->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN);
}
draw_particle_system(&scene->part_sys);
@ -518,9 +516,10 @@ static void spawn_chest(Scene_t* scene, unsigned int tile_idx)
Entity_t* p_crate = create_chest(&scene->ent_manager);
if (p_crate == NULL) return;
p_crate->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
p_crate->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
CTransform_t* p_ctransform = get_component(p_crate, CTRANSFORM_COMP_T);
p_ctransform->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
p_ctransform->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
p_ctransform->active = true;
}
@ -529,10 +528,10 @@ static void spawn_crate(Scene_t* scene, unsigned int tile_idx, bool metal, Conta
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
Entity_t* p_crate = create_crate(&scene->ent_manager, metal, item);
if (p_crate == NULL) return;
p_crate->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
p_crate->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
CTransform_t* p_ctransform = get_component(p_crate, CTRANSFORM_COMP_T);
p_ctransform->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
p_ctransform->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
p_ctransform->active = active;
}
@ -542,9 +541,8 @@ static void spawn_boulder(Scene_t* scene, unsigned int tile_idx)
Entity_t* p_boulder = create_boulder(&scene->ent_manager);
if (p_boulder == NULL) return;
CTransform_t* p_ctransform = get_component(p_boulder, CTRANSFORM_COMP_T);
p_ctransform->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
p_ctransform->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
p_boulder->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
p_boulder->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
}
static void toggle_block_system(Scene_t* scene)
@ -642,9 +640,8 @@ static void toggle_block_system(Scene_t* scene)
Entity_t* p_ent = create_water_runner(&scene->ent_manager, DEFAULT_MAP_WIDTH, DEFAULT_MAP_HEIGHT, tile_idx);
if (p_ent != NULL)
{
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
p_ent->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
p_ent->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
}
}
break;
@ -653,9 +650,8 @@ static void toggle_block_system(Scene_t* scene)
Entity_t* p_ent = create_level_end(&scene->ent_manager);
if (p_ent != NULL)
{
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);
p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);;
p_ent->position.x = (tile_idx % tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);
p_ent->position.y = (tile_idx / tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);;
}
}
break;
@ -966,8 +962,7 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
break;
case ACTION_SET_SPAWNPOINT:
{
CTransform_t* p_ct = get_component(p_player, CTRANSFORM_COMP_T);
p_player->spawn_pos = p_ct->position;
p_player->spawn_pos = p_player->position;
}
break;
default:

View File

@ -202,17 +202,16 @@ static void render_regular_game_scene(Scene_t* scene)
sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
{
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
// Entity culling
Vector2 box_size = {0};
if (p_bbox != NULL) box_size = p_bbox->size;
if (
p_ct->position.x + box_size.x < min.x * tilemap.tile_size
|| p_ct->position.x > max.x * tilemap.tile_size
|| p_ct->position.y + box_size.y < min.y * tilemap.tile_size
|| p_ct->position.y > max.y * tilemap.tile_size
p_ent->position.x + box_size.x < min.x * tilemap.tile_size
|| p_ent->position.x > max.x * tilemap.tile_size
|| p_ent->position.y + box_size.y < min.y * tilemap.tile_size
|| p_ent->position.y > max.y * tilemap.tile_size
) continue;
// Render Sprite only
@ -222,7 +221,7 @@ static void render_regular_game_scene(Scene_t* scene)
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
if (spr.sprite != NULL)
{
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
Vector2 pos = Vector2Add(p_ent->position, spr.offset);
draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x);
}
continue;
@ -250,11 +249,11 @@ static void render_regular_game_scene(Scene_t* scene)
{
if (p_ent->m_tag == BOULDER_ENT_TAG)
{
DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, colour);
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, colour);
}
else
{
DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour);
DrawRectangle(p_ent->position.x, p_ent->position.y, p_bbox->size.x, p_bbox->size.y, colour);
}
if (p_ent->m_tag == CRATES_ENT_TAG)
@ -266,42 +265,42 @@ static void render_regular_game_scene(Scene_t* scene)
{
case CONTAINER_LEFT_ARROW:
DrawLine(
p_ct->position.x,
p_ct->position.y + p_bbox->half_size.y,
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x,
p_ent->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y,
BLACK
);
break;
case CONTAINER_RIGHT_ARROW:
DrawLine(
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ct->position.x + p_bbox->size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->size.x,
p_ent->position.y + p_bbox->half_size.y,
BLACK
);
break;
case CONTAINER_UP_ARROW:
DrawLine(
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y,
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y,
BLACK
);
break;
case CONTAINER_DOWN_ARROW:
DrawLine(
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->half_size.y,
p_ct->position.x + p_bbox->half_size.x,
p_ct->position.y + p_bbox->size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->size.y,
BLACK
);
break;
case CONTAINER_BOMB:
DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
break;
default:
break;

View File

@ -86,7 +86,7 @@ static bool check_collision_and_move(
CBBox_t* p_bbox = get_component(ent, CBBOX_COMP_T);
Vector2 overlap = {0,0};
Vector2 prev_overlap = {0,0};
uint8_t overlap_mode = find_AABB_overlap(p_ct->position, p_bbox->size, *other_pos, other_bbox, &overlap);
uint8_t overlap_mode = find_AABB_overlap(ent->position, p_bbox->size, *other_pos, other_bbox, &overlap);
if (overlap_mode == 1)
{
// If there is collision, use previous overlap to determine direction
@ -119,53 +119,53 @@ static bool check_collision_and_move(
// One way collision is a bit special
if (
p_ct->prev_position.y + p_bbox->size.y - 1 < other_pos->y
&& p_ct->position.y + p_bbox->size.y - 1 >= other_pos->y
&& ent->position.y + p_bbox->size.y - 1 >= other_pos->y
)
{
offset.y = other_pos->y - (p_ct->position.y + p_bbox->size.y);
offset.y = other_pos->y - (ent->position.y + p_bbox->size.y);
}
}
p_ct->position = Vector2Add(p_ct->position, offset);
ent->position = Vector2Add(ent->position, offset);
}
else if (overlap_mode == 2)
{
if ( other_solid != SOLID ) goto collision_end;
// On complete overlap, find a free space in this order: top, left, right, bottom
Vector2 point_to_test = {0};
point_to_test.x = p_ct->position.x;
point_to_test.x = ent->position.x;
point_to_test.y = other_pos->y - p_bbox->size.y + 1;
if (!check_collision_offset(ent, point_to_test, p_bbox->size, tilemap, (Vector2){0}))
{
p_ct->position = point_to_test;
ent->position = point_to_test;
goto collision_end;
}
point_to_test.x = other_pos->x - p_bbox->size.x + 1;
point_to_test.y = p_ct->position.y;
point_to_test.y = ent->position.y;
if (!check_collision_offset(ent, point_to_test, p_bbox->size, tilemap, (Vector2){0}))
{
p_ct->position = point_to_test;
ent->position = point_to_test;
goto collision_end;
}
point_to_test.x = other_pos->x + other_bbox.x - 1;
point_to_test.y = p_ct->position.y;
point_to_test.y = ent->position.y;
if (!check_collision_offset(ent, point_to_test, p_bbox->size, tilemap, (Vector2){0}))
{
p_ct->position = point_to_test;
ent->position = point_to_test;
goto collision_end;
}
point_to_test.x = p_ct->position.x;
point_to_test.x = ent->position.x;
point_to_test.y = other_pos->y + other_bbox.y - 1;
if (!check_collision_offset(ent, point_to_test, p_bbox->size, tilemap, (Vector2){0}))
{
p_ct->position = point_to_test;
ent->position = point_to_test;
goto collision_end;
}
// If no free space, Move up no matter what
p_ct->position.x = p_ct->position.x;
p_ct->position.y = other_pos->y - p_bbox->size.y + 1;
//p_ct->position.x = p_ct->position.x;
ent->position.y = other_pos->y - p_bbox->size.y + 1;
}
collision_end:
return overlap_mode > 0;
@ -242,12 +242,10 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
{
if (p_ent->m_tag == BOULDER_ENT_TAG)
{
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
//const CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_rock"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ctransform->position,
.position = p_ent->position,
.n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update,
@ -258,12 +256,10 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
else if (p_ent->m_tag == CRATES_ENT_TAG)
{
const CContainer_t* p_container = get_component(p_ent, CCONTAINER_T);
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
//const CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, (p_container->material == WOODEN_CONTAINER) ? "p_wood" : "p_metal"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ctransform->position,
.position = p_ent->position,
.n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update,
@ -273,11 +269,10 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
}
else if (p_ent->m_tag == CHEST_ENT_TAG)
{
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_wood"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ctransform->position,
.position = p_ent->position,
.n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update,
@ -288,7 +283,7 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
ParticleEmitter_t emitter2 = {
.spr = get_sprite(&scene->engine->assets, "p_coin"),
.config = get_emitter_conf(&scene->engine->assets, "pe_single"),
.position = p_ctransform->position,
.position = p_ent->position,
.n_particles = 1,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update,
@ -300,11 +295,10 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
}
else if (p_ent->m_tag == ARROW_ENT_TAG)
{
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_arrow"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ctransform->position,
.position = p_ent->position,
.n_particles = 2,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update,
@ -330,11 +324,10 @@ void player_respawn_system(Scene_t* scene)
Entity_t* ent = create_dead_player(&scene->ent_manager);
if (ent != NULL)
{
CTransform_t* new_ct = get_component(ent, CTRANSFORM_COMP_T);
memcpy(&new_ct->position, &p_ct->position, sizeof(p_ct->position));
ent->position = p_player->position;
}
p_player->m_alive = true;
p_ct->position = p_player->spawn_pos;
p_player->position = p_player->spawn_pos;
memset(&p_ct->velocity, 0, sizeof(p_ct->velocity));
memset(&p_ct->accel, 0, sizeof(p_ct->accel));
}
@ -374,14 +367,14 @@ void player_movement_input_system(Scene_t* scene)
if (p_pstate->player_dir.y < 0)
{
unsigned int tile_idx = get_tile_idx(
p_ctransform->position.x + p_bbox->half_size.x,
p_ctransform->position.y + p_bbox->half_size.y,
p_player->position.x + p_bbox->half_size.x,
p_player->position.y + p_bbox->half_size.y,
data->tilemap.width
);
if (tilemap.tiles[tile_idx].tile_type == LADDER && p_ctransform->velocity.y >= 0)
{
p_pstate->ladder_state = true;
p_ctransform->position.y--;
p_player->position.y--;
}
}
else if (p_pstate->player_dir.y > 0)
@ -391,31 +384,31 @@ void player_movement_input_system(Scene_t* scene)
if (p_mstate->ground_state & 1)
{
tile_idx = get_tile_idx(
p_ctransform->position.x + p_bbox->half_size.x,
p_ctransform->position.y + p_bbox->size.y,
p_player->position.x + p_bbox->half_size.x,
p_player->position.y + p_bbox->size.y,
data->tilemap.width
);
}
else
{
tile_idx = get_tile_idx(
p_ctransform->position.x + p_bbox->half_size.x,
p_ctransform->position.y + p_bbox->half_size.y,
p_player->position.x + p_bbox->half_size.x,
p_player->position.y + p_bbox->half_size.y,
data->tilemap.width
);
}
if (tile_idx < tilemap.n_tiles && tilemap.tiles[tile_idx].tile_type == LADDER)
{
p_pstate->ladder_state = true;
p_ctransform->position.y++;
p_player->position.y++;
}
}
}
else
{
unsigned int tile_x = (p_ctransform->position.x + p_bbox->half_size.x) / TILE_SIZE;
unsigned int tile_y1 = (p_ctransform->position.y + p_bbox->half_size.y) / TILE_SIZE;
unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE;
unsigned int tile_x = (p_player->position.x + p_bbox->half_size.x) / TILE_SIZE;
unsigned int tile_y1 = (p_player->position.y + p_bbox->half_size.y) / TILE_SIZE;
unsigned int tile_y2 = (p_player->position.y + p_bbox->size.y) / TILE_SIZE;
p_pstate->ladder_state = false;
if (!(p_mstate->ground_state & 1))
@ -432,7 +425,7 @@ void player_movement_input_system(Scene_t* scene)
p_ctransform->velocity.x = p_pstate->player_dir.x * 40;
if (p_pstate->player_dir.y != 0)
{
p_ctransform->position.x = tile_x * TILE_SIZE + 1;
p_player->position.x = tile_x * TILE_SIZE + 1;
}
}
}
@ -473,7 +466,7 @@ void player_movement_input_system(Scene_t* scene)
}
uint8_t collide_type = check_collision_offset(
p_player, p_ctransform->position, p_bbox->size,
p_player, p_player->position, p_bbox->size,
&tilemap, (Vector2){0, p_bbox->size.y - PLAYER_HEIGHT}
);
if (collide_type == 1)
@ -531,7 +524,6 @@ void player_bbox_update_system(Scene_t* scene)
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);
CPlayerState_t* p_pstate = get_component(p_player, CPLAYERSTATE_T);
CMovementState_t* p_mstate = get_component(p_player, CMOVEMENTSTATE_T);
@ -571,13 +563,13 @@ void player_bbox_update_system(Scene_t* scene)
if (
check_collision_offset(
p_player, p_ctransform->position, new_bbox,
p_player, p_player->position, new_bbox,
&tilemap, offset
) != 1
)
{
set_bbox(p_bbox, new_bbox.x, new_bbox.y);
p_ctransform->position = Vector2Add(p_ctransform->position, offset);
p_player->position = Vector2Add(p_player->position, offset);
}
CHitBoxes_t* p_hitbox = get_component(p_player, CHITBOXES_T);
@ -595,12 +587,11 @@ void player_crushing_system(Scene_t* scene)
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);
uint8_t edges = check_bbox_edges(
&data->tilemap, p_player,
p_ctransform->position, p_bbox->size, true
p_player->position, p_bbox->size, true
);
// There is a second check for to ensure that there is an solid entity/tile overlapping the player bbox
@ -612,13 +603,13 @@ void player_crushing_system(Scene_t* scene)
CollideEntity_t ent =
{
.p_ent = p_player,
.bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, p_bbox->size.x, 1},
.prev_bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, p_bbox->size.x, p_bbox->size.y},
.bbox = (Rectangle){p_player->position.x, p_player->position.y, p_bbox->size.x, 1},
.prev_bbox = (Rectangle){p_player->position.x, p_player->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,
.tile_x1 = (p_player->position.x) / TILE_SIZE,
.tile_y1 = (p_player->position.y) / TILE_SIZE,
.tile_x2 = (p_player->position.x + p_bbox->size.x - 1) / TILE_SIZE,
.tile_y2 = (p_player->position.y + p_bbox->size.y - 1) / TILE_SIZE,
}
};
@ -629,7 +620,7 @@ void player_crushing_system(Scene_t* scene)
collide |= 1 << 1;
}
ent.bbox.y = p_ctransform->position.y + p_bbox->size.y;
ent.bbox.y = p_player->position.y + p_bbox->size.y;
collide_type = check_collision_line(&ent, &data->tilemap, true);
if (collide_type == 1)
{
@ -649,13 +640,13 @@ void player_crushing_system(Scene_t* scene)
CollideEntity_t ent =
{
.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},
.bbox = (Rectangle){p_player->position.x, p_player->position.y, 1, p_bbox->size.y},
.prev_bbox = (Rectangle){p_player->position.x, p_player->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,
.tile_x1 = (p_player->position.x) / TILE_SIZE,
.tile_y1 = (p_player->position.y) / TILE_SIZE,
.tile_x2 = (p_player->position.x + p_bbox->size.x - 1) / TILE_SIZE,
.tile_y2 = (p_player->position.y + p_bbox->size.y - 1) / TILE_SIZE,
}
};
@ -667,7 +658,7 @@ void player_crushing_system(Scene_t* scene)
}
//Right
ent.bbox.x = p_ctransform->position.x + p_bbox->size.x; // 2 to account for the previous subtraction
ent.bbox.x = p_player->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)
{
@ -693,11 +684,10 @@ void spike_collision_system(Scene_t* scene)
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;
unsigned int tile_x1 = (p_ent->position.x) / TILE_SIZE;
unsigned int tile_y1 = (p_ent->position.y) / TILE_SIZE;
unsigned int tile_x2 = (p_ent->position.x + p_bbox->size.x - 1) / TILE_SIZE;
unsigned int tile_y2 = (p_ent->position.y + p_bbox->size.y - 1) / TILE_SIZE;
tile_x1 = (tile_x1 < 0) ? 0 : tile_x1;
tile_x2 = (tile_x2 >= tilemap.width) ? tilemap.width - 1 : tile_x2;
@ -712,7 +702,7 @@ void spike_collision_system(Scene_t* scene)
if(tilemap.tiles[tile_idx].tile_type == SPIKES)
{
uint8_t collide = find_AABB_overlap(
p_ctransform->position, p_bbox->size,
p_ent->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
@ -759,10 +749,10 @@ void tile_collision_system(Scene_t* scene)
// exclude self
// 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
unsigned int tile_x1 = (p_ctransform->position.x - 1) / TILE_SIZE;
unsigned int tile_y1 = (p_ctransform->position.y - 1) / 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_x1 = (p_ent->position.x - 1) / TILE_SIZE;
unsigned int tile_y1 = (p_ent->position.y - 1) / TILE_SIZE;
unsigned int tile_x2 = (p_ent->position.x + p_bbox->size.x) / TILE_SIZE;
unsigned int tile_y2 = (p_ent->position.y + p_bbox->size.y) / TILE_SIZE;
tile_x1 = (tile_x1 < 0) ? 0 : tile_x1;
tile_x2 = (tile_x2 >= tilemap.width) ? tilemap.width - 1 : tile_x2;
@ -808,8 +798,6 @@ void tile_collision_system(Scene_t* scene)
CBBox_t *p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
if (p_other_bbox == NULL) continue;
CTransform_t *p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T);
SolidType_t solid = p_other_bbox->solid? SOLID : NOT_SOLID;
if (p_ent->m_tag == PLAYER_ENT_TAG && p_other_ent->m_tag == CHEST_ENT_TAG)
{
@ -817,7 +805,7 @@ void tile_collision_system(Scene_t* scene)
}
check_collision_and_move(
&tilemap, p_ent,
&p_other_ct->position, p_other_bbox->size,
&p_other_ent->position, p_other_bbox->size,
solid
);
}
@ -841,7 +829,7 @@ void edge_velocity_check_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_bbox->size, false
p_ent->position, p_bbox->size, false
);
if (edges & (1<<3))
{
@ -862,26 +850,26 @@ void edge_velocity_check_system(Scene_t* scene)
// Deal with float precision, by rounding when it is near to an integer enough by 2 dp
float decimal;
float fractional = modff(p_ctransform->position.x, &decimal);
float fractional = modff(p_ent->position.x, &decimal);
if (fractional > 0.99)
{
p_ctransform->position.x = decimal;
(p_ctransform->position.x > 0) ? p_ctransform->position.x++ : p_ctransform->position.x--;
p_ent->position.x = decimal;
(p_ent->position.x > 0) ? p_ent->position.x++ : p_ent->position.x--;
}
else if (fractional < 0.01)
{
p_ctransform->position.x = decimal;
p_ent->position.x = decimal;
}
fractional = modff(p_ctransform->position.y, &decimal);
fractional = modff(p_ent->position.y, &decimal);
if (fractional > 0.99)
{
p_ctransform->position.y = decimal;
(p_ctransform->position.y > 0) ? p_ctransform->position.y++ : p_ctransform->position.y--;
p_ent->position.y = decimal;
(p_ent->position.y > 0) ? p_ent->position.y++ : p_ent->position.y--;
}
else if (fractional < 0.01)
{
p_ctransform->position.y = decimal;
p_ent->position.y = decimal;
}
}
}
@ -975,7 +963,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_bbox->size, false
p_ent->position, p_bbox->size, false
);
if (edges & (1<<3))
{
@ -1019,11 +1007,11 @@ void moveable_update_system(Scene_t* scene)
if (p_moveable->gridmove)
{
float remaining_distance = p_moveable->target_pos.x - p_ctransform->position.x;
float remaining_distance = p_moveable->target_pos.x - p_ent->position.x;
if (fabs(remaining_distance) < 0.1)
{
p_ctransform->prev_position = p_moveable->prev_pos;
p_ctransform->position = p_moveable->target_pos;
p_ent->position = p_moveable->target_pos;
p_moveable->gridmove = false;
p_bbox->solid = true;
p_ctransform->movement_mode = REGULAR_MOVEMENT;
@ -1031,11 +1019,11 @@ void moveable_update_system(Scene_t* scene)
}
else if (remaining_distance > 0.1)
{
p_ctransform->position.x += (remaining_distance > p_moveable->move_speed) ? p_moveable->move_speed : remaining_distance;
p_ent->position.x += (remaining_distance > p_moveable->move_speed) ? p_moveable->move_speed : remaining_distance;
}
else
{
p_ctransform->position.x += (remaining_distance < -p_moveable->move_speed) ? -p_moveable->move_speed : remaining_distance;
p_ent->position.x += (remaining_distance < -p_moveable->move_speed) ? -p_moveable->move_speed : remaining_distance;
memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity));
}
}
@ -1049,8 +1037,8 @@ void moveable_update_system(Scene_t* scene)
// Point to check is the one row below
Vector2 point_to_check = {
.x = p_ctransform->position.x + p_bbox->half_size.x,
.y = p_ctransform->position.y + p_bbox->size.y + 1
.x = p_ent->position.x + p_bbox->half_size.x,
.y = p_ent->position.y + p_bbox->size.y + 1
};
unsigned int tile_x = point_to_check.x / TILE_SIZE;
unsigned int tile_y = point_to_check.y / TILE_SIZE;
@ -1069,11 +1057,11 @@ void moveable_update_system(Scene_t* scene)
Entity_t* other_ent = get_entity(&scene->ent_manager, other_ent_idx);
CBBox_t* p_other_bbox = get_component(other_ent, CBBOX_COMP_T);
CTransform_t* p_other_ct = get_component(other_ent, CTRANSFORM_COMP_T);
Rectangle box = {p_other_ct->position.x, p_other_ct->position.y, p_other_bbox->size.x, p_other_bbox->size.y};
Rectangle box = {other_ent->position.x, other_ent->position.y, p_other_bbox->size.x, p_other_bbox->size.y};
if (!point_in_AABB(point_to_check, box) || Vector2LengthSqr(p_other_ct->velocity) != 0) continue;
}
tile_x = (p_ctransform->position.x) / TILE_SIZE - 1;
tile_x = (p_ent->position.x) / TILE_SIZE - 1;
if (tile_x >= 0 && tile_x < tilemap.width)
{
@ -1159,7 +1147,7 @@ void moveable_update_system(Scene_t* scene)
{
p_moveable->gridmove = true;
p_bbox->solid = false;
p_moveable->prev_pos = p_ctransform->position;
p_moveable->prev_pos = p_ent->position;
p_moveable->target_pos = Vector2Scale((Vector2){tile_x,tile_y-1}, TILE_SIZE);
memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity));
memset(&p_ctransform->accel, 0, sizeof(p_ctransform->accel));
@ -1189,7 +1177,7 @@ void player_pushing_system(Scene_t* scene)
CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T);
Vector2 point_to_check = p_ctransform->position;
Vector2 point_to_check = p_player->position;
point_to_check.y += p_bbox->half_size.y;
if (p_pstate->player_dir.x > 0)
{
@ -1221,15 +1209,15 @@ void player_pushing_system(Scene_t* scene)
CTransform_t *p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T);
CBBox_t *p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
Rectangle box = {
.x = p_other_ct->position.x,
.y = p_other_ct->position.y,
.x = p_other_ent->position.x,
.y = p_other_ent->position.y,
.width = p_other_bbox->size.x,
.height = p_other_bbox->size.y
};
if (point_in_AABB(point_to_check, box))
{
Vector2 target_pos = p_other_ct->position;
if (p_ctransform->position.x < p_other_ct->position.x)
Vector2 target_pos = p_other_ent->position;
if (p_player->position.x < p_other_ent->position.x)
{
target_pos.x += TILE_SIZE;
tile_x++;
@ -1249,7 +1237,7 @@ void player_pushing_system(Scene_t* scene)
)
{
p_other_moveable->gridmove = true;
p_other_moveable->prev_pos = p_other_ct->position;
p_other_moveable->prev_pos = p_other_ent->position;
p_other_moveable->target_pos = target_pos;
memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity));
memset(&p_ctransform->accel, 0, sizeof(p_ctransform->accel));
@ -1298,46 +1286,46 @@ void movement_update_system(Scene_t* scene)
if (fabs(p_ctransform->velocity.x) < 1e-3) p_ctransform->velocity.x = 0;
if (fabs(p_ctransform->velocity.y) < 1e-3) p_ctransform->velocity.y = 0;
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
// Store previous position before update
p_ctransform->prev_position = p_ctransform->position;
p_ctransform->position = Vector2Add(
p_ctransform->position,
p_ctransform->prev_position = p_ent->position;
p_ent->position = Vector2Add(
p_ent->position,
Vector2Scale(p_ctransform->velocity, delta_time)
);
memset(&p_ctransform->accel, 0, sizeof(p_ctransform->accel));
// Level boundary collision
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
unsigned int level_width = tilemap.width * TILE_SIZE;
unsigned int level_height = tilemap.height * TILE_SIZE;
if (p_bbox != NULL)
{
if(p_ctransform->position.x < 0 || p_ctransform->position.x + p_bbox->size.x > level_width)
if(p_ent->position.x < 0 || p_ent->position.x + p_bbox->size.x > level_width)
{
p_ctransform->position.x = (p_ctransform->position.x < 0) ? 0 : p_ctransform->position.x;
if (p_ctransform->position.x + p_bbox->size.x > level_width)
p_ent->position.x = (p_ent->position.x < 0) ? 0 : p_ent->position.x;
if (p_ent->position.x + p_bbox->size.x > level_width)
{
p_ctransform->position.x = level_width - p_bbox->size.x;
p_ent->position.x = level_width - p_bbox->size.x;
}
else
{
p_ctransform->position.x = p_ctransform->position.x;
p_ent->position.x = p_ent->position.x;
}
p_ctransform->velocity.x = 0;
}
if(p_ctransform->position.y < 0 || p_ctransform->position.y + p_bbox->size.y > level_height)
if(p_ent->position.y < 0 || p_ent->position.y + p_bbox->size.y > level_height)
{
p_ctransform->position.y = (p_ctransform->position.y < 0) ? 0 : p_ctransform->position.y;
if (p_ctransform->position.y + p_bbox->size.y > level_height)
p_ent->position.y = (p_ent->position.y < 0) ? 0 : p_ent->position.y;
if (p_ent->position.y + p_bbox->size.y > level_height)
{
p_ctransform->position.y = level_height - p_bbox->size.y;
p_ent->position.y = level_height - p_bbox->size.y;
}
else
{
p_ctransform->position.y = p_ctransform->position.y;
p_ent->position.y = p_ent->position.y;
}
p_ctransform->velocity.y = 0;
}
@ -1345,8 +1333,8 @@ void movement_update_system(Scene_t* scene)
else
{
if (
p_ctransform->position.x < 0 || p_ctransform->position.x > level_width
|| p_ctransform->position.y < 0 || p_ctransform->position.y > level_height
p_ent->position.x < 0 || p_ent->position.x > level_width
|| p_ent->position.y < 0 || p_ent->position.y > level_height
)
{
destroy_entity(scene, &tilemap, p_ent);
@ -1418,7 +1406,7 @@ void state_transition_update_system(Scene_t* scene)
else if (p_ctransform->velocity.x < 0) p_mstate->x_dir = 0;
bool on_ground = check_on_ground(
p_ent, p_ctransform->position, p_ctransform->prev_position, p_bbox->size,
p_ent, p_ent->position, p_ctransform->prev_position, p_bbox->size,
&data->tilemap
);
@ -1428,10 +1416,10 @@ void state_transition_update_system(Scene_t* scene)
}
// Upthrust depends on water overlapping
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) / TILE_SIZE;
unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE;
unsigned int tile_x1 = (p_ent->position.x) / TILE_SIZE;
unsigned int tile_y1 = (p_ent->position.y) / TILE_SIZE;
unsigned int tile_x2 = (p_ent->position.x + p_bbox->size.x) / TILE_SIZE;
unsigned int tile_y2 = (p_ent->position.y + p_bbox->size.y) / TILE_SIZE;
float water_area = 0;
for (unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
{
@ -1452,7 +1440,7 @@ void state_transition_update_system(Scene_t* scene)
Vector2 overlap;
if (find_AABB_overlap(
p_ctransform->position, p_bbox->size,
p_ent->position, p_bbox->size,
water_tl, water_sz, &overlap
))
{
@ -1493,7 +1481,7 @@ void state_transition_update_system(Scene_t* scene)
ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_water"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ctransform->position,
.position = p_ent->position,
.n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update,
@ -1513,10 +1501,7 @@ void update_entity_emitter_system(Scene_t* scene)
sc_map_foreach(&scene->ent_manager.component_map[CEMITTER_T], ent_idx, p_emitter)
{
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
//CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
Vector2 new_pos = Vector2Add(p_ctransform->position,p_emitter->offset);
//new_pos.y += p_bbox->half_size.y;
Vector2 new_pos = Vector2Add(p_ent->position,p_emitter->offset);
if (is_emitter_handle_alive(&scene->part_sys, p_emitter->handle))
{
update_emitter_handle_position(&scene->part_sys, p_emitter->handle, new_pos);
@ -1551,14 +1536,14 @@ void update_tilemap_system(Scene_t* scene)
// Compute new occupied tile positions and add
// Extend the check by a little to avoid missing
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) / TILE_SIZE;
unsigned int tile_y2 = (p_ctransform->position.y) / TILE_SIZE;
unsigned int tile_x1 = (p_ent->position.x) / TILE_SIZE;
unsigned int tile_y1 = (p_ent->position.y) / TILE_SIZE;
unsigned int tile_x2 = (p_ent->position.x) / TILE_SIZE;
unsigned int tile_y2 = (p_ent->position.y) / TILE_SIZE;
if (p_bbox != NULL)
{
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;
tile_x2 = (p_ent->position.x + p_bbox->size.x - 1) / TILE_SIZE;
tile_y2 = (p_ent->position.y + p_bbox->size.y - 1) / TILE_SIZE;
}
tile_x2 = (tile_x2 >= tilemap.width) ? tilemap.width - 1 : tile_x2;
tile_y2 = (tile_y2 >= tilemap.height) ? tilemap.width - 1 : tile_y2;
@ -1595,8 +1580,8 @@ void hitbox_update_system(Scene_t* scene)
for (uint8_t i = 0; i < p_hitbox->n_boxes; ++i)
{
Vector2 hitbox_pos = {
.x = p_ctransform->position.x + p_hitbox->boxes[i].x,
.y = p_ctransform->position.y + p_hitbox->boxes[i].y,
.x = p_ent->position.x + p_hitbox->boxes[i].x,
.y = p_ent->position.y + p_hitbox->boxes[i].y,
};
unsigned int tile_x1 = (hitbox_pos.x) / TILE_SIZE;
@ -1646,9 +1631,8 @@ void hitbox_update_system(Scene_t* scene)
CHurtbox_t* p_other_hurtbox = get_component(p_other_ent, CHURTBOX_T);
if (p_other_hurtbox == NULL) continue;
CTransform_t* p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T);
CBBox_t* p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
Vector2 hurtbox_pos = Vector2Add(p_other_ct->position, p_other_hurtbox->offset);
Vector2 hurtbox_pos = Vector2Add(p_other_ent->position, p_other_hurtbox->offset);
if (
find_AABB_overlap(
@ -1674,7 +1658,7 @@ void hitbox_update_system(Scene_t* scene)
CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T);
if (p_pstate != NULL)
{
if (p_ctransform->position.y + p_bbox->size.y <= p_other_ct->position.y)
if (p_ent->position.y + p_bbox->size.y <= p_other_ent->position.y)
{
p_ctransform->velocity.y = -400;
if (p_pstate->jump_pressed)
@ -1686,10 +1670,10 @@ void hitbox_update_system(Scene_t* scene)
}
if (p_ent->m_tag == PLAYER_ENT_TAG)
{
data->camera.base_y = p_ctransform->position.y;
data->camera.base_y = p_ent->position.y;
}
}
else if (p_ctransform->position.y >= p_other_ct->position.y + p_other_bbox->size.y)
else if (p_ent->position.y >= p_other_ent->position.y + p_other_bbox->size.y)
{
p_ctransform->velocity.y = 0;
}
@ -1760,17 +1744,17 @@ void boulder_destroy_wooden_tile_system(Scene_t* scene)
Entity_t* p_boulder;
sc_map_foreach_value(&scene->ent_manager.entities_map[BOULDER_ENT_TAG], p_boulder)
{
const CTransform_t* p_ctransform = get_component(p_boulder, CTRANSFORM_COMP_T);
//const CTransform_t* p_ctransform = get_component(p_boulder, CTRANSFORM_COMP_T);
const CBBox_t* p_bbox = get_component(p_boulder, CBBOX_COMP_T);
//if (p_ctransform->velocity.y <= 0) continue;
unsigned int tile_idx = get_tile_idx(
p_ctransform->position.x + p_bbox->half_size.x,
p_ctransform->position.y + p_bbox->size.y + 1,
p_boulder->position.x + p_bbox->half_size.x,
p_boulder->position.y + p_bbox->size.y + 1,
tilemap.width
);
unsigned int tile_x = (p_ctransform->position.x + p_bbox->half_size.x) / tilemap.tile_size;
unsigned int tile_x = (p_boulder->position.x + p_bbox->half_size.x) / tilemap.tile_size;
if (tilemap.tiles[tile_idx].tile_type == ONEWAY_TILE)
{
@ -1827,16 +1811,14 @@ void container_destroy_system(Scene_t* scene)
case CONTAINER_BOMB:
if (dmg_src != NULL && dmg_src->m_tag == PLAYER_ENT_TAG)
{
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
const CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
const CTransform_t* dmg_src_ctransform = get_component(dmg_src, CTRANSFORM_COMP_T);
const CBBox_t* dmg_src_bbox = get_component(dmg_src, CBBOX_COMP_T);
Vector2 launch_dir = {0, -1};
if (dmg_src_ctransform->position.x + dmg_src_bbox->size.x <= p_ctransform->position.x)
if (dmg_src->position.x + dmg_src_bbox->size.x <= p_ent->position.x)
{
launch_dir.x = 1;
}
else if (dmg_src_ctransform->position.x >= p_ctransform->position.x + p_bbox->size.x)
else if (dmg_src->position.x >= p_ent->position.x + p_bbox->size.x)
{
launch_dir.x = -1;
}
@ -1874,9 +1856,7 @@ void container_destroy_system(Scene_t* scene)
if (new_ent != NULL)
{
CTransform_t* new_p_ct = get_component(new_ent, CTRANSFORM_COMP_T);
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
new_p_ct->position = Vector2Add(new_p_ct->position, p_ct->position);
new_ent->position = Vector2Add(new_ent->position, p_ent->position);
}
}
}
@ -1908,14 +1888,13 @@ void airtimer_update_system(Scene_t* scene)
{
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
if (!p_ent->m_alive) continue;
CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
CMovementState_t* p_movement = get_component(p_ent, CMOVEMENTSTATE_T);
if (p_ctransform == NULL || p_bbox == NULL || p_movement == NULL) continue;
if (p_bbox == NULL || p_movement == NULL) continue;
Vector2 point_to_check = {
p_ctransform->position.x + p_bbox->half_size.x,
p_ctransform->position.y + p_bbox->half_size.y / 2,
p_ent->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y / 2,
};
unsigned int tile_idx = get_tile_idx(
@ -1953,7 +1932,7 @@ void airtimer_update_system(Scene_t* scene)
.spr = get_sprite(&scene->engine->assets, "p_water"),
.config = get_emitter_conf(&scene->engine->assets, "pe_bubbling"),
//.position = new_pos,
.position = p_ctransform->position,
.position = p_ent->position,
.n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &floating_particle_system_update,
@ -1980,7 +1959,7 @@ void airtimer_update_system(Scene_t* scene)
ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_bigbubble"),
.config = get_emitter_conf(&scene->engine->assets, "pe_slow"),
.position = p_ctransform->position,
.position = p_ent->position,
.n_particles = 1,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &floating_particle_system_update,
@ -2051,7 +2030,7 @@ void camera_update_system(Scene_t* scene)
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);
data->camera.target_pos.x = p_ctransform->position.x;
data->camera.target_pos.x = p_player->position.x;
target_vel = p_ctransform->velocity;
CMovementState_t* p_movement = get_component(p_player, CMOVEMENTSTATE_T);
CPlayerState_t* p_pstate = get_component(p_player, CPLAYERSTATE_T);
@ -2062,11 +2041,11 @@ void camera_update_system(Scene_t* scene)
|| (p_pstate->ladder_state & 1)
)
{
data->camera.base_y = p_ctransform->position.y;
data->camera.base_y = p_player->position.y;
}
if (p_ctransform->position.y >= data->camera.base_y)
if (p_player->position.y >= data->camera.base_y)
{
data->camera.target_pos.y = p_ctransform->position.y;
data->camera.target_pos.y = p_player->position.y;
data->camera.target_pos.y += p_ctransform->velocity.y * 0.2;
}
}
@ -2123,10 +2102,9 @@ void level_end_detection_system(Scene_t* scene)
TileGrid_t tilemap = lvl_scene->data.tilemap;
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_flag)
{
CTransform_t* p_ct = get_component(p_flag, CTRANSFORM_COMP_T);
unsigned int tile_idx = get_tile_idx(
p_ct->position.x,
p_ct->position.y,
p_flag->position.x,
p_flag->position.y,
tilemap.width
);
@ -2136,14 +2114,13 @@ void level_end_detection_system(Scene_t* scene)
{
if (p_other_ent->m_tag != PLAYER_ENT_TAG) continue;
CTransform_t* p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T);
CBBox_t* p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
Vector2 pos = Vector2Subtract(p_ct->position,(Vector2){tilemap.tile_size >> 1, tilemap.tile_size >> 1});
Vector2 pos = Vector2Subtract(p_flag->position,(Vector2){tilemap.tile_size >> 1, tilemap.tile_size >> 1});
if (
find_AABB_overlap(
pos, (Vector2){tilemap.tile_size, tilemap.tile_size},
p_other_ct->position, p_other_bbox->size, NULL
p_other_ent->position, p_other_bbox->size, NULL
)
)
{

View File

@ -159,6 +159,17 @@ Entity_t* create_bomb(EntityManager_t* ent_manager, Vector2 launch_dir)
Entity_t* p_bomb = add_entity(ent_manager, DESTRUCTABLE_ENT_TAG);
if (p_bomb == NULL) return NULL;
p_bomb->position.x += (TILE_SIZE - 25) / 2;
p_bomb->position.y += (TILE_SIZE - 25) / 2;
if (launch_dir.x > 0)
{
p_bomb->position.x += TILE_SIZE/ 2;
}
else if (launch_dir.x < 0)
{
p_bomb->position.x -= TILE_SIZE / 2;
}
add_component(p_bomb, CTILECOORD_COMP_T);
add_component(p_bomb, CMOVEMENTSTATE_T);
CHitBoxes_t* p_hitbox = add_component(p_bomb, CHITBOXES_T);
@ -179,19 +190,9 @@ Entity_t* create_bomb(EntityManager_t* ent_manager, Vector2 launch_dir)
p_ctransform->active = true;
p_ctransform->shape_factor = (Vector2){0.1, 0.1};
p_ctransform->movement_mode = REGULAR_MOVEMENT;
p_ctransform->position.x += (TILE_SIZE - 25) / 2;
p_ctransform->position.y += (TILE_SIZE - 25) / 2;
p_ctransform->velocity = Vector2Scale(Vector2Normalize(launch_dir), 500);
if (launch_dir.x > 0)
{
p_ctransform->position.x += TILE_SIZE/ 2;
}
else if (launch_dir.x < 0)
{
p_ctransform->position.x -= TILE_SIZE / 2;
}
return p_bomb;
}
@ -200,6 +201,8 @@ Entity_t* create_explosion(EntityManager_t* ent_manager)
Entity_t* p_explosion = add_entity(ent_manager, DESTRUCTABLE_ENT_TAG);
if (p_explosion == NULL) return NULL;
p_explosion->position.x -= 16;
p_explosion->position.y -= 16;
add_component(p_explosion, CTILECOORD_COMP_T);
CHitBoxes_t* p_hitbox = add_component(p_explosion, CHITBOXES_T);
p_hitbox->n_boxes = 1;
@ -209,8 +212,6 @@ Entity_t* create_explosion(EntityManager_t* ent_manager)
CTransform_t* p_ctransform = add_component(p_explosion, CTRANSFORM_COMP_T);
p_ctransform->movement_mode = KINEMATIC_MOVEMENT;
p_ctransform->active = true;
p_ctransform->position.x -= 16;
p_ctransform->position.y -= 16;
p_hitbox->boxes[0] = (Rectangle){0, 0, TILE_SIZE + 32, TILE_SIZE + 32};
CSprite_t* p_cspr = add_component(p_explosion, CSPRITE_T);

View File

@ -105,9 +105,8 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
}
Entity_t* ent = create_crate(&scene->scene.ent_manager, tmp_idx > 5, item);
CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
p_ct->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
p_ct->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
}
else
{
@ -129,9 +128,8 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
case 20:
{
Entity_t* ent = create_boulder(&scene->scene.ent_manager);
CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
p_ct->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
p_ct->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
}
break;
case 21:
@ -142,10 +140,9 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
case 22:
{
Entity_t* ent = create_player(&scene->scene.ent_manager);
CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
p_ct->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
p_ct->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
ent->spawn_pos = p_ct->position;
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
ent->spawn_pos = ent->position;
}
break;
default:

View File

@ -223,9 +223,8 @@ void update_water_runner_system(Scene_t* scene)
while (move_left)
{
p_crunner->current_tile = p_crunner->bfs_tilemap.tilemap[p_crunner->current_tile].to;
CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
p_ct->position.x = (p_crunner->current_tile % tilemap.width) * tilemap.tile_size;
p_ct->position.y = (p_crunner->current_tile / tilemap.width) * tilemap.tile_size;
ent->position.x = (p_crunner->current_tile % tilemap.width) * tilemap.tile_size;
ent->position.y = (p_crunner->current_tile / tilemap.width) * tilemap.tile_size;
Tile_t* tile = tilemap.tiles + p_crunner->current_tile;
tile->wet = true;

View File

@ -108,7 +108,7 @@ static void level_scene_render_func(Scene_t* scene)
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
if (spr.sprite != NULL)
{
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
Vector2 pos = Vector2Add(p_ent->position, spr.offset);
draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x);
}
}
@ -318,8 +318,8 @@ static void toggle_block_system(Scene_t* scene)
if (p_ent == NULL) return;
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
p_ent->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
p_ent->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
}
else
{