Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2014-06-03 16:27:53 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2014-06-16 15:26:37 (GMT)
commite7fcacc7e9c487915188da1b009505f07cc8e1b4 (patch)
tree9ea97e90555d9f094a340db930d5c26f74cd4d79
parentcdca918f56e4d8a10fa7337af0bf5ceb1a3e3b67 (diff)
Basic keyboard use works, save and restore game state
-rwxr-xr-xactivity.py18
-rw-r--r--game.py266
2 files changed, 120 insertions, 164 deletions
diff --git a/activity.py b/activity.py
index 984c437..f5ccd63 100755
--- a/activity.py
+++ b/activity.py
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
+import logging
+import json
+
from gi.repository import Gtk
from sugar3.activity import activity
@@ -19,9 +22,11 @@ class MazeActivity(activity.Activity):
activity.Activity.__init__(self, handle)
self.build_toolbar()
- self.game = game.MazeGame()
+ state = json.loads(self.metadata['state'])
+ self.game = game.MazeGame(state)
self.set_canvas(self.game)
self.game.show()
+ self.connect("key_press_event", self.game.key_press_cb)
"""
game_name = 'game'
@@ -108,3 +113,14 @@ class MazeActivity(activity.Activity):
def _harder_button_cb(self, button):
self.game.harder()
+
+ def write_file(self, file_path):
+ logging.debug('Saving the state of the game...')
+ data = {'seed': self.game.maze.seed,
+ 'width': self.game.maze.width,
+ 'height': self.game.maze.height, }
+ logging.debug('Saving data: %s', data)
+ self.metadata['state'] = json.dumps(data)
+
+ def read_file(self, file_path):
+ pass
diff --git a/game.py b/game.py
index ee2708b..44c9f66 100644
--- a/game.py
+++ b/game.py
@@ -25,10 +25,10 @@
import sys
import time
-import json
from math import pi
from gi.repository import Gdk
from gi.repository import Gtk
+from gi.repository import GObject
import logging
@@ -52,7 +52,7 @@ class MazeGame(Gtk.DrawingArea):
GOAL_COLOR = (0x00, 0xff, 0x00)
WIN_COLOR = (0xff, 0xff, 0x00)
- def __init__(self):
+ def __init__(self, state=None):
super(MazeGame, self).__init__()
# note what time it was when we first launched
self.game_start_time = time.time()
@@ -77,12 +77,13 @@ class MazeGame(Gtk.DrawingArea):
# start with a small maze using a seed that will be different
# each time you play
- data = {'seed': int(time.time()),
- 'width': int(9 * self.aspectRatio),
- 'height': 9}
+ if state is None:
+ state = {'seed': int(time.time()),
+ 'width': int(9 * self.aspectRatio),
+ 'height': 9}
- logging.debug('Starting the game with: %s', data)
- self.maze = Maze(**data)
+ logging.debug('Starting the game with: %s', state)
+ self.maze = Maze(**state)
self.reset()
self.frame = 0
@@ -91,27 +92,37 @@ class MazeGame(Gtk.DrawingArea):
# support arrow keys, game pad arrows and game pad buttons
# each set maps to a local player index and a direction
- # TODO
- """
self.arrowkeys = {
# real key: (localplayer index, ideal key)
- pygame.K_UP: (0, pygame.K_UP),
- pygame.K_DOWN: (0, pygame.K_DOWN),
- pygame.K_LEFT: (0, pygame.K_LEFT),
- pygame.K_RIGHT: (0, pygame.K_RIGHT),
- pygame.K_KP8: (1, pygame.K_UP),
- pygame.K_KP2: (1, pygame.K_DOWN),
- pygame.K_KP4: (1, pygame.K_LEFT),
- pygame.K_KP6: (1, pygame.K_RIGHT),
- pygame.K_KP9: (2, pygame.K_UP),
- pygame.K_KP3: (2, pygame.K_DOWN),
- pygame.K_KP7: (2, pygame.K_LEFT),
- pygame.K_KP1: (2, pygame.K_RIGHT)
+ 'Up': (0, 'Up'),
+ 'Down': (0, 'Down'),
+ 'Left': (0, 'Left'),
+ 'Right': (0, 'Right'),
+ 'KP_Up': (1, 'Up'),
+ 'KP_Down': (1, 'Down'),
+ 'KP_Left': (1, 'Left'),
+ 'KP_Right': (1, 'Right'),
+ 'KP_Page_Up': (2, 'Up'),
+ 'KP_Page_Down': (2, 'Down'),
+ 'KP_Home': (2, 'Left'),
+ 'KP_End': (2, 'Right')
}
- """
+
Gdk.Screen.get_default().connect('size-changed',
self.__configure_cb)
self.connect('draw', self.__draw_cb)
+ self.connect('event', self.__event_cb)
+
+ self.set_events(
+ Gdk.EventMask.EXPOSURE_MASK | Gdk.EventMask.BUTTON_PRESS_MASK |
+ Gdk.EventMask.BUTTON_RELEASE_MASK |
+ Gdk.EventMask.BUTTON_MOTION_MASK |
+ Gdk.EventMask.POINTER_MOTION_MASK |
+ Gdk.EventMask.POINTER_MOTION_HINT_MASK |
+ Gdk.EventMask.KEY_PRESS_MASK |
+ Gdk.EventMask.TOUCH_MASK)
+ self.set_can_focus(True)
+ self.grab_focus()
def __configure_cb(self, event):
''' Screen size has changed '''
@@ -182,12 +193,11 @@ class MazeGame(Gtk.DrawingArea):
self.outline = int(self.tileSize / 5)
def drawPoint(x, y):
- # logging.error('drawing %s %s = %s', x, y, self.maze.map[x][y])
rect = Rectangle(self.bounds.x + x * self.tileSize,
self.bounds.y + y * self.tileSize,
self.tileSize, self.tileSize)
tile = self.maze.map[x][y]
- background_color = (0xff, 0x00, 0xff)
+ background_color = self.EMPTY_COLOR
if tile == self.maze.EMPTY:
background_color = self.EMPTY_COLOR
elif tile == self.maze.SOLID:
@@ -197,13 +207,13 @@ class MazeGame(Gtk.DrawingArea):
ctx.save()
ctx.set_source_rgb(*background_color)
ctx.rectangle(*rect.get_bounds())
- logging.error('drawing %s %s', rect.get_bounds(), background_color)
ctx.fill()
if tile == self.maze.SEEN:
ctx.set_source_rgb(*self.TRAIL_COLOR)
radius = self.tileSize / 2 - self.outline
- ctx.arc(rect.x + radius, rect.y + radius, radius, 0, 2 * pi)
+ center = self.tileSize / 2
+ ctx.arc(rect.x + center, rect.y + center, radius, 0, 2 * pi)
ctx.fill()
ctx.restore()
@@ -269,42 +279,76 @@ class MazeGame(Gtk.DrawingArea):
"""Mark a single point that needs to be redrawn."""
self.dirtyPoints.append(pt)
+ def __event_cb(self, widget, event):
+ pass
+ """
+ if event.type in (
+ Gdk.EventType.TOUCH_BEGIN,
+ Gdk.EventType.TOUCH_CANCEL, Gdk.EventType.TOUCH_END,
+ Gdk.EventType.TOUCH_UPDATE, Gdk.EventType.BUTTON_PRESS,
+ Gdk.EventType.BUTTON_RELEASE, Gdk.EventType.MOTION_NOTIFY):
+ x = event.touch.x
+ y = event.touch.y
+ seq = str(event.touch.sequence)
+ updated_positions = False
+ # save a copy of the old touches
+ """
+
+ def key_press_cb(self, widget, event):
+ key_name = Gdk.keyval_name(event.keyval)
+ logging.error('key %s presssed', key_name)
+ if key_name in ('plus', 'equal'):
+ self.harder()
+ elif key_name == 'minus':
+ self.easier()
+ elif key_name in self.arrowkeys:
+ playernum, direction = self.arrowkeys[key_name]
+ player = self.localplayers[playernum]
+ player.hidden = False
+
+ if direction == 'Up':
+ player.direction = (0, -1)
+ elif direction == 'Down':
+ player.direction = (0, 1)
+ elif direction == 'Left':
+ player.direction = (-1, 0)
+ elif direction == 'Right':
+ player.direction = (1, 0)
+
+ if len(self.remoteplayers) > 0:
+ mesh.broadcast("move:%s,%d,%d,%d,%d" %
+ (player.uid,
+ player.position[0],
+ player.position[1],
+ player.direction[0],
+ player.direction[1]))
+ self.player_walk(player)
+
+ def player_walk(self, player):
+ oldposition = player.position
+ newposition = player.animate(self.maze)
+ if oldposition != newposition:
+ self.markPointDirty(oldposition)
+ self.markPointDirty(newposition)
+ if player in self.localplayers:
+ self.maze.map[player.previous[0]][player.previous[1]] = \
+ self.maze.SEEN
+ if self.maze.map[newposition[0]][newposition[1]] == \
+ self.maze.GOAL:
+ self.finish(player)
+ self.queue_draw()
+ GObject.timeout_add(200, self.player_walk, player)
+ """
+ finish_delay = min(2 * len(self.allplayers), 6)
+ if self.finish_time is not None and \
+ time.time() > self.finish_time + finish_delay:
+ self.harder()
+ """
+
def processEvent(self, event):
"""Process a single pygame event. This includes keystrokes
as well as multiplayer events from the mesh."""
- if event.type == pygame.QUIT:
- self.running = False
- elif event.type == pygame.KEYDOWN:
- if event.key in (pygame.K_PLUS, pygame.K_EQUALS):
- self.harder()
- elif event.key == pygame.K_MINUS:
- self.easier()
- elif event.key in self.arrowkeys:
- playernum, direction = self.arrowkeys[event.key]
- player = self.localplayers[playernum]
- player.hidden = False
-
- if direction == pygame.K_UP:
- player.direction = (0, -1)
- elif direction == pygame.K_DOWN:
- player.direction = (0, 1)
- elif direction == pygame.K_LEFT:
- player.direction = (-1, 0)
- elif direction == pygame.K_RIGHT:
- player.direction = (1, 0)
-
- if len(self.remoteplayers) > 0:
- mesh.broadcast("move:%s,%d,%d,%d,%d" %
- (player.uid,
- player.position[0],
- player.position[1],
- player.direction[0],
- player.direction[1]))
- elif event.type == pygame.KEYUP:
- pass
- elif event.type == pygame.MOUSEMOTION:
- pass
- elif event.type == pygame.MOUSEBUTTONDOWN:
+ if event.type == pygame.MOUSEBUTTONDOWN:
self.mouse_in_use = 1
self.prev_mouse_pos = pygame.mouse.get_pos()
@@ -414,35 +458,6 @@ class MazeGame(Gtk.DrawingArea):
event, sys.exc_info())
else:
logging.debug("Message from unknown buddy?")
-
- elif event.type == pygame.USEREVENT:
- # process our buttons
- if hasattr(event, 'action') and event.action == 'harder_button':
- self.harder()
- elif hasattr(event, 'action') and event.action == 'easier_button':
- self.easier()
- # process file save / restore events
- elif event.code == olpcgames.FILE_READ_REQUEST:
- logging.debug('Loading the state of the game...')
- state = json.loads(event.metadata['state'])
- logging.debug('Loaded data: %s', state)
- self.maze = Maze(**state)
- self.reset()
- return True
- elif event.code == olpcgames.FILE_WRITE_REQUEST:
- logging.debug('Saving the state of the game...')
- data = {'seed': self.maze.seed,
- 'width': self.maze.width,
- 'height': self.maze.height, }
- logging.debug('Saving data: %s', data)
- event.metadata['state'] = json.dumps(data)
- f = open(event.filename, 'w')
- try:
- f.write(str(time.time()))
- finally:
- f.close()
- logging.debug('Done saving.')
- return True
else:
logging.debug('Unknown event: %r', event)
@@ -518,39 +533,6 @@ class MazeGame(Gtk.DrawingArea):
# it was something I don't recognize...
logging.debug("Message from %s: %s", player.nick, message)
- def arrowKeysPressed(self):
- keys = pygame.key.get_pressed()
- for key in self.allkeys:
- if keys[key]:
- return True
- return False
-
- def run(self):
- """Run the main loop of the game."""
- # lets draw once before we enter the event loop
-
- clock = pygame.time.Clock()
- pygame.display.flip()
-
- while self.running:
- clock.tick(25)
-
- a, b, c, d = pygame.cursors.load_xbm('my_cursor.xbm',
- 'my_cursor_mask.xbm')
- pygame.mouse.set_cursor(a, b, c, d)
- self.frame += 1
- # process all queued events
- for event in pausescreen.get_events(sleep_timeout=30):
- self.processEvent(event)
-
- self.animate()
- self.draw()
-
- pygame.display.update()
- # don't animate faster than about 20 frames per second
- # this keeps the speed reasonable and limits cpu usage
- clock.tick(25)
-
def harder(self):
"""Make a new maze that is harder than the current one."""
# both width and height must be odd
@@ -585,50 +567,8 @@ class MazeGame(Gtk.DrawingArea):
(self.game_running_time(), self.maze.seed,
self.maze.width, self.maze.height))
- def animate(self):
- """Animate one frame of action."""
-
- for player in self.allplayers:
- oldposition = player.position
- newposition = player.animate(self.maze)
- if oldposition != newposition:
- self.markPointDirty(oldposition)
- self.markPointDirty(newposition)
- if player in self.localplayers:
- self.maze.map[player.previous[0]][player.previous[1]] = \
- self.maze.SEEN
- if self.maze.map[newposition[0]][newposition[1]] == \
- self.maze.GOAL:
- self.finish(player)
-
- finish_delay = min(2 * len(self.allplayers), 6)
- if self.finish_time is not None and \
- time.time() > self.finish_time + finish_delay:
- self.harder()
-
def finish(self, player):
self.finish_time = time.time()
player.elapsed = self.finish_time - self.level_start_time
if len(self.remoteplayers) > 0:
mesh.broadcast("finish:%s,%.2f" % (player.nick, player.elapsed))
-
-
-def main():
- """Run a game of Maze."""
- # canvas_size = 1024,768-75
- # screen = pygame.display.set_mode(canvas_size)
-
- # ask pygame how big the screen is, leaving a little room for the toolbar
- toolbarheight = 75
- pygame.display.init()
-# maxX,maxY = pygame.display.list_modes()[0]
- videoinfo = pygame.display.Info()
- width = videoinfo.current_w
- height = videoinfo.current_h - toolbarheight
- screen = pygame.display.set_mode((width, height))
-
- game = MazeGame(screen)
- game.run()
-
-if __name__ == '__main__':
- main()