Day 45 complete

This commit is contained in:
Edward R. Gonzalez 2023-12-29 14:53:00 -05:00
parent 577ee6b208
commit 470e85ea3a
7 changed files with 188 additions and 96 deletions

View File

@ -33,7 +33,7 @@ Module build order:
## Milestone
Day 43 : The Equations of Motion
Day 45 : Geometric vs. Temporal Movement Search
Features Done so far:

View File

@ -63,12 +63,17 @@ constexpr char const* vec2f_ops = stringize(
}
inline
<unit_type> scalar_product( <type> a, <type> b )
{
<unit_type> scalar_product( <type> a, <type> b ) {
<unit_type> result = a.x * b.x + a.y * b.y;
return result;
}
inline
<unit_type> magnitude_squared( <type> v ) {
<unit_type> result = scalar_product( v, v );
return result;
}
inline
<type> operator - ( <type> v ) {
<type> result {

View File

@ -876,7 +876,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
move_accel = 94.f;
}
Pos2_f32 new_player_pos = { player->position.rel_pos.x, player->position.rel_pos.y };
TileMapPos old_pos = player->position;
Pos2_f32 new_player_pos = { old_pos.rel_pos.x, old_pos.rel_pos.y };
Vec2 player_move_vec = {};
if ( player_actions.player_x_move_analog || player_actions.player_y_move_analog )
@ -900,109 +901,154 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
player->move_velocity += player_move_accel * 0.5f;
new_player_pos += player->move_velocity;
b32 collision_nw = false;
b32 collision_ne = false;
b32 collision_sw = false;
b32 collision_se = false;
do
// Old collision implmentation
#if 1
{
// Base position
//TileMapPos test_pos = {
//new_player_pos.x, new_player_pos.y,
//player->position.tile_x, player->position.tile_y, player->position.tile_z
//};
//test_pos = recannonicalize_position( tile_map, test_pos );
b32 collision_nw = false;
b32 collision_ne = false;
b32 collision_sw = false;
b32 collision_se = false;
do
{
// Base position
//TileMapPos test_pos = {
//new_player_pos.x, new_player_pos.y,
//old_pos.tile_x, old_pos.tile_y, old_pos.tile_z
//};
//test_pos = recannonicalize_position( tile_map, test_pos );
// TODO(Ed) : Need a delta-function that auto-reconnonicalizes.
// TODO(Ed) : Need a delta-function that auto-reconnonicalizes.
TileMapPos test_pos_nw {
new_player_pos.x - player_half_width, new_player_pos.y + player_quarter_height,
player->position.tile_x, player->position.tile_y, player->position.tile_z
TileMapPos test_pos_nw {
new_player_pos.x - player_half_width, new_player_pos.y + player_quarter_height,
old_pos.tile_x, old_pos.tile_y, old_pos.tile_z
};
test_pos_nw = recannonicalize_position( tile_map, test_pos_nw );
collision_nw = ! TileMap_is_point_empty( tile_map, test_pos_nw );
TileMapPos test_pos_ne {
new_player_pos.x + player_half_width, new_player_pos.y + player_quarter_height,
old_pos.tile_x, old_pos.tile_y, old_pos.tile_z
};
test_pos_ne = recannonicalize_position( tile_map, test_pos_ne );
collision_ne = ! TileMap_is_point_empty( tile_map, test_pos_ne );
TileMapPos test_pos_sw {
new_player_pos.x - player_half_width, new_player_pos.y,
old_pos.tile_x, old_pos.tile_y, old_pos.tile_z
};
test_pos_sw = recannonicalize_position( tile_map, test_pos_sw );
collision_sw = ! TileMap_is_point_empty( tile_map, test_pos_sw );
TileMapPos test_pos_se {
new_player_pos.x + player_half_width, new_player_pos.y,
old_pos.tile_x, old_pos.tile_y, old_pos.tile_z
};
test_pos_se = recannonicalize_position( tile_map, test_pos_se );
collision_se = ! TileMap_is_point_empty( tile_map, test_pos_se );
}
while(0);
if ( collision_se || collision_sw || collision_ne || collision_nw )
{
// Should be colliding with a wall
Vec2 wall_vector = { 0, 0 };
if ( collision_nw && collision_sw )
{
wall_vector = { 1.f, 0.f };
}
{
wall_vector = { -1.f, 0.f };
}
if ( collision_nw && collision_ne )
{
wall_vector = { 0.f, 1.f };
}
if ( collision_se && collision_sw )
{
wall_vector = { 0.f, -1.f };
}
//if ( collision_nw && !collision_ne && !collision_sw && !collision_se )
//{
// wall_vector = { 1.f, 1.f };
//}
// The 2x multiplier allows for the the "bounce off" velocity to occur instead of the player just looking like they impacted the wall and stopped
player->move_velocity -= cast( Vel2, 1.f * scalar_product( Vec2( player->move_velocity ), wall_vector ) * wall_vector );
new_player_pos = { old_pos.rel_pos.x, old_pos.rel_pos.y };
new_player_pos += player->move_velocity;
}
TileMapPos new_pos = {
new_player_pos.x, new_player_pos.y,
old_pos.tile_x, old_pos.tile_y, old_pos.tile_z
};
test_pos_nw = recannonicalize_position( tile_map, test_pos_nw );
collision_nw = ! TileMap_is_point_empty( tile_map, test_pos_nw );
TileMapPos test_pos_ne {
new_player_pos.x + player_half_width, new_player_pos.y + player_quarter_height,
player->position.tile_x, player->position.tile_y, player->position.tile_z
};
test_pos_ne = recannonicalize_position( tile_map, test_pos_ne );
collision_ne = ! TileMap_is_point_empty( tile_map, test_pos_ne );
TileMapPos test_pos_sw {
new_player_pos.x - player_half_width, new_player_pos.y,
player->position.tile_x, player->position.tile_y, player->position.tile_z
};
test_pos_sw = recannonicalize_position( tile_map, test_pos_sw );
collision_sw = ! TileMap_is_point_empty( tile_map, test_pos_sw );
TileMapPos test_pos_se {
new_player_pos.x + player_half_width, new_player_pos.y,
player->position.tile_x, player->position.tile_y, player->position.tile_z
};
test_pos_se = recannonicalize_position( tile_map, test_pos_se );
collision_se = ! TileMap_is_point_empty( tile_map, test_pos_se );
new_pos = recannonicalize_position( tile_map, new_pos );
player->position = new_pos;
}
while(0);
if ( collision_se || collision_sw || collision_ne || collision_nw )
#else
{
// Should be colliding with a wall
TileMapPos new_pos = {
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 );
Vec2 wall_vector = { 0, 0 };
if ( collision_nw && collision_sw )
s32 min_tile_x = 0;
s32 min_tile_y = 0;
TileMapPos best_position = old_pos;
Dist2 best_distance2 = cast(Dist2, magnitude_squared( player->move_velocity ) );
for ( s32 tile_y = 0; tile_y <= min_tile_y; ++ tile_y )
{
wall_vector = { 1.f, 0.f };
}
if ( collision_ne && collision_se )
{
wall_vector = { -1.f, 0.f };
}
if ( collision_nw && collision_ne )
{
wall_vector = { 0.f, 1.f };
}
if ( collision_se && collision_sw )
{
wall_vector = { 0.f, -1.f };
for ( s32 tile_x = 0; tile_x <= min_tile_x; ++ tile_x )
{
TileMapPos test_tile_pos = centered_tile_point( tile_x, tile_y, new_pos.tile_z );
s32 tile_value = TileMap_get_tile_value( tile_map, test_tile_pos );
if ( TileMap_is_tile_value_empty( tile_value ) )
{
Vec2 tile_xy_in_meters = Vec2 { tile_map->tile_size_in_meters, tile_map->tile_size_in_meters };
Vec2 min_corner = -0.5f * tile_xy_in_meters;
Vec2 max_corner = 0.5f * tile_xy_in_meters;
TileMapPos rel_new_player_pos = subtract( test_tile_pos, new_pos );
Vec2 test_pos = closest_point_in_rectangle( min_corner, max_corner, rel_new_player_pos );
f32 test_dist2 = ;
if ( best_distance2 > test_dst )
{
best_position = ;
best_distance2 = ;
}
}
}
}
//if ( collision_nw && !collision_ne && !collision_sw && !collision_se )
//{
// wall_vector = { 1.f, 1.f };
//}
// The 2x multiplier allows for the the "bounce off" velocity to occur instead of the player just looking like they impacted the wall and stopped
player->move_velocity -= cast( Vel2, 1.f * scalar_product( Vec2( player->move_velocity ), wall_vector ) * wall_vector );
new_player_pos = { player->position.rel_pos.x, player->position.rel_pos.y };
new_player_pos += player->move_velocity;
player->position = new_pos;
}
#endif
TileMapPos new_pos = {
new_player_pos.x, new_player_pos.y,
player->position.tile_x, player->position.tile_y, player->position.tile_z
};
new_pos = recannonicalize_position( tile_map, new_pos );
bool on_new_tile = TileMap_are_on_same_tile( & new_pos, & player->position );
bool on_new_tile = TileMap_are_on_same_tile( & player->position, & old_pos );
if ( ! on_new_tile )
{
u32 new_tile_value = TileMap_get_tile_value( tile_map, new_pos );
u32 new_tile_value = TileMap_get_tile_value( tile_map, player->position );
if ( new_tile_value == 3 )
{
++ new_pos.tile_z;
++ player->position.tile_z;
}
else if ( new_tile_value == 4 )
{
-- new_pos.tile_z;
-- player->position.tile_z;
}
}
player->position = new_pos;
if ( player_actions.player_y_move_digital > 0 || player_actions.player_y_move_analog > 0 )
{
game_state->hero_direction = HeroBitmaps_Back;

View File

@ -66,6 +66,12 @@ inline f32 scalar_product( Pos2_f32 a, Pos2_f32 b )
return result;
}
inline f32 magnitude_squared( Pos2_f32 v )
{
f32 result = scalar_product( v, v );
return result;
}
inline Pos2_f32 operator-( Pos2_f32 v )
{
Pos2_f32 result { -v.x, -v.y };
@ -201,6 +207,12 @@ inline f32 scalar_product( Vel2_f32 a, Vel2_f32 b )
return result;
}
inline f32 magnitude_squared( Vel2_f32 v )
{
f32 result = scalar_product( v, v );
return result;
}
inline Vel2_f32 operator-( Vel2_f32 v )
{
Vel2_f32 result { -v.x, -v.y };
@ -326,6 +338,12 @@ inline f32 scalar_product( Accel2_f32 a, Accel2_f32 b )
return result;
}
inline f32 magnitude_squared( Accel2_f32 v )
{
f32 result = scalar_product( v, v );
return result;
}
inline Accel2_f32 operator-( Accel2_f32 v )
{
Accel2_f32 result { -v.x, -v.y };

View File

@ -55,6 +55,12 @@ inline f32 scalar_product( Vec2_f32 a, Vec2_f32 b )
return result;
}
inline f32 magnitude_squared( Vec2_f32 v )
{
f32 result = scalar_product( v, v );
return result;
}
inline Vec2_f32 operator-( Vec2_f32 v )
{
Vec2_f32 result { -v.x, -v.y };

View File

@ -94,7 +94,7 @@ TileChunk* TileMap_get_chunk( TileMap* tile_map, s32 tile_chunk_x, s32 tile_chun
}
inline
TileChunkPosition get_tile_chunk_position_for( TileMap* tile_map, u32 abs_tile_x, u32 abs_tile_y, u32 abs_tile_z )
TileChunkPosition get_tile_chunk_position_for( TileMap* tile_map, s32 abs_tile_x, s32 abs_tile_y, s32 abs_tile_z )
{
assert( tile_map != nullptr );
@ -130,6 +130,16 @@ u32 TileMap_get_tile_value( TileMap* tile_map, TileMapPos position )
return value;
}
internal
b32 TileMap_is_tile_value_empty(s32 tile_value)
{
b32
is_empty = tile_value == 1;
is_empty |= tile_value == 3;
is_empty |= tile_value == 4;
return is_empty;
}
internal
b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPos position )
{
@ -137,11 +147,7 @@ b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPos position )
u32 chunk_value = TileMap_get_tile_value( tile_map, position.tile_x, position.tile_y, position.tile_z );
b32
is_empty = chunk_value == 1;
is_empty |= chunk_value == 3;
is_empty |= chunk_value == 4;
return is_empty;
return TileMap_is_tile_value_empty( chunk_value );
}
internal
@ -177,4 +183,14 @@ b32 TileMap_are_on_same_tile( TileMapPos* pos_a, TileMapPos* pos_b )
return result;
}
inline
TileMapPos centered_tile_point( s32 tile_x, s32 tile_y, s32 tile_z )
{
TileMapPos result {};
result.tile_x = tile_x;
result.tile_y = tile_y;
result.tile_z = tile_z;
return result;
}
NS_ENGINE_END

View File

@ -34,3 +34,4 @@ Handmade Engine Translation Unit
#include "tile_map.cpp"
#include "random.cpp"
#include "engine.cpp"