mirror of
https://github.com/Ed94/HandmadeHero.git
synced 2024-12-21 22:14:43 -08:00
Day 49 complete
This commit is contained in:
parent
2c3b6d9e66
commit
393f98a03d
@ -35,7 +35,7 @@ The final build order should have an additional game module: `handmade`, that wi
|
||||
|
||||
## Milestone
|
||||
|
||||
Day 48 : Line Segment Intersection Collisions
|
||||
Day 49 : Debugging Canonical Coordinatescl
|
||||
|
||||
Features Done so far:
|
||||
|
||||
|
@ -441,10 +441,7 @@ void player_init( hh::Player* player, hh::GameState* gs )
|
||||
|
||||
entity->kind = hh::EntityKind_Hero;
|
||||
|
||||
entity->position.tile_x = 4;
|
||||
entity->position.tile_y = 4;
|
||||
entity->position.rel_pos.x = 0.f;
|
||||
entity->position.rel_pos.y = 0.f;
|
||||
entity->position = gs->spawn_pos;
|
||||
|
||||
entity->velocity = {};
|
||||
|
||||
@ -569,7 +566,9 @@ void update_player( hh::Player* player, f32 delta_time, World* world, hh::GameSt
|
||||
f32 player_half_width = entity->width / 2.f;
|
||||
f32 player_quarter_height = entity->height / 4.f;
|
||||
|
||||
f32 move_accel = 36.f;
|
||||
// f32 move_accel = 36.f;
|
||||
f32 move_accel = 200.f;
|
||||
|
||||
if ( actions->sprint )
|
||||
{
|
||||
move_accel = 94.f;
|
||||
@ -702,21 +701,21 @@ void update_player( hh::Player* player, f32 delta_time, World* world, hh::GameSt
|
||||
}
|
||||
else
|
||||
{
|
||||
TileMapPos new_pos = {
|
||||
TileMapPos new_pos = recannonicalize_position( tile_map, {
|
||||
new_player_pos.x, new_player_pos.y,
|
||||
old_pos.tile_x, old_pos.tile_y, old_pos.tile_z
|
||||
};
|
||||
new_pos = recannonicalize_position( tile_map, new_pos );
|
||||
});
|
||||
TileMapPos best_position = old_pos;
|
||||
f32 min_intersection_delta = 1.0f;
|
||||
|
||||
if (0)
|
||||
{
|
||||
s32 min_tile_x = min( old_pos.tile_x, new_pos.tile_x );
|
||||
s32 min_tile_y = min( old_pos.tile_y, new_pos.tile_y );
|
||||
|
||||
s32 max_tile_x = max( old_pos.tile_x, new_pos.tile_x );
|
||||
s32 max_tile_y = max( old_pos.tile_y, new_pos.tile_y );
|
||||
|
||||
TileMapPos best_position = old_pos;
|
||||
|
||||
f32 min_intersection_delta = 1.0f;
|
||||
for ( s32 tile_y = min_tile_y; tile_y <= max_tile_y; ++ tile_y )
|
||||
for ( s32 tile_x = min_tile_x; tile_x <= max_tile_x; ++ tile_x )
|
||||
{
|
||||
@ -739,15 +738,54 @@ void update_player( hh::Player* player, f32 delta_time, World* world, hh::GameSt
|
||||
test_wall( max_corner.y, rel_old_pos_inv, min_corner.x, max_corner.x, vel_inv, & min_intersection_delta );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 tile_delta_x = sign( new_pos.tile_x - old_pos.tile_x );
|
||||
s32 tile_delta_y = sign( new_pos.tile_y - old_pos.tile_y );
|
||||
|
||||
for ( s32 tile_y = old_pos.tile_y; ; tile_y += tile_delta_y )
|
||||
{
|
||||
for ( s32 tile_x = old_pos.tile_x; ; tile_x += tile_delta_x )
|
||||
{
|
||||
TileMapPos test_tile_pos = centered_tile_point( tile_x, tile_y, old_pos.tile_z );
|
||||
s32 tile_value = TileMap_get_tile_value( tile_map, test_tile_pos );
|
||||
|
||||
local_persist TileChunkPosition last_chunk = {};
|
||||
TileChunkPosition curr_chunk = get_tile_chunk_position_for(tile_map, old_pos.tile_x, old_pos.tile_y, old_pos.tile_z );
|
||||
|
||||
if ( ! TileMap_is_tile_value_empty( tile_value ) )
|
||||
{
|
||||
Vec2 tile_xy_in_meters = Vec2 { tile_map->tile_side_in_meters, tile_map->tile_side_in_meters };
|
||||
|
||||
Vec2 min_corner = -0.5f * tile_xy_in_meters;
|
||||
Vec2 max_corner = 0.5f * tile_xy_in_meters;
|
||||
|
||||
Vec2 rel_old_pos = subtract( old_pos, test_tile_pos ).rel_pos;
|
||||
Vec2 rel_old_pos_inv = { rel_old_pos.y, rel_old_pos.x };
|
||||
Vec2 vel_inv = { entity->velocity.y, entity->velocity.x };
|
||||
|
||||
test_wall( min_corner.x, rel_old_pos, min_corner.y, max_corner.y, entity->velocity, & min_intersection_delta );
|
||||
test_wall( max_corner.x, rel_old_pos, min_corner.y, max_corner.y, entity->velocity, & min_intersection_delta );
|
||||
test_wall( min_corner.y, rel_old_pos_inv, min_corner.x, max_corner.x, vel_inv, & min_intersection_delta );
|
||||
test_wall( max_corner.y, rel_old_pos_inv, min_corner.x, max_corner.x, vel_inv, & min_intersection_delta );
|
||||
}
|
||||
|
||||
if ( tile_x == new_pos.tile_x )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( tile_y == new_pos.tile_y )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
new_player_pos = { old_pos.rel_pos.x, old_pos.rel_pos.y };
|
||||
new_player_pos += entity->velocity * min_intersection_delta;
|
||||
|
||||
new_pos = {
|
||||
new_pos = recannonicalize_position( tile_map, {
|
||||
new_player_pos.x, new_player_pos.y,
|
||||
old_pos.tile_x, old_pos.tile_y, old_pos.tile_z
|
||||
};
|
||||
new_pos = recannonicalize_position( tile_map, new_pos );
|
||||
});
|
||||
entity->position = new_pos;
|
||||
}
|
||||
|
||||
@ -923,6 +961,9 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
|
||||
state->game_memory.transient_size = memory->transient_size / Memory::game_memory_factor;
|
||||
state->game_memory.transient = rcast(Byte*, memory->transient) + state->game_memory.transient_size;
|
||||
|
||||
hh::GameState* gs = rcast( hh::GameState*, state->game_memory.persistent );
|
||||
assert( sizeof(hh::GameState) <= state->game_memory.persistent_size );
|
||||
|
||||
World* world;
|
||||
|
||||
// World setup
|
||||
@ -965,8 +1006,8 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
|
||||
world->tiles_per_screen_x = 17;
|
||||
world->tiles_per_screen_y = 9;
|
||||
|
||||
u32 screen_x = 0;
|
||||
u32 screen_y = 0;
|
||||
s32 screen_x = -10;
|
||||
s32 screen_y = -10;
|
||||
u32 rng_index = 0;
|
||||
|
||||
b32 door_left = false;
|
||||
@ -978,7 +1019,7 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
|
||||
|
||||
u32 abs_tile_z = 0;
|
||||
|
||||
for ( u32 screen_index = 0; screen_index < 100; ++ screen_index )
|
||||
for ( u32 screen_index = 0; screen_index <= 100; ++ screen_index )
|
||||
{
|
||||
// TODO(Ed) : We need a proper RNG.
|
||||
assert( rng_index < array_count(RNG_Table) )
|
||||
@ -1015,6 +1056,9 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
|
||||
door_top = true;
|
||||
}
|
||||
|
||||
local_persist TileChunkPosition last_chunk = {};
|
||||
s32 chunk_index = 0;
|
||||
|
||||
for (s32 tile_y = 0; tile_y < world->tiles_per_screen_y; ++ tile_y )
|
||||
{
|
||||
for ( s32 tile_x = 0; tile_x < world->tiles_per_screen_x; ++ tile_x )
|
||||
@ -1022,6 +1066,12 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
|
||||
s32 abs_tile_x = screen_x * world->tiles_per_screen_x + tile_x;
|
||||
s32 abs_tile_y = screen_y * world->tiles_per_screen_y + tile_y;
|
||||
|
||||
do_once()
|
||||
{
|
||||
gs->spawn_pos.tile_x = abs_tile_x + 4;
|
||||
gs->spawn_pos.tile_y = abs_tile_y + 4;
|
||||
}
|
||||
|
||||
s32 tile_value = 1;
|
||||
|
||||
b32 in_middle_x = tile_x == (world->tiles_per_screen_x / 2);
|
||||
@ -1063,9 +1113,22 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
|
||||
}
|
||||
}
|
||||
|
||||
last_chunk = get_tile_chunk_position_for( tile_map, abs_tile_x, abs_tile_y, abs_tile_z );
|
||||
chunk_index =
|
||||
last_chunk.z * tile_map->tile_chunks_num_y * tile_map->tile_chunks_num_x
|
||||
+ last_chunk.y * tile_map->tile_chunks_num_x
|
||||
+ last_chunk.x;
|
||||
|
||||
// u32 tile_value = tile_x == tile_y && tile_y % 2 ? 1 : 0;
|
||||
TileMap_set_tile_value( & state->world_arena, world->tile_map, abs_tile_x, abs_tile_y, abs_tile_z, tile_value );
|
||||
}
|
||||
|
||||
s32 something = false;
|
||||
something++;
|
||||
if ( something )
|
||||
{
|
||||
something--;
|
||||
}
|
||||
}
|
||||
|
||||
door_left = door_right;
|
||||
@ -1107,9 +1170,6 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
|
||||
}
|
||||
}
|
||||
|
||||
hh::GameState* gs = rcast( hh::GameState*, state->game_memory.persistent );
|
||||
assert( sizeof(hh::GameState) <= state->game_memory.persistent_size );
|
||||
|
||||
// Personally made assets
|
||||
{
|
||||
StrPath path_test_bg {};
|
||||
@ -1198,9 +1258,6 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
|
||||
|
||||
using hh::FacingDirection_Front;
|
||||
|
||||
// gs->player_1 = {};
|
||||
// gs->player_2 = {};
|
||||
|
||||
gs->camera_assigned_entity_id = gs->player_1.entity_id;
|
||||
}
|
||||
|
||||
@ -1420,9 +1477,16 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
||||
s32 tile_id = TileMap_get_tile_value( tile_map, col, row, gs->camera_pos.tile_z );
|
||||
f32 color[3] = { 0.15f, 0.15f, 0.15f };
|
||||
|
||||
if ( tile_id > 1 || (entity_followed && row == entity_followed->position.tile_y && col == entity_followed->position.tile_x) )
|
||||
if ( tile_id > 1 || tile_id == 0 || (entity_followed && row == entity_followed->position.tile_y && col == entity_followed->position.tile_x) )
|
||||
// if ( tile_id > 1 )
|
||||
{
|
||||
if ( tile_id == 0 )
|
||||
{
|
||||
color[0] = 0.88f;
|
||||
color[1] = 0.22f;
|
||||
color[2] = 0.77f;
|
||||
}
|
||||
|
||||
if ( tile_id == 2 )
|
||||
{
|
||||
color[0] = 0.42f;
|
||||
|
@ -7,7 +7,7 @@ NS_ENGINE_BEGIN
|
||||
inline
|
||||
TileMapPos subtract( TileMapPos pos_a, TileMapPos pos_b )
|
||||
{
|
||||
TileMapPos result {
|
||||
TileMapPos result = {
|
||||
pos_a.rel_pos - pos_b.rel_pos,
|
||||
|
||||
pos_a.tile_x - pos_b.tile_x,
|
||||
@ -16,6 +16,7 @@ TileMapPos subtract( TileMapPos pos_a, TileMapPos pos_b )
|
||||
// TODO(Ed) : Think about how to handle z...
|
||||
pos_a.tile_z - pos_b.tile_z
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -53,6 +54,13 @@ TileMapPos recannonicalize_position( TileMap* tile_map, TileMapPos pos )
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
void offset( TileMap* tile_map, TileMapPos& map_pos, Vec2 rel_offset )
|
||||
{
|
||||
map_pos.rel_pos += rel_offset;
|
||||
map_pos = recannonicalize_position( tile_map, map_pos);
|
||||
}
|
||||
|
||||
inline
|
||||
u32 TileChunk_get_tile_value( TileChunk* tile_chunk, TileMap* tile_map, s32 x, s32 y )
|
||||
{
|
||||
@ -77,18 +85,20 @@ void TileChunk_set_tile_value( TileChunk* tile_chunk, TileMap* tile_map, s32 x,
|
||||
}
|
||||
|
||||
inline
|
||||
TileChunk* TileMap_get_chunk( TileMap* tile_map, s32 tile_chunk_x, s32 tile_chunk_y, s32 tile_chunk_z )
|
||||
TileChunk* TileMap_get_chunk( TileMap* tile_map, TileChunkPosition chunk_pos )
|
||||
{
|
||||
TileChunk* chunk = nullptr;
|
||||
|
||||
if ( tile_chunk_x >= 0 && tile_chunk_x < scast(s32, tile_map->tile_chunks_num_x)
|
||||
&& tile_chunk_y >= 0 && tile_chunk_y < scast(s32, tile_map->tile_chunks_num_y)
|
||||
&& tile_chunk_z >= 0 && tile_chunk_z < scast(s32, tile_map->tile_chunks_num_z) )
|
||||
if ( chunk_pos.x >= 0 && chunk_pos.x < tile_map->tile_chunks_num_x
|
||||
&& chunk_pos.y >= 0 && chunk_pos.y < tile_map->tile_chunks_num_y
|
||||
&& chunk_pos.z >= 0 && chunk_pos.z < tile_map->tile_chunks_num_z )
|
||||
{
|
||||
chunk = & tile_map->chunks[
|
||||
tile_chunk_z * tile_map->tile_chunks_num_y * tile_map->tile_chunks_num_x
|
||||
+ tile_chunk_y * tile_map->tile_chunks_num_x
|
||||
+ tile_chunk_x ];
|
||||
chunk_pos.z * tile_map->tile_chunks_num_y * tile_map->tile_chunks_num_x
|
||||
+ chunk_pos.y * tile_map->tile_chunks_num_x
|
||||
+ chunk_pos.x ];
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
return chunk;
|
||||
@ -100,9 +110,22 @@ TileChunkPosition get_tile_chunk_position_for( TileMap* tile_map, s32 abs_tile_x
|
||||
assert( tile_map != nullptr );
|
||||
|
||||
TileChunkPosition chunk_pos {};
|
||||
chunk_pos.tile_chunk_x = abs_tile_x >> tile_map->chunk_shift;
|
||||
chunk_pos.tile_chunk_y = abs_tile_y >> tile_map->chunk_shift;
|
||||
chunk_pos.tile_chunk_z = abs_tile_z;
|
||||
chunk_pos.x = abs_tile_x >> tile_map->chunk_shift;
|
||||
chunk_pos.y = abs_tile_y >> tile_map->chunk_shift;
|
||||
chunk_pos.z = abs_tile_z;
|
||||
|
||||
// Correct negative values
|
||||
s32 neg_mask = (1 << (sizeof(s32) * 8 - 1));
|
||||
s32 is_neg_x = (chunk_pos.x & neg_mask) < 0;
|
||||
s32 is_neg_y = (chunk_pos.y & neg_mask) < 0;
|
||||
s32 offset_x = is_neg_x * tile_map->tile_chunks_num_x;
|
||||
s32 offset_y = is_neg_y * tile_map->tile_chunks_num_y;
|
||||
chunk_pos.x = offset_x + chunk_pos.x;
|
||||
chunk_pos.y = offset_y + chunk_pos.y;
|
||||
|
||||
// chunk_pos.tile_x = (abs_tile_x * (-1 * is_neg_x)) & tile_map->chunk_mask;
|
||||
// chunk_pos.tile_y = (abs_tile_y * (-1 * is_neg_y)) & tile_map->chunk_mask;
|
||||
|
||||
chunk_pos.tile_x = abs_tile_x & tile_map->chunk_mask;
|
||||
chunk_pos.tile_y = abs_tile_y & tile_map->chunk_mask;
|
||||
|
||||
@ -117,7 +140,7 @@ u32 TileMap_get_tile_value( TileMap* tile_map, s32 tile_x, s32 tile_y, s32 tile_
|
||||
s32 value = 0;
|
||||
|
||||
TileChunkPosition chunk_pos = get_tile_chunk_position_for( tile_map, tile_x, tile_y, tile_z );
|
||||
TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y, chunk_pos.tile_chunk_z );
|
||||
TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos );
|
||||
|
||||
if ( chunk && chunk->tiles )
|
||||
value = TileChunk_get_tile_value( chunk, tile_map, chunk_pos.tile_x, chunk_pos.tile_y );
|
||||
@ -155,7 +178,7 @@ internal
|
||||
void TileMap_set_tile_value( MemoryArena* arena, TileMap* tile_map, s32 abs_tile_x, s32 abs_tile_y, s32 abs_tile_z, s32 value )
|
||||
{
|
||||
TileChunkPosition chunk_pos = get_tile_chunk_position_for( tile_map, abs_tile_x, abs_tile_y, abs_tile_z );
|
||||
TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y, chunk_pos.tile_chunk_z );
|
||||
TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos );
|
||||
|
||||
assert( chunk != nullptr );
|
||||
|
||||
|
@ -23,9 +23,9 @@ struct TileChunk
|
||||
*/
|
||||
struct TileChunkPosition
|
||||
{
|
||||
s32 tile_chunk_x;
|
||||
s32 tile_chunk_y;
|
||||
s32 tile_chunk_z;
|
||||
s32 x;
|
||||
s32 y;
|
||||
s32 z;
|
||||
|
||||
// "Chunk-relative (x, y)
|
||||
|
||||
|
@ -150,6 +150,8 @@ struct GameState
|
||||
Player player_1;
|
||||
Player player_2;
|
||||
|
||||
engine::TileMapPos spawn_pos;
|
||||
|
||||
// PlayerState player_state;
|
||||
// PlayerState player_state_2;
|
||||
|
||||
|
@ -14,6 +14,13 @@ f32 abs( f32 value )
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
s32 sign( s32 value )
|
||||
{
|
||||
s32 result = value >= 0 ? 1 : -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
f32 sqrt( f32 value )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user