[gnome-robots] decouple Game and GameArea



commit 8c80a4a7b51bd81a11395989bb28ea8e578a3cb6
Author: Andrey Kutejko <andy128k gmail com>
Date:   Sun Sep 20 23:02:19 2020 +0200

    decouple Game and GameArea

 src/game-area.vala  |  25 +++++--
 src/game.vala       | 196 +++++++++++++++++++---------------------------------
 src/properties.vala |   1 +
 src/robots.vala     |  20 ++++--
 4 files changed, 109 insertions(+), 133 deletions(-)
---
diff --git a/src/game-area.vala b/src/game-area.vala
index 91ee0f6..817b817 100644
--- a/src/game-area.vala
+++ b/src/game-area.vala
@@ -25,6 +25,7 @@ public class GameArea : DrawingArea {
 
     const int MINIMUM_TILE_WIDTH = 8;
     const int MINIMUM_TILE_HEIGHT = 8;
+    const int ANIMATION_DELAY = 100;
 
     private int tile_width = 0;
     private int tile_height = 0;
@@ -39,6 +40,7 @@ public class GameArea : DrawingArea {
     private Bubble yahoo_bubble;
     private Bubble splat_bubble;
 
+    private uint timer_id;
     private Animated player_animation;
     private Animated player_dead_animation;
     private Animated robot1_animation;
@@ -124,6 +126,12 @@ public class GameArea : DrawingArea {
             .sequence (Theme.Frames.ROBOT2_START)
             .limit (Theme.Frames.NUM_ROBOT2_ANIMATIONS)
             .forever ();
+
+        timer_id = Timeout.add (ANIMATION_DELAY, timer_cb);
+    }
+
+    ~GameArea () {
+        Source.remove (timer_id);
     }
 
     private bool resize_cb (Gdk.EventConfigure e) {
@@ -151,7 +159,7 @@ public class GameArea : DrawingArea {
                                game.splat.y * tile_height + 8);
         }
 
-        switch (game.get_state ()) {
+        switch (game.state) {
         case Game.State.DEAD:
             aieee_bubble.draw (cr,
                                game.player.x * tile_width + 8,
@@ -185,7 +193,7 @@ public class GameArea : DrawingArea {
         int animation = 0;
         switch (type) {
         case ObjectType.PLAYER:
-            if (game.get_state () != Game.State.DEAD) {
+            if (game.state != Game.State.DEAD) {
                 animation = player_animation.frame;
             } else {
                 animation = player_dead_animation.frame;
@@ -210,29 +218,36 @@ public class GameArea : DrawingArea {
         cr.restore ();
     }
 
-    public void tick () {
+    private bool timer_cb () {
         player_animation.tick ();
         player_dead_animation.tick ();
         robot1_animation.tick ();
         robot2_animation.tick ();
+
+        game.tick ();
+
+        queue_draw ();
+        return true;
     }
 
     private void mouse_cb (int n_press, double x, double y) {
-        if (game.get_state () != Game.State.PLAYING) {
+        if (game.state != Game.State.PLAYING) {
             return;
         }
 
         int dx, dy;
         get_dir (x, y, out dx, out dy);
 
+        // TODO: replace by player_command
         if (game.player_move (dx, dy)) {
             game.move_robots ();
+            queue_draw ();
         }
     }
 
     private void move_cb (double x, double y) {
         var window = get_window ();
-        if (game.get_state () != Game.State.PLAYING) {
+        if (game.state != Game.State.PLAYING) {
             set_cursor_default (window);
         } else {
             int dx, dy;
diff --git a/src/game.vala b/src/game.vala
index f7ec535..a21c998 100644
--- a/src/game.vala
+++ b/src/game.vala
@@ -19,11 +19,6 @@
 
 using Games;
 
-public const int ANIMATION_DELAY = 100;
-public const int DEAD_DELAY = 30;
-public const int CHANGE_DELAY = 20;
-public const int WAITING_DELAY = 1;
-
 public Game game = null;
 
 public class Game {
@@ -34,17 +29,19 @@ public class Game {
     public const int GAME_WIDTH = 45;
     public const int GAME_HEIGHT = 30;
 
+    public const int DEAD_DELAY = 30;
+    public const int CHANGE_DELAY = 20;
+
     public enum State {
         PLAYING = 1,
         WAITING,
         COMPLETE,
         DEAD,
-        ROBOT,
         TYPE2,
-        WTYPE2,
+        WAITING_TYPE2,
     }
 
-    public enum KeyboardControl {
+    public enum PlayerCommand {
         NW = 0,
         N,
         NE,
@@ -54,14 +51,14 @@ public class Game {
         SW,
         S,
         SE,
-        TELE,
-        RTEL,
+        SAFE_TELEPORT,
+        RANDOM_TELEPORT,
         WAIT,
     }
 
     Rand rand;
-    public State state = State.PLAYING;
-    public Arena arena;
+    public State state { get; private set; }
+    public Arena arena { get; private set; }
     public GameConfig config { get; set; }
     public int width {
         get { return arena.width; }
@@ -72,13 +69,12 @@ public class Game {
     public Arena.Coords player { get; private set; }
     public Arena.Coords? splat { get; private set; }
 
-    int endlev_counter = 0;
-    int current_level = 0;
-    int score = 0;
-    int kills = 0;
-    int score_step = 0;
-    int safe_teleports = 0;
-    uint game_timer_id = -1;
+    private int endlev_counter = 0;
+    private int current_level = 0;
+    private int score = 0;
+    private int kills = 0;
+    private int score_step = 0;
+    private int safe_teleports = 0;
 
     struct ArenaChange {
         Arena arena;
@@ -89,10 +85,7 @@ public class Game {
     public Game () {
         arena = new Arena (GAME_WIDTH, GAME_HEIGHT);
         rand = new Rand ();
-    }
-
-    public State get_state () {
-        return state;
+        state = State.PLAYING;
     }
 
     /**
@@ -106,6 +99,10 @@ public class Game {
      * Enters a score in the high-score table
      **/
     void log_score (int sc) {
+        if (sc <= 0) {
+            return;
+        }
+
         string key;
         if (properties_super_safe_moves ()) {
             key = config.description + "-super-safe";
@@ -115,17 +112,15 @@ public class Game {
             key = config.description;
         }
 
-        if (sc != 0) {
-            string name = category_name_from_key (key);
-            var category = new Scores.Category (key, name);
-            highscores.add_score.begin (sc, category, null, (ctx, res) => {
-                try {
-                    highscores.add_score.end (res);
-                } catch (Error error) {
-                    warning ("Failed to add score: %s", error.message);
-                }
-            });
-        }
+        string name = category_name_from_key (key);
+        var category = new Scores.Category (key, name);
+        highscores.add_score.begin (sc, category, null, (ctx, res) => {
+            try {
+                highscores.add_score.end (res);
+            } catch (Error error) {
+                warning ("Failed to add score: %s", error.message);
+            }
+        });
     }
 
     /**
@@ -137,7 +132,6 @@ public class Game {
         arena[player.x, player.y] = ObjectType.PLAYER;
         endlev_counter = 0;
         set_move_action_sensitivity (false);
-        game_area.queue_draw ();
     }
 
     /**
@@ -149,7 +143,7 @@ public class Game {
      **/
     void add_kill (ObjectType type) {
         int si;
-        if ((state == State.WAITING) || (state == State.WTYPE2)) {
+        if ((state == State.WAITING) || (state == State.WAITING_TYPE2)) {
             if (type == ObjectType.ROBOT1) {
                 si = config.score_type1_waiting;
                 kills += 1;
@@ -300,20 +294,8 @@ public class Game {
         update_game_status (score, current_level + 1, safe_teleports);
     }
 
-
-    /**
-     * timeout_cb
-     * @data: callback data
-     *
-     * Description:
-     * Game timer callback function
-     **/
-    bool timeout_cb () {
-        game_area.tick ();
-
-        game_area.queue_draw ();
-
-        if ((state == State.TYPE2) || (state == State.WTYPE2)) {
+    public void tick () {
+        if ((state == State.TYPE2) || (state == State.WAITING_TYPE2)) {
             var new_arena = move_type2_robots ();
             var change = ArenaChange () {
                 arena = new_arena,
@@ -323,12 +305,11 @@ public class Game {
             update_arena (change);
             if (state == State.TYPE2) {
                 state = State.PLAYING;
-            } else if (state == State.WTYPE2) {
+            } else if (state == State.WAITING_TYPE2) {
                 state = State.WAITING;
             }
         } else if (state == State.WAITING) {
             splat = null;
-            game_area.queue_draw ();
             move_robots ();
         } else if (state == State.COMPLETE) {
             ++endlev_counter;
@@ -339,7 +320,6 @@ public class Game {
                 set_move_action_sensitivity (true);
                 update_game_status (score, current_level + 1, safe_teleports);
                 splat = null;
-                game_area.queue_draw ();
             }
         } else if (state == State.DEAD) {
             ++endlev_counter;
@@ -350,47 +330,9 @@ public class Game {
                 start_new_game ();
             }
         }
-
-        return true;
-    }
-
-    /**
-     * Destroys the game timer
-     **/
-    void destroy_game_timer () {
-        if (game_timer_id != -1) {
-            Source.remove (game_timer_id);
-            game_timer_id = -1;
-        }
-    }
-
-
-    /**
-     * create_game_timer
-     *
-     * Description:
-     * Creates the game timer
-     **/
-    void create_game_timer () {
-        if (game_timer_id != -1) {
-            destroy_game_timer ();
-        }
-
-        game_timer_id = Timeout.add (ANIMATION_DELAY, timeout_cb);
     }
 
     /**
-     * Initialises everything when game first starts up
-     **/
-    public void init_game () {
-        create_game_timer ();
-        start_new_game ();
-    }
-
-    /**
-     * start_new_game
-     *
-     * Description:
      * Initialises everything needed to start a new game
      **/
     public void start_new_game () {
@@ -406,7 +348,6 @@ public class Game {
 
         splat = null;
         generate_level ();
-        game_area.queue_draw ();
 
         state = State.PLAYING;
 
@@ -443,10 +384,10 @@ public class Game {
     public void move_robots () {
         var new_arena = move_all_robots ();
 
-        var num_robots2 = arena.count (obj => obj == ObjectType.ROBOT2);
+        var num_robots2 = new_arena.count (obj => obj == ObjectType.ROBOT2);
         if (num_robots2 > 0) {
             if (state == State.WAITING) {
-                state = State.WTYPE2;
+                state = State.WAITING_TYPE2;
             } else if (state == State.PLAYING) {
                 state = State.TYPE2;
             }
@@ -665,7 +606,6 @@ public class Game {
 
         splat = null;
         update_arena (change);
-        game_area.queue_draw ();
 
         return true;
     }
@@ -691,7 +631,6 @@ public class Game {
 
             update_arena (change);
             splat = null;
-            game_area.queue_draw ();
             play_sound (Sound.TELEPORT);
 
             return true;
@@ -733,7 +672,6 @@ public class Game {
 
             update_arena (change);
             splat = null;
-            game_area.queue_draw ();
             play_sound (Sound.TELEPORT);
 
             return true;
@@ -747,69 +685,81 @@ public class Game {
     /**
      * handles keyboard commands
      **/
-    public void keypress (KeyboardControl key) {
+    public bool player_command (PlayerCommand key) {
         if (state != State.PLAYING)
-            return;
+            return false;
 
         switch (key) {
-        case KeyboardControl.NW:
+        case PlayerCommand.NW:
             if (player_move (-1, -1)) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.N:
+            return false;
+        case PlayerCommand.N:
             if (player_move (0, -1)) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.NE:
+            return false;
+        case PlayerCommand.NE:
             if (player_move (1, -1)) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.W:
+            return false;
+        case PlayerCommand.W:
             if (player_move (-1, 0)) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.STAY:
+            return false;
+        case PlayerCommand.STAY:
             if (player_move (0, 0)) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.E:
+            return false;
+        case PlayerCommand.E:
             if (player_move (1, 0)) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.SW:
+            return false;
+        case PlayerCommand.SW:
             if (player_move (-1, 1)) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.S:
+            return false;
+        case PlayerCommand.S:
             if (player_move (0, 1)) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.SE:
+            return false;
+        case PlayerCommand.SE:
             if (player_move (1, 1)) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.TELE:
+            return false;
+        case PlayerCommand.SAFE_TELEPORT:
             if (safe_teleport ()) {
                 move_robots ();
             }
-            break;
-        case KeyboardControl.RTEL:
+            return true;
+        case PlayerCommand.RANDOM_TELEPORT:
             if (random_teleport ()) {
                 move_robots ();
+                return true;
             }
-            break;
-        case KeyboardControl.WAIT:
+            return false;
+        case PlayerCommand.WAIT:
             state = State.WAITING;
-            break;
+            return true;
+        default:
+            return false;
         }
     }
 }
diff --git a/src/properties.vala b/src/properties.vala
index 8acb6d7..2516229 100644
--- a/src/properties.vala
+++ b/src/properties.vala
@@ -93,6 +93,7 @@ void type_selection (string config_name) {
 
     game.config = game_configs.find_by_name (config_name);
     game.start_new_game ();
+    game_area.queue_draw ();
 }
 
 /**
diff --git a/src/robots.vala b/src/robots.vala
index 240279a..9cf0bc4 100644
--- a/src/robots.vala
+++ b/src/robots.vala
@@ -174,19 +174,26 @@ void new_game_cb () {
 
     if (ret == ResponseType.ACCEPT) {
         game.start_new_game ();
+        game_area.queue_draw ();
     }
 }
 
 void random_teleport_cb () {
-    game.keypress (Game.KeyboardControl.RTEL);
+    if (game.player_command (Game.PlayerCommand.RANDOM_TELEPORT)) {
+        game_area.queue_draw ();
+    }
 }
 
 void safe_teleport_cb () {
-    game.keypress (Game.KeyboardControl.TELE);
+    if (game.player_command (Game.PlayerCommand.SAFE_TELEPORT)) {
+        game_area.queue_draw ();
+    }
 }
 
 void wait_cb () {
-    game.keypress (Game.KeyboardControl.WAIT);
+    if (game.player_command (Game.PlayerCommand.WAIT)) {
+        game_area.queue_draw ();
+    }
 }
 
 bool window_configure_event_cb () {
@@ -261,7 +268,9 @@ bool keyboard_cb (EventControllerKey controller, uint keyval, uint keycode, Gdk.
 
     for (var i = 0; i < control_keys.length; ++i) {
         if (pressed == ((char)control_keys[i]).toupper ()) {
-            game.keypress ((Game.KeyboardControl)i);
+            if (game.player_command ((Game.PlayerCommand)i)) {
+                game_area.queue_draw ();
+            }
             return true;
         }
     }
@@ -407,7 +416,8 @@ void activate (Gtk.Application app) {
     init_keyboard ();
 
     game.config = game_configs.find_by_name (properties.selected_config);
-    game.init_game ();
+    game.start_new_game ();
+    game_area.queue_draw ();
 
     GLib.Settings.sync ();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]