[lightsoff/wip/gtkview] Added basic mouse-playable version
- From: Robert Roth <robertroth src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lightsoff/wip/gtkview] Added basic mouse-playable version
- Date: Fri, 29 Jun 2018 20:27:13 +0000 (UTC)
commit 9246b114e99d87a4235466b4677b66193466f32b
Author: Robert Roth <robert roth off gmail com>
Date: Fri Jun 29 23:26:50 2018 +0300
Added basic mouse-playable version
data/lightsoff.ui | 2 +-
src/game-view-gtk.vala | 143 ++++++++++++++++++++++++++++++++++++++++++++++
src/lightsoff-window.vala | 22 +++++--
src/meson.build | 1 +
4 files changed, 163 insertions(+), 5 deletions(-)
---
diff --git a/data/lightsoff.ui b/data/lightsoff.ui
index dab0e53..0185eea 100644
--- a/data/lightsoff.ui
+++ b/data/lightsoff.ui
@@ -2,7 +2,7 @@
<interface>
<requires lib="gtk+" version="3.12"/>
<template class="LightsoffWindow" parent="GtkApplicationWindow">
- <property name="resizable">False</property>
+ <property name="resizable">True</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="visible">True</property>
diff --git a/src/game-view-gtk.vala b/src/game-view-gtk.vala
new file mode 100644
index 0000000..b372320
--- /dev/null
+++ b/src/game-view-gtk.vala
@@ -0,0 +1,143 @@
+public class GtkGameView : Gtk.Grid, GameView {
+
+ private Gtk.ToggleButton[,] lights;
+ private new const int SIZE = 5;
+ private PuzzleGenerator puzzle_generator;
+ private int current_level;
+ private int moves;
+
+ public void swap_board (int direction)
+ {
+ current_level += direction;
+ load_level (current_level);
+ }
+ public void hide_cursor ()
+ {
+ }
+ public void activate_cursor ()
+ {
+ }
+ public void move_cursor (int x, int y)
+ {
+ }
+ public void reset_game ()
+ {
+
+
+ }
+
+ public GtkGameView (int level)
+ {
+ puzzle_generator = new PuzzleGenerator (SIZE);
+ /* Clear level */
+ current_level = level;
+ lights = new Gtk.ToggleButton [SIZE, SIZE];
+ for (var x = 0; x < SIZE; x++)
+ for (var y = 0; y < SIZE; y++)
+ {
+ lights[x, y] = new Gtk.ToggleButton ();
+ lights[x, y].show ();
+ lights[x, y].toggled.connect (light_toggled_cb);
+ attach (lights[x, y], x, y, 1, 1);
+ }
+
+ set_size_request (SIZE * 64, SIZE * 64);
+ row_homogeneous = true;
+ column_homogeneous = true;
+ load_level (current_level);
+ }
+
+ private void find_light (Gtk.ToggleButton light, out int x, out int y)
+ {
+ x = y = 0;
+ for (x = 0; x < SIZE; x++)
+ for (y = 0; y < SIZE; y++)
+ if (lights[x, y] == light)
+ return;
+ }
+
+ private bool is_completed ()
+ {
+ var cleared = true;
+ for (var x = 0; x < SIZE; x++)
+ for (var y = 0; y < SIZE; y++)
+ if (lights[x, y].active)
+ cleared = false;
+
+ return cleared;
+ }
+
+ public void light_toggled_cb (Gtk.ToggleButton source)
+ {
+ int xl, yl;
+ find_light (source, out xl, out yl);
+
+ toggle_light (xl, yl, true);
+ moves_changed (++moves);
+ if (is_completed ()) {
+ load_level (++current_level);
+ }
+ }
+ // Pseudorandomly generates and sets the state of each light based on
+ // a level number; hopefully this is stable between machines, but that
+ // depends on GLib's PRNG stability. Also, provides some semblance of
+ // symmetry for some levels.
+
+ // Toggle a light and those in each cardinal direction around it.
+ private void toggle_light (int x, int y, bool clicked = false)
+ {
+ for (var xi = 0; xi < SIZE; xi++)
+ for (var yi = 0; yi < SIZE; yi++)
+ lights[xi, yi].toggled.disconnect (light_toggled_cb);
+
+ if (x>= SIZE || y >= SIZE || x < 0 || y < 0 )
+ return;
+ if ((int) x + 1 < SIZE)
+ lights[(int) x + 1, (int) y].set_active (!lights[(int) x + 1, (int) y].get_active ());
+ if ((int) x - 1 >= 0)
+ lights[(int) x - 1, (int) y].set_active (!lights[(int) x - 1, (int) y].get_active ());
+ if ((int) y + 1 < SIZE)
+ lights[(int) x, (int) y + 1].set_active (!lights[(int) x, (int) y + 1].get_active ());
+ if ((int) y - 1 >= 0)
+ lights[(int) x, (int) y - 1].set_active (!lights[(int) x, (int) y - 1].get_active ());
+
+ if (!clicked)
+ lights[(int) x, (int) y].set_active (!lights[(int) x, (int) y ].get_active ());
+
+ for (var xi = 0; xi < SIZE; xi++)
+ for (var yi = 0; yi < SIZE; yi++)
+ lights[xi, yi].toggled.connect (light_toggled_cb);
+ }
+
+ public void load_level (int level)
+ {
+ moves = 0;
+ moves_changed (moves);
+ level_changed (level);
+ /* We *must* not have level < 1, as the following assumes a nonzero, nonnegative number */
+ if (level < 1)
+ level = 1;
+
+ for (var xi = 0; xi < SIZE; xi++)
+ for (var yi = 0; yi < SIZE; yi++)
+ lights[xi, yi].toggled.disconnect (light_toggled_cb);
+
+ /* Clear level */
+ for (var x = 0; x < SIZE; x++)
+ for (var y = 0; y < SIZE; y++)
+ lights[x, y].active = false;
+
+ /* Use the same pseudo-random levels */
+ Random.set_seed (level);
+
+ /* Levels require more and more clicks to make */
+ var solution_length = (int) Math.floor (2 * Math.log (level) + 1);
+
+ /* Do the moves the player needs to */
+ var sol = puzzle_generator.minimal_solution (solution_length);
+ for (var x = 0; x < SIZE; x++)
+ for (var y = 0; y < SIZE; y++)
+ if (sol[x, y])
+ toggle_light (x, y);
+ }
+}
diff --git a/src/lightsoff-window.vala b/src/lightsoff-window.vala
index 3204364..a392435 100644
--- a/src/lightsoff-window.vala
+++ b/src/lightsoff-window.vala
@@ -28,12 +28,12 @@ public class LightsoffWindow : ApplicationWindow
{ "next-level", next_level_cb }
};
- public Gtk.Widget build_game_container (int level, out GameView out_game_view)
+ public Gtk.Widget build_clutter_game_container (int level, out GameView out_game_view)
{
var clutter_embed = new GtkClutter.Embed ();
clutter_embed.show ();
var stage = (Clutter.Stage) clutter_embed.get_stage ();
- stage.key_release_event.connect (key_release_event_cb);
+ stage.key_release_event.connect (key_release_clutter_event_cb);
stage.background_color = Clutter.Color.from_string ("#000000");
ClutterGameView clutter_game_view = new ClutterGameView (level);
@@ -47,6 +47,20 @@ public class LightsoffWindow : ApplicationWindow
return clutter_embed;
}
+ public Gtk.Widget build_gtk_game_container (int level, out GameView out_game_view)
+ {
+ var aspect_frame = new Gtk.AspectFrame (null, 0.5f, 0.5f, 1.0f, false);
+ aspect_frame.show ();
+
+ GtkGameView gtk_game_view = new GtkGameView (level);
+ gtk_game_view.show ();
+
+ aspect_frame.add (gtk_game_view);
+
+ out_game_view = gtk_game_view;
+ return aspect_frame;
+ }
+
public LightsoffWindow ()
{
settings = new GLib.Settings ("org.gnome.lightsoff");
@@ -57,7 +71,7 @@ public class LightsoffWindow : ApplicationWindow
int level = settings.get_int ("level");
level_changed_cb (level);
- this.add (build_game_container (level, out game_view));
+ this.add (build_gtk_game_container (level, out game_view));
game_view.level_changed.connect (level_changed_cb);
game_view.moves_changed.connect (update_subtitle);
@@ -99,7 +113,7 @@ public class LightsoffWindow : ApplicationWindow
settings.set_int ("level", level);
}
- private bool key_release_event_cb (Clutter.Actor actor, Clutter.KeyEvent event)
+ private bool key_release_clutter_event_cb (Clutter.Actor actor, Clutter.KeyEvent event)
{
switch (event.keyval)
{
diff --git a/src/meson.build b/src/meson.build
index 33b94fd..e711372 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -5,6 +5,7 @@ lightsoff_vala_sources = [
'puzzle-generator.vala',
'game-view.vala',
'game-view-clutter.vala',
+ 'game-view-gtk.vala',
]
lightsoff_resources_file = files('lightsoff.gresource.xml')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]