mirror of
https://github.com/Ed94/HandmadeHero.git
synced 2024-12-21 22:14:43 -08:00
Day 45 complete
This commit is contained in:
parent
577ee6b208
commit
470e85ea3a
@ -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:
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
|
@ -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 };
|
||||
|
@ -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
|
||||
|
@ -34,3 +34,4 @@ Handmade Engine Translation Unit
|
||||
#include "tile_map.cpp"
|
||||
#include "random.cpp"
|
||||
#include "engine.cpp"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user