Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/implodegame.py
diff options
context:
space:
mode:
Diffstat (limited to 'implodegame.py')
-rw-r--r--implodegame.py159
1 files changed, 38 insertions, 121 deletions
diff --git a/implodegame.py b/implodegame.py
index 17496f0..fe4229b 100644
--- a/implodegame.py
+++ b/implodegame.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright (C) 2007, Joseph C. Lee
+# Copyright (C) 2007-2009, Joseph C. Lee
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -21,31 +21,13 @@ _logger = logging.getLogger('implode-activity.implodegame')
from gettext import gettext as _
-import gobject
import gtk
import random
-import time
import board
import boardgen
import gridwidget
-# A list of the animation stages in order, along with time on-screen (in
-# seconds per tick).
-_ANIM_TIME_LIST = (
- (gridwidget.ANIMATE_SHRINK, 0.1),
- (gridwidget.ANIMATE_FALL, 0.1),
- (gridwidget.ANIMATE_SLIDE, 0.1),
- (gridwidget.ANIMATE_ZOOM, 0.1),
-)
-_ANIM_MODES = [x[0] for x in _ANIM_TIME_LIST]
-_ANIM_TIMES = dict(_ANIM_TIME_LIST)
-
-# Win animation time on screen (in seconds per tick).
-_WIN_ANIM_TIME = 0.04
-
-# Animation timer interval (in msec)
-_TIMER_INTERVAL = 20
class ImplodeGame(gtk.EventBox):
"""Gtk widget for playing the implode game."""
@@ -53,12 +35,11 @@ class ImplodeGame(gtk.EventBox):
def __init__(self, *args, **kwargs):
super(ImplodeGame, self).__init__(*args, **kwargs)
self._animate = True
- self._animation_mode = gridwidget.ANIMATE_NONE
- self._start_time = 0.0
+ self._current_anim = None
self._board = None
- self._undoStack = []
- self._redoStack = []
+ self._undo_stack = []
+ self._redo_stack = []
self._random = random.Random()
#self._random.seed(0)
@@ -68,9 +49,6 @@ class ImplodeGame(gtk.EventBox):
self._seed = 0
self._fragmentation = 0
- self._animating = False
- self._end_anim_func = None
-
self._grid = gridwidget.GridWidget()
self._grid.connect('piece-selected', self._piece_selected_cb)
self._grid.connect('undo-key-pressed', self._undo_key_pressed_cb)
@@ -86,7 +64,7 @@ class ImplodeGame(gtk.EventBox):
def new_game(self):
_logger.debug('New game.')
- self._finish_animation()
+ self._stop_animation()
self._seed = self._random.randint(0, 99999)
size_frag_dict = {
0: (( 8, 6), 0),
@@ -97,18 +75,18 @@ class ImplodeGame(gtk.EventBox):
self._reset_board()
def replay_game(self):
- self._finish_animation()
+ self._stop_animation()
_logger.debug('Replay game.')
self._reset_board()
def undo(self):
_logger.debug('Undo.')
- self._finish_animation()
- if len(self._undoStack) == 0:
+ self._stop_animation()
+ if len(self._undo_stack) == 0:
return
- self._redoStack.append(self._board)
- self._board = self._undoStack.pop()
+ self._redo_stack.append(self._board)
+ self._board = self._undo_stack.pop()
# Force board refresh.
self._grid.set_board(self._board)
@@ -116,12 +94,12 @@ class ImplodeGame(gtk.EventBox):
def redo(self):
_logger.debug('Redo.')
- self._finish_animation()
- if len(self._redoStack) == 0:
+ self._stop_animation()
+ if len(self._redo_stack) == 0:
return
- self._undoStack.append(self._board)
- self._board = self._redoStack.pop()
+ self._undo_stack.append(self._board)
+ self._board = self._redo_stack.pop()
# Force board refresh.
self._grid.set_board(self._board)
@@ -144,15 +122,15 @@ class ImplodeGame(gtk.EventBox):
'size' : self._size,
'fragmentation' : self._fragmentation,
'board' : encode_board(self._board),
- 'undo_stack': [encode_board(b) for b in self._undoStack],
- 'redo_stack': [encode_board(b) for b in self._redoStack],
+ 'undo_stack': [encode_board(b) for b in self._undo_stack],
+ 'redo_stack': [encode_board(b) for b in self._redo_stack],
'win_draw_flag': self._grid.get_win_draw_flag(),
'win_color': self._grid.get_win_color(),
}
def set_game_state(self, state):
# Sets the game state using a dictionary of atomic subobjects.
- self._finish_animation()
+ self._stop_animation()
def decode_board(state):
b = board.Board()
(w, h) = (state[0], state[1])
@@ -166,8 +144,8 @@ class ImplodeGame(gtk.EventBox):
self._size = state['size']
self._fragmentation = state['fragmentation']
self._board = decode_board(state['board'])
- self._undoStack = [decode_board(x) for x in state['undo_stack']]
- self._redoStack = [decode_board(x) for x in state['redo_stack']]
+ self._undo_stack = [decode_board(x) for x in state['undo_stack']]
+ self._redo_stack = [decode_board(x) for x in state['redo_stack']]
self._grid.set_board(self._board)
self._grid.set_win_state(state['win_draw_flag'], state['win_color'])
@@ -178,26 +156,19 @@ class ImplodeGame(gtk.EventBox):
max_size=self._size)
self._grid.set_board(self._board)
self._grid.set_win_draw_flag(False)
- self._undoStack = []
- self._redoStack = []
+ self._undo_stack = []
+ self._redo_stack = []
def _piece_selected_cb(self, widget, x, y):
# Handles piece selection.
- self._finish_animation()
+ self._stop_animation()
contiguous = self._board.get_contiguous(x, y)
if len(contiguous) >= 3:
self._contiguous = contiguous
- if not self._animate:
- self._remove_contiguous()
+ if self._animate:
+ self._current_anim = self._grid.start_removal_anim(self._remove_contiguous, contiguous)
else:
- self._start_time = time.time()
- self._animation_mode = 0
- self._grid.set_removal_block_set(contiguous)
- self._grid.set_animation_mode(_ANIM_MODES[0])
- self._grid.set_animation_percent(0.0)
- self._animating = True
- self._end_anim_func = self._end_removal_animation
- gobject.timeout_add(_TIMER_INTERVAL, self._removal_timer)
+ self._remove_contiguous()
def _undo_key_pressed_cb(self, widget, dummy):
self.undo()
@@ -211,16 +182,13 @@ class ImplodeGame(gtk.EventBox):
if self._board.is_empty():
self.new_game()
- def _finish_animation(self):
- if self._end_anim_func:
- temp_animate = self._animate
- self._animate = False
- self._end_anim_func()
- self._animate = temp_animate
+ def _stop_animation(self):
+ if self._current_anim is not None:
+ self._current_anim.stop()
- def _remove_contiguous(self):
- self._redoStack = []
- self._undoStack.append(self._board.clone())
+ def _remove_contiguous(self, anim_stopped=False):
+ self._redo_stack = []
+ self._undo_stack.append(self._board.clone())
self._board.clear_pieces(self._contiguous)
self._board.drop_pieces()
self._board.remove_empty_columns()
@@ -229,71 +197,20 @@ class ImplodeGame(gtk.EventBox):
self._grid.set_board(self._board)
if self._board.is_empty():
- if not self._animate:
- self._init_win_state()
+ if self._animate and not anim_stopped:
+ self._current_anim = self._grid.start_win_anim(self._init_win)
else:
- self._start_time = time.time()
- self._grid.set_animation_mode(gridwidget.ANIMATE_WIN)
- self._grid.set_animation_percent(0.0)
- self._animating = True
- self._end_anim_func = self._end_win_animation
- gobject.timeout_add(_TIMER_INTERVAL, self._win_timer)
+ self._init_win()
else:
contiguous = self._board.get_all_contiguous()
if len(contiguous) == 0:
- self._init_lose_state()
+ self._init_lose()
- def _init_win_state(self):
+ def _init_win(self, anim_stopped=False):
self._grid.set_win_draw_flag(True)
# Clear the undo stack so that the undo/redo buttons do nothing after
# winning.
- self._undoStack = []
+ self._undo_stack = []
- def _init_lose_state(self):
+ def _init_lose(self):
pass
-
- def _win_timer(self):
- if not self._animating:
- return False
- delta = time.time() - self._start_time
- total = _WIN_ANIM_TIME * self._grid.get_animation_length()
- if total > 0:
- percent = float(delta) / total
- if percent < 1.0:
- self._grid.set_animation_percent(percent)
- return True
- self._end_win_animation()
- return False
-
- def _end_win_animation(self):
- self._animating = False
- self._end_anim_func = None
- self._grid.set_animation_mode(gridwidget.ANIMATE_NONE)
- self._init_win_state()
-
- def _removal_timer(self):
- if not self._animating:
- return False
- delta = time.time() - self._start_time
- total = (_ANIM_TIMES[_ANIM_MODES[self._animation_mode]]
- * self._grid.get_animation_length())
- if total > 0:
- percent = float(delta) / total
- if percent < 1.0:
- self._grid.set_animation_percent(percent)
- return True
- self._animation_mode += 1
- if self._animation_mode >= len(_ANIM_MODES):
- self._end_removal_animation()
- return False
- else:
- self._grid.set_animation_mode(_ANIM_MODES[self._animation_mode])
- self._grid.set_animation_percent(0.0)
- self._start_time = time.time()
- return True
-
- def _end_removal_animation(self):
- self._animating = False
- self._end_anim_func = None
- self._grid.set_animation_mode(gridwidget.ANIMATE_NONE)
- self._remove_contiguous()