improved smooth movement animation for classic BD scheduling types
authorHolger Schemel <holger.schemel@virtion.de>
Tue, 11 Jun 2024 21:39:28 +0000 (23:39 +0200)
committerHolger Schemel <holger.schemel@virtion.de>
Tue, 11 Jun 2024 21:53:16 +0000 (23:53 +0200)
Using the BD game engine with classic scheduling types like "BD1" may
result in alternating numbers of frames per iteration cycle due to
dynamic game speed calculations (like alternating between 7 and 8
frames per iteration), so always using the last maximum number of
cycle frames (to adjust to dynamically changing game speed) results in
always using the wrong number of frames per iteration cycle, causing
less smooth movement animations (due to little stops or jumps for each
iteration cycle movement animation).

Storing the last maximum number of cycle frames for even and odd
cycles separately can improve this by using the "right" number of
cycle frames even if they are alternating between two values.

src/game_bd/bd_gameplay.c
src/game_bd/bd_gameplay.h
src/game_bd/main_bd.c

index 3ca3e43c874f020f015d9619ef23ed730f0fd13a..085dad08f6f0201c9aa6f65d79982df4ab521514 100644 (file)
@@ -122,6 +122,8 @@ static void load_cave(GdGame *game)
   game->milliseconds_anim = 0;
   game->milliseconds_game = 0;        // set game timer to zero, too
 
+  game->cycle_counter = 0;
+
   // create new element buffer
   game->element_buffer = gd_cave_map_new(game->cave, int);
 
@@ -395,17 +397,22 @@ static GdGameState gd_game_main_int(GdGame *game, boolean allow_iterate, boolean
        }
       }
 
-      // store last maximum number of cycles (to force redraw if changed)
+      // store last maximum number of cycle frames (to force redraw if changed)
       game->itermax_last = game->itermax;
 
-      // update maximum number of cycles (frame) per cave iteration
-      game->itermax = game->itercycle;
+      // store maximum number of cycle frames separately for even and odd cycles
+      game->itermax2[game->cycle_counter % 2] = game->itercycle;
+
+      // update maximum number of cycle frames per cave iteration
+      game->itermax = game->itermax2[!(game->cycle_counter % 2)];
 
-      // reset cycle (frame) counter for the next cave iteration
+      // reset cycle frame counter for the next cave iteration
       game->itercycle = 0;
 
       iterate_cave(game, game->player_move, game->player_fire);
 
+      game->cycle_counter++;
+
       if (game->player_move == GD_MV_STILL)
       {
        game->player_move_stick = FALSE;
index 98659a48364e33e373dd6469d64c36dc4dcfc8e6..999c5e845ccc824955cc188430978ad6e6347060 100644 (file)
@@ -83,9 +83,11 @@ typedef struct _gd_game
   int itercycle;
   int itermax;
   int itermax_last;
+  int itermax2[2];
   int animcycle;
   int milliseconds_game;
   int milliseconds_anim;
+  int cycle_counter;
 
   int replay_no_more_movements;
   boolean show_story;          // to remember that story for a particular cave was already shown.
index 7730ba9b3cdc581ed3359dfe28a0eab6cd3cb76d..34a75074754a3dde0df08ddc1b5bbd93b02a5057 100644 (file)
@@ -339,6 +339,8 @@ void InitGameEngine_BD(void)
   game_bd.game->itercycle = 0;
   game_bd.game->itermax = 8;   // default; dynamically changed at runtime
   game_bd.game->itermax_last = game_bd.game->itermax;
+  game_bd.game->itermax2[0] = game_bd.game->itermax;
+  game_bd.game->itermax2[1] = game_bd.game->itermax;
 
   game_bd.player_moving = FALSE;
   game_bd.player_snapping = FALSE;