[gnome-robots] decouple game class from user interaction (message box/sound)



commit 4e34f27f037273866d50551b8dd9283a4a253504
Author: Andrey Kutejko <andy128k gmail com>
Date:   Sun Sep 27 12:01:06 2020 +0200

    decouple game class from user interaction (message box/sound)

 src/game-area.vala | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/game.vala      | 60 +++++++++++++++++++++++++----------------------------
 src/robots.vala    | 16 ++++----------
 3 files changed, 90 insertions(+), 47 deletions(-)
---
diff --git a/src/game-area.vala b/src/game-area.vala
index aeaacc9..5cac1cb 100644
--- a/src/game-area.vala
+++ b/src/game-area.vala
@@ -130,6 +130,8 @@ public class GameArea : DrawingArea {
             .forever ();
 
         timer_id = Timeout.add (ANIMATION_DELAY, timer_cb);
+
+        game.game_event.connect (on_game_event);
     }
 
     ~GameArea () {
@@ -243,9 +245,7 @@ public class GameArea : DrawingArea {
         get_dir (x, y, out dx, out dy);
 
         var cmd = PlayerCommand.from_direction (dx, dy);
-        if (game.player_command (cmd)) {
-            queue_draw ();
-        }
+        player_command (cmd);
     }
 
     private void move_cb (double x, double y) {
@@ -296,5 +296,60 @@ public class GameArea : DrawingArea {
         odx = MOVE_TABLE[octant, 0];
         ody = MOVE_TABLE[octant, 1];
     }
+
+    public void player_command (PlayerCommand cmd) {
+        if (game.player_command (cmd)) {
+            queue_draw ();
+        } else {
+            play_sound (Sound.BAD);
+        }
+    }
+
+    private void on_game_event (Game.Event event) {
+        switch (event) {
+        case Game.Event.TELEPORTED:
+            play_sound (Sound.TELEPORT);
+            break;
+        case Game.Event.SPLAT:
+            play_sound (Sound.SPLAT);
+            break;
+        case Game.Event.LEVEL_COMPLETE:
+            play_sound (Sound.YAHOO);
+            break;
+        case Game.Event.DEATH:
+            play_sound (Sound.DIE);
+            break;
+        case Game.Event.VICTORY:
+            message_box (_("Congratulations, You Have Defeated the Robots!! \nBut Can You do it Again?"));
+            play_sound (Sound.VICTORY);
+            break;
+        case Game.Event.NO_TELEPORT_LOCATIONS:
+            message_box (_("There are no teleport locations left!!"));
+            break;
+        case Game.Event.NO_SAFE_TELEPORT_LOCATIONS:
+            break;
+        default:
+            break;
+        }
+    }
+
+    /**
+     * Displays a modal dialog box with a given message
+     **/
+    private void message_box (string msg) {
+        var window = get_toplevel () as Gtk.Window;
+        if (window != null) {
+            var box = new Gtk.MessageDialog (window,
+                                             Gtk.DialogFlags.MODAL,
+                                             Gtk.MessageType.INFO,
+                                             Gtk.ButtonsType.OK,
+                                             "%s", msg);
+            box.run ();
+            box.destroy ();
+        } else {
+            warning ("There is no top level window.");
+            info ("%s", msg);
+        }
+    }
 }
 
diff --git a/src/game.vala b/src/game.vala
index 6f9c41d..5f36fee 100644
--- a/src/game.vala
+++ b/src/game.vala
@@ -144,6 +144,18 @@ public class Game {
         state = State.PLAYING;
     }
 
+    public enum Event {
+        TELEPORTED,
+        SPLAT,
+        LEVEL_COMPLETE,
+        DEATH,
+        VICTORY,
+        NO_TELEPORT_LOCATIONS,
+        NO_SAFE_TELEPORT_LOCATIONS,
+    }
+
+    public signal void game_event (Event event);
+
     /**
      * Displays the high-score table
      **/
@@ -184,9 +196,9 @@ public class Game {
      **/
     private void kill_player () {
         state = State.DEAD;
-        play_sound (Sound.DIE);
         arena[player.x, player.y] = ObjectType.PLAYER;
         endlev_counter = 0;
+        game_event (Event.DEATH);
     }
 
     /**
@@ -266,8 +278,7 @@ public class Game {
             num_robots1 = config.initial_type1;
             num_robots2 = config.initial_type2;
 
-            message_box (_("Congratulations, You Have Defeated the Robots!! \nBut Can You do it Again?"));
-            play_sound (Sound.VICTORY);
+            game_event (Event.VICTORY);
         }
 
         safe_teleports += config.free_safe_teleports;
@@ -301,12 +312,12 @@ public class Game {
             switch (arena[change.push.x, change.push.y]) {
             case ObjectType.ROBOT1:
                 splat = change.push;
-                play_sound (Sound.SPLAT);
+                game_event (Event.SPLAT);
                 score += config.score_type1_splatted;
                 break;
             case ObjectType.ROBOT2:
                 splat = change.push;
-                play_sound (Sound.SPLAT);
+                game_event (Event.SPLAT);
                 score += config.score_type2_splatted;
                 break;
             default:
@@ -325,7 +336,7 @@ public class Game {
              * leads to the player being ressurected and winning. */
             if (arena.count (obj => obj == ObjectType.ROBOT1 || obj == ObjectType.ROBOT2) <= 0) {
                 state = State.COMPLETE;
-                play_sound (Sound.YAHOO);
+                game_event (Event.LEVEL_COMPLETE);
                 endlev_counter = 0;
             }
         }
@@ -623,14 +634,12 @@ public class Game {
         var change = try_player_move (dx, dy);
 
         if (change == null) {
-            play_sound (Sound.BAD);
             return false;
         }
 
         if (properties_safe_moves ()) {
             if (!check_safe (change)) {
                 if (properties_super_safe_moves () || safe_move_available ()) {
-                    play_sound (Sound.BAD);
                     return false;
                 }
             }
@@ -663,13 +672,12 @@ public class Game {
 
             update_arena (change);
             splat = null;
-            play_sound (Sound.TELEPORT);
-
+            game_event (Event.TELEPORTED);
             return true;
         }
 
         /* This should never happen. */
-        message_box (_("There are no teleport locations left!!"));
+        game_event (Event.NO_TELEPORT_LOCATIONS);
         return false;
     }
 
@@ -703,24 +711,24 @@ public class Game {
 
             update_arena (change);
             splat = null;
-            play_sound (Sound.TELEPORT);
+            game_event (Event.TELEPORTED);
 
             return true;
         }
 
-        message_box (_("There are no safe locations to teleport to!!"));
+        game_event (Event.NO_SAFE_TELEPORT_LOCATIONS);
         kill_player ();
         return false;
     }
 
     /**
-     * handles keyboard commands
+     * handles player's commands
      **/
-    public bool player_command (PlayerCommand key) {
+    public bool player_command (PlayerCommand cmd) {
         if (state != State.PLAYING)
             return false;
 
-        switch (key) {
+        switch (cmd) {
         case PlayerCommand.NW:
         case PlayerCommand.N:
         case PlayerCommand.NE:
@@ -731,12 +739,13 @@ public class Game {
         case PlayerCommand.S:
         case PlayerCommand.SE:
             int dx, dy;
-            assert (key.to_direction (out dx, out dy));
+            assert (cmd.to_direction (out dx, out dy));
             if (player_move (dx, dy)) {
                 move_robots ();
                 return true;
+            } else {
+                return false;
             }
-            return false;
         case PlayerCommand.SAFE_TELEPORT:
             if (safe_teleport ()) {
                 move_robots ();
@@ -745,9 +754,8 @@ public class Game {
         case PlayerCommand.RANDOM_TELEPORT:
             if (random_teleport ()) {
                 move_robots ();
-                return true;
             }
-            return false;
+            return true;
         case PlayerCommand.WAIT:
             state = State.WAITING;
             return true;
@@ -757,15 +765,3 @@ public class Game {
     }
 }
 
-/**
- * Displays a modal dialog box with a given message
- **/
-void message_box (string msg) {
-    var box = new Gtk.MessageDialog (window,
-                                     Gtk.DialogFlags.MODAL,
-                                     Gtk.MessageType.INFO,
-                                     Gtk.ButtonsType.OK,
-                                     "%s", msg);
-    box.run ();
-    box.destroy ();
-}
diff --git a/src/robots.vala b/src/robots.vala
index 850dcc0..cf6146f 100644
--- a/src/robots.vala
+++ b/src/robots.vala
@@ -151,21 +151,15 @@ public class RobotsWindow : ApplicationWindow {
     }
 
     private void random_teleport_cb () {
-        if (game.player_command (PlayerCommand.RANDOM_TELEPORT)) {
-            game_area.queue_draw ();
-        }
+        game_area.player_command (PlayerCommand.RANDOM_TELEPORT);
     }
 
     private void safe_teleport_cb () {
-        if (game.player_command (PlayerCommand.SAFE_TELEPORT)) {
-            game_area.queue_draw ();
-        }
+        game_area.player_command (PlayerCommand.SAFE_TELEPORT);
     }
 
     private void wait_cb () {
-        if (game.player_command (PlayerCommand.WAIT)) {
-            game_area.queue_draw ();
-        }
+        game_area.player_command (PlayerCommand.WAIT);
     }
 
     private bool keyboard_cb (uint keyval, uint keycode, Gdk.ModifierType state) {
@@ -181,9 +175,7 @@ public class RobotsWindow : ApplicationWindow {
 
         for (var i = 0; i < control_keys.length; ++i) {
             if (pressed == ((char)control_keys[i]).toupper ()) {
-                if (game.player_command ((PlayerCommand)i)) {
-                    game_area.queue_draw ();
-                }
+                game_area.player_command ((PlayerCommand)i);
                 return true;
             }
         }


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