fix movement bugs
[fishladder.git] / fishladder.c
index 4ff74588763a3990458addab078b3b00a87c1d42..73c9210a92474dadb5f3dbef33638a92ee957526 100644 (file)
@@ -1,6 +1,7 @@
 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
 
 //#define VG_STEAM
+//#define VG_STEAM_APPID 1218140U
 #include "vg/vg.h"
 #include "fishladder_resources.h"
 
@@ -245,7 +246,8 @@ enum e_fish_state
        k_fish_state_soon_dead = -1,
        k_fish_state_dead = 0,
        k_fish_state_alive,
-       k_fish_state_bg
+       k_fish_state_bg,
+       k_fish_state_soon_alive
 };
 
 struct world
@@ -270,6 +272,7 @@ struct world
        int simulating;
        int sim_run, max_runs;
        
+       float sim_speed;
        float frame_lerp;
        
        struct cell_terminal
@@ -1356,6 +1359,7 @@ void vg_update(void)
                        world.sim_frame = 0;
                        world.sim_start = vg_time;
                        world.sim_run = 0;
+                       world.sim_speed = 2.5f;
                        
                        for( int i = 0; i < world.w*world.h; i ++ )
                                world.data[ i ].state &= ~FLAG_FLIP_FLOP;
@@ -1367,7 +1371,7 @@ void vg_update(void)
        // Fish ticks
        if( world.simulating )
        {       
-               while( world.sim_frame < (int)((vg_time-world.sim_start)*2.0f) )
+               while( world.sim_frame < (int)((vg_time-world.sim_start)*world.sim_speed) )
                {
                        //vg_info( "frame: %u\n", world.sim_frame );
                        sfx_set_playrnd( &audio_random, &audio_system_balls_switching, 0, 9 );
@@ -1394,6 +1398,9 @@ void vg_update(void)
                                if( fish->state == k_fish_state_soon_dead )
                                        fish->state = k_fish_state_dead;
                                
+                               if( fish->state == k_fish_state_soon_alive )
+                                       fish->state = k_fish_state_alive;
+                               
                                if( fish->state < k_fish_state_alive )
                                        continue;
                                
@@ -1488,7 +1495,7 @@ void vg_update(void)
                                                        fish->state = world_check_pos_ok( fish->pos )? k_fish_state_bg: k_fish_state_dead;
                                        }
                                        
-                                       v2i_add( fish->pos, fish->dir, fish->pos );
+                                       //v2i_add( fish->pos, fish->dir, fish->pos );
                                }
                                else if( fish->state == k_fish_state_bg )
                                {
@@ -1505,7 +1512,7 @@ void vg_update(void)
                                                        if( cell_entry->config == k_cell_type_con_r || cell_entry->config == k_cell_type_con_u 
                                                                || cell_entry->config == k_cell_type_con_l || cell_entry->config == k_cell_type_con_d )
                                                        {
-                                                               fish->state = k_fish_state_alive;
+                                                               fish->state = k_fish_state_soon_alive;
                                                                
                                                                fish->dir[0] = 0;
                                                                fish->dir[1] = 0;
@@ -1535,6 +1542,7 @@ void vg_update(void)
                                
                                if( fish->state == k_fish_state_alive )
                                {
+                                       v2i_add( fish->pos, fish->dir, fish->pos );
                                        struct cell *cell_current = pcell( fish->pos );
 
                                        if( cell_current->state & FLAG_IS_TRIGGER )
@@ -1559,23 +1567,56 @@ void vg_update(void)
                        }
                        
                        // Third pass (collisions)
+                       struct fish *fi, *fj;
+                       
                        for( int i = 0; i < world.num_fishes; i ++ )
                        {
-                               if( world.fishes[i].state == k_fish_state_alive )
+                               fi = &world.fishes[i];
+                               
+                               if( fi->state == k_fish_state_alive )
                                {
+                                       int continue_again = 0;
+                               
                                        for( int j = i+1; j < world.num_fishes; j ++ )
                                        {
-                                               if( (world.fishes[j].state == k_fish_state_alive) && 
-                                                        (world.fishes[i].pos[0] == world.fishes[j].pos[0]) &&
-                                                        (world.fishes[i].pos[1] == world.fishes[j].pos[1]) )
+                                               fj = &world.fishes[j];
+                                               
+                                               if( (fj->state == k_fish_state_alive) )
                                                {
-                                                       // Shatter death (+0.5s)
-                                                       world.fishes[i].state = k_fish_state_soon_dead;
-                                                       world.fishes[j].state = k_fish_state_soon_dead;
-                                                       world.fishes[i].death_time = 0.5f;
-                                                       world.fishes[j].death_time = 0.5f;
+                                                       v2i fi_prev;
+                                                       v2i fj_prev;
+                                                       
+                                                       v2i_sub( fi->pos, fi->dir, fi_prev );
+                                                       v2i_sub( fj->pos, fj->dir, fj_prev );
+                                               
+                                                       int 
+                                                       collide_next_frame = ( 
+                                                                (fi->pos[0] == fj->pos[0]) &&
+                                                                (fi->pos[1] == fj->pos[1]))? 1: 0,
+                                                       collide_this_frame = (
+                                                                (fi_prev[0] == fj->pos[0]) &&
+                                                                (fi_prev[1] == fj->pos[1]) &&
+                                                                (fj_prev[0] == fi->pos[0]) &&
+                                                                (fj_prev[1] == fi->pos[1])
+                                                               )? 1: 0;
+                                               
+                                                       if( collide_next_frame || collide_this_frame )
+                                                       {
+                                                               // Shatter death (+0.5s)
+                                                               float death_time = collide_this_frame? 0.0f: 0.5f;
+                                                               
+                                                               fi->state = k_fish_state_soon_dead;
+                                                               fj->state = k_fish_state_soon_dead;
+                                                               fi->death_time = death_time;
+                                                               fj->death_time = death_time;
+                                                               
+                                                               continue_again = 1;
+                                                               break;
+                                                       }
                                                }
                                        }
+                                       if( continue_again )
+                                               continue;
                                }
                        }
                        
@@ -1654,6 +1695,10 @@ void vg_update(void)
                                                world.sim_frame = 0;
                                                world.sim_start = vg_time;
                                                world.num_fishes = 0;
+                                               
+                                               for( int i = 0; i < world.w*world.h; i ++ )
+                                                       world.data[ i ].state &= ~FLAG_FLIP_FLOP;
+                                               
                                                continue;
                                        }
                                        else
@@ -1690,7 +1735,7 @@ void vg_update(void)
                }
                
                float scaled_time = 0.0f;
-               scaled_time = (vg_time-world.sim_start)*2.0f;
+               scaled_time = (vg_time-world.sim_start)*world.sim_speed;
                world.frame_lerp = scaled_time - (float)world.sim_frame;
                
                // Update positions