[gnome-games/glines-vala] swell-foop: Make the game playable by keyboard
- From: Thomas Hindoe Paaboel Andersen <thomashpa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/glines-vala] swell-foop: Make the game playable by keyboard
- Date: Sat, 14 Jul 2012 23:30:16 +0000 (UTC)
commit f190f9b1c7010046d6e14243a2e9efe056763637
Author: Daniel Buch <boogiewasthere gmail com>
Date: Sun Jul 15 01:01:13 2012 +0200
swell-foop: Make the game playable by keyboard
To handle the mixed mouse/keyboard highlighting a field is added to hold the highlighted tile.
The svg for the cursor actor is copied from lightsoff.
swell-foop/data/themes/colors/Makefile.am | 6 +-
swell-foop/data/themes/colors/highlight.svg | 99 ++++++++++++++++++
swell-foop/data/themes/shapesandcolors/Makefile.am | 6 +-
.../data/themes/shapesandcolors/highlight.svg | 99 ++++++++++++++++++
swell-foop/src/game-view.vala | 108 ++++++++++++++++++--
swell-foop/src/swell-foop.vala | 35 ++++++-
6 files changed, 339 insertions(+), 14 deletions(-)
---
diff --git a/swell-foop/data/themes/colors/Makefile.am b/swell-foop/data/themes/colors/Makefile.am
index c6532ed..7b046c0 100644
--- a/swell-foop/data/themes/colors/Makefile.am
+++ b/swell-foop/data/themes/colors/Makefile.am
@@ -4,13 +4,15 @@ theme_DATA = \
blue.svg \
green.svg \
red.svg \
- yellow.svg
+ yellow.svg \
+ highlight.svg
EXTRA_DIST = \
bkg.svg \
blue.svg \
green.svg \
red.svg \
- yellow.svg
+ yellow.svg \
+ highlight.svg
-include $(top_srcdir)/git.mk
diff --git a/swell-foop/data/themes/colors/highlight.svg b/swell-foop/data/themes/colors/highlight.svg
new file mode 100644
index 0000000..a830854
--- /dev/null
+++ b/swell-foop/data/themes/colors/highlight.svg
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/";
+ xmlns:cc="http://creativecommons.org/ns#";
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+ xmlns:svg="http://www.w3.org/2000/svg";
+ xmlns="http://www.w3.org/2000/svg";
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+ width="75"
+ height="75"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="highlight.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3179">
+ <stop
+ style="stop-color:#35669b;stop-opacity:0.96078432;"
+ offset="0"
+ id="stop3181" />
+ <stop
+ style="stop-color:#5e92c8;stop-opacity:0.96078432;"
+ offset="1"
+ id="stop3183" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <filter
+ inkscape:collect="always"
+ id="filter3393"
+ x="-0.43563023"
+ width="1.8712605"
+ y="-0.43563023"
+ height="1.8712605">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="5.5324044"
+ id="feGaussianBlur3395" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8.76"
+ inkscape:cx="17.522831"
+ inkscape:cy="37.5"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1438"
+ inkscape:window-height="882"
+ inkscape:window-x="0"
+ inkscape:window-y="16" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-164.71428,-194.21933)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.64102568;fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1;filter:url(#filter3393)"
+ id="path3183"
+ sodipodi:cx="22.888128"
+ sodipodi:cy="25.285389"
+ sodipodi:rx="15.239726"
+ sodipodi:ry="15.239726"
+ d="M 38.127854,25.285389 A 15.239726,15.239726 0 1 1 7.6484022,25.285389 A 15.239726,15.239726 0 1 1 38.127854,25.285389 z"
+ transform="matrix(1.247191,0,0,1.247191,173.66841,200.18362)" />
+ </g>
+</svg>
diff --git a/swell-foop/data/themes/shapesandcolors/Makefile.am b/swell-foop/data/themes/shapesandcolors/Makefile.am
index 96c42f8..4e80ee4 100644
--- a/swell-foop/data/themes/shapesandcolors/Makefile.am
+++ b/swell-foop/data/themes/shapesandcolors/Makefile.am
@@ -4,13 +4,15 @@ theme_DATA = \
blue.svg \
green.svg \
red.svg \
- yellow.svg
+ yellow.svg \
+ highlight.svg
EXTRA_DIST = \
bkg.svg \
blue.svg \
green.svg \
red.svg \
- yellow.svg
+ yellow.svg \
+ highlight.svg
-include $(top_srcdir)/git.mk
diff --git a/swell-foop/data/themes/shapesandcolors/highlight.svg b/swell-foop/data/themes/shapesandcolors/highlight.svg
new file mode 100644
index 0000000..a830854
--- /dev/null
+++ b/swell-foop/data/themes/shapesandcolors/highlight.svg
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/";
+ xmlns:cc="http://creativecommons.org/ns#";
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+ xmlns:svg="http://www.w3.org/2000/svg";
+ xmlns="http://www.w3.org/2000/svg";
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+ width="75"
+ height="75"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="highlight.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3179">
+ <stop
+ style="stop-color:#35669b;stop-opacity:0.96078432;"
+ offset="0"
+ id="stop3181" />
+ <stop
+ style="stop-color:#5e92c8;stop-opacity:0.96078432;"
+ offset="1"
+ id="stop3183" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <filter
+ inkscape:collect="always"
+ id="filter3393"
+ x="-0.43563023"
+ width="1.8712605"
+ y="-0.43563023"
+ height="1.8712605">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="5.5324044"
+ id="feGaussianBlur3395" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#000000"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="1"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8.76"
+ inkscape:cx="17.522831"
+ inkscape:cy="37.5"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1438"
+ inkscape:window-height="882"
+ inkscape:window-x="0"
+ inkscape:window-y="16" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-164.71428,-194.21933)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.64102568;fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1;filter:url(#filter3393)"
+ id="path3183"
+ sodipodi:cx="22.888128"
+ sodipodi:cy="25.285389"
+ sodipodi:rx="15.239726"
+ sodipodi:ry="15.239726"
+ d="M 38.127854,25.285389 A 15.239726,15.239726 0 1 1 7.6484022,25.285389 A 15.239726,15.239726 0 1 1 38.127854,25.285389 z"
+ transform="matrix(1.247191,0,0,1.247191,173.66841,200.18362)" />
+ </g>
+</svg>
diff --git a/swell-foop/src/game-view.vala b/swell-foop/src/game-view.vala
index 3c87964..b6e6e50 100644
--- a/swell-foop/src/game-view.vala
+++ b/swell-foop/src/game-view.vala
@@ -4,8 +4,27 @@
* with the model class by composite relation and with the control layer by means of signals and
* events.
*/
+
public class GameView : Clutter.Group
{
+ private TileActor highlighted = null;
+
+ private CursorActor cursor;
+ private bool cursor_active = false;
+ private int _cursor_x;
+ public int cursor_x
+ {
+ get { return this._cursor_x; }
+ set { this._cursor_x = value.clamp(0, game.columns - 1); }
+ }
+
+ private int _cursor_y;
+ public int cursor_y
+ {
+ get { return this._cursor_y; }
+ set { this._cursor_y = value.clamp(0, game.rows - 1); }
+ }
+
/* A 2D array holding all tiles */
private TileActor[,] tiles;
@@ -81,6 +100,8 @@ public class GameView : Clutter.Group
tile.destroy ();
}
}
+
+ cursor.destroy ();
}
private void place_tiles ()
@@ -122,6 +143,10 @@ public class GameView : Clutter.Group
game_actors.add_actor (tile);
}
}
+
+ cursor = new CursorActor (theme.cursor, tile_size);
+ game_actors.add_actor (cursor);
+ cursor.hide ();
}
public bool is_zealous;
@@ -137,6 +162,9 @@ public class GameView : Clutter.Group
t.hide ();
add_actor (t);
}
+ theme.cursor.hide ();
+ add_actor (theme.cursor);
+
theme = new Theme ("shapesandcolors");
themes.insert ("shapesandcolors", theme);
foreach (var t in theme.textures)
@@ -144,6 +172,8 @@ public class GameView : Clutter.Group
t.hide ();
add_actor (t);
}
+ theme.cursor.hide ();
+ add_actor (theme.cursor);
}
/* When a tile in the model layer is closed, play an animation at the view layer */
@@ -163,14 +193,27 @@ public class GameView : Clutter.Group
tile.animate_to (new_xx, new_yy, is_zealous);
}
+ /* Sets the opacity for all tiles connected to the actor */
+ private void opacity_for_connected_tiles (TileActor? actor, int opacity)
+ {
+ if (actor == null)
+ return;
+
+ var connected_tiles = game.connected_tiles (actor.tile);
+ foreach (var l in connected_tiles)
+ tiles[l.grid_x, l.grid_y].opacity = opacity;
+ }
+
/* When the mouse enters a tile, bright up the connected tiles */
private bool tile_entered_cb (Clutter.Actor actor, Clutter.CrossingEvent event)
{
+ if (cursor_active)
+ return false;
+
var tile = (TileActor) actor;
- var connected_tiles = game.connected_tiles (tile.tile);
- foreach (var l in connected_tiles)
- tiles[l.grid_x, l.grid_y].opacity = 255;
+ opacity_for_connected_tiles (tile, 255);
+ highlighted = tile;
return false;
}
@@ -178,11 +221,12 @@ public class GameView : Clutter.Group
/* When the mouse leaves a tile, lower the brightness of the connected tiles */
private bool tile_left_cb (Clutter.Actor actor, Clutter.CrossingEvent event)
{
+ if (cursor_active)
+ return false;
+
var tile = (TileActor) actor;
- var connected_tiles = game.connected_tiles (tile.tile);
- foreach (var l in connected_tiles)
- tiles[l.grid_x, l.grid_y].opacity = 180;
+ opacity_for_connected_tiles (tile, 180);
return false;
}
@@ -192,6 +236,18 @@ public class GameView : Clutter.Group
{
var tile = (TileActor) actor;
+ opacity_for_connected_tiles (highlighted, 180);
+
+ if (cursor_active)
+ {
+ cursor_active = false;
+ cursor.hide ();
+ }
+
+ /* Move the cursor to where the mouse was clicked. Expected for mixed mouse/keyboard use */
+ cursor_x = tile.tile.grid_x;
+ cursor_y = tile.tile.grid_y;
+
game.remove_connected_tiles (tile.tile);
return false;
@@ -208,6 +264,30 @@ public class GameView : Clutter.Group
return false;
}
+ /* Move Keyboard cursor */
+ public void cursor_move (int x, int y)
+ {
+ cursor_active = true;
+
+ opacity_for_connected_tiles (highlighted, 180);
+ cursor_x += x;
+ cursor_y += y;
+ highlighted = tiles[cursor_x, cursor_y];
+ opacity_for_connected_tiles (highlighted, 255);
+
+ float xx, yy;
+ xx = cursor_x * tile_size + tile_size / 2;
+ yy = (game.rows - 1 - cursor_y) * tile_size + tile_size / 2;
+ cursor.set_position (xx, yy);
+ cursor.show ();
+ }
+
+ /* Keyboard Cursor Click */
+ public void cursor_click ()
+ {
+ game.remove_connected_tiles (tiles[cursor_x, cursor_y].tile);
+ }
+
/* Show flying score animation after each tile-removing click */
public void update_score_cb (int points_awarded)
{
@@ -230,11 +310,12 @@ public class GameView : Clutter.Group
/**
* This class holds the textures for a specific theme. These textures are used for creating light
- * actors.
+ * actors and cursor actor.
*/
public class Theme
{
public Clutter.Texture[] textures;
+ public Clutter.Texture cursor;
public Theme (string name)
{
@@ -246,6 +327,8 @@ public class Theme
{
for (int i = 0; i < 4; i++)
textures[i] = new Clutter.Texture.from_file (Path.build_filename (DATADIR, "themes", name, colors[i] + ".svg"));
+
+ cursor = new Clutter.Texture.from_file (Path.build_filename (DATADIR, "themes", name, "highlight.svg"));
}
catch (Clutter.TextureError e)
{
@@ -292,6 +375,17 @@ private class TileActor : Clutter.Clone
}
}
+public class CursorActor : Clutter.Clone
+{
+ public CursorActor (Clutter.Texture texture, int size)
+ {
+ source = texture;
+ opacity = 180;
+ set_size (size, size);
+ set_anchor_point (size / 2, size / 2);
+ }
+}
+
/**
* This class defines the view of a score. All clutter related stuff goes here
*/
diff --git a/swell-foop/src/swell-foop.vala b/swell-foop/src/swell-foop.vala
index efb0207..bb8261f 100644
--- a/swell-foop/src/swell-foop.vala
+++ b/swell-foop/src/swell-foop.vala
@@ -93,7 +93,6 @@ public class SwellFoop : Gtk.Application
var ui_description =
"<ui>" +
" <toolbar name='Toolbar'>" +
- " <toolitem action='NewGame'/>" +
" </toolbar>" +
"</ui>";
ui_manager.add_ui_from_string (ui_description, -1);
@@ -157,14 +156,12 @@ public class SwellFoop : Gtk.Application
view.is_zealous = settings.get_boolean ("zealous");
view.game = game;
stage.add_actor (view);
-
/* Request an appropriate size for the game view */
stage.set_size (view.width, view.height);
clutter_embed.set_size_request ((int) stage.width, (int) stage.height);
/* When the mouse leaves the window we need to update the view */
clutter_embed.leave_notify_event.connect (view.board_left_cb);
-
high_scores = new GnomeGamesSupport.Scores ("swell-foop",
new GnomeGamesSupport.ScoresCategory[0],
null, null, 0,
@@ -173,6 +170,38 @@ public class SwellFoop : Gtk.Application
high_scores.add_category ("small", _("Small"));
high_scores.add_category ("normal", _("Normal"));
high_scores.add_category ("large", _("Large"));
+
+ stage.key_release_event.connect (key_release_event_cb);
+ }
+
+ private bool key_release_event_cb (Clutter.Actor actor, Clutter.KeyEvent event)
+ {
+ switch (event.keyval)
+ {
+ case Clutter.Key.F2:
+ new_game ();
+ break;
+ case Clutter.Key.Up:
+ view.cursor_move (0, 1);
+ break;
+ case Clutter.Key.Down:
+ view.cursor_move (0, -1);
+ break;
+ case Clutter.Key.Left:
+ view.cursor_move (-1, 0);
+ break;
+ case Clutter.Key.Right:
+ view.cursor_move (1, 0);
+ break;
+ case Clutter.Key.space:
+ case Clutter.Key.Return:
+ view.cursor_click ();
+ break;
+ default:
+ break;
+ }
+
+ return false;
}
private Size get_size ()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]