def action(stage): contiguous = stage.board.get_contiguous(x, y) removal_drawer = stage.preview.removal_drawer stage.preview.set_drawer(removal_drawer) removal_drawer.init(stage.board, contiguous) removal_drawer.set_anim_time(0.0) start_time = time.time() def update_func(start_time_ref=[start_time]): delta = time.time() - start_time_ref[0] length = removal_drawer.get_anim_length() if delta > length: if not removal_drawer.next_stage(): return False start_time_ref[0] = time.time() delta = 0.0 removal_drawer.set_anim_time(delta) return True def local_end_anim_func(anim_stopped): stage.preview.set_drawer(stage.preview.board_drawer) stage.undo_stack.append(stage.board) board = stage.board.clone() board.clear_pieces(contiguous) board.drop_pieces() board.remove_empty_columns() stage.set_board(board) if not anim_stopped: stage.next_action() stage.anim = Anim(update_func, local_end_anim_func) stage.anim.start()
def action(stage): # Caveat: This has the potential to get a little messed up if it is an # early action in a stage or if the screen changes size as the cursor # is moving... Best to keep a pause before it in the sequence. (old_x, old_y) = stage.preview.get_cursor_pos() (new_x, new_y) = coord_func(stage) delta_x = new_x - old_x delta_y = new_y - old_y dist = math.sqrt(delta_x * delta_x + delta_y * delta_y) move_time = dist * _MOUSE_SPEED start_time = time.time() def update_func(): delta = time.time() - start_time if delta >= move_time or move_time == 0.0: return False t = max(0.0, min(1.0, delta / move_time)) # Use the first half of cosine wave to ease in/out. w = 1.0 - (0.5 * math.cos(t * math.pi) + 0.5) inv_w = 1.0 - w move_x = old_x * inv_w + new_x * w move_y = old_y * inv_w + new_y * w stage.preview.set_cursor_pos(move_x, move_y) return True def end_anim_func(anim_stopped): if not anim_stopped: stage.next_action() stage.anim = Anim(update_func, end_anim_func) stage.anim.start()
def action(stage): start_time = time.time() def update_func(): delta = time.time() - start_time return delta < delay def end_anim_func(anim_stopped): if not anim_stopped: stage.next_action() stage.anim = Anim(update_func, end_anim_func) stage.anim.start()
def action(stage): start_time = time.time() stage.preview.set_click_visible(True) def update_func(): delta = time.time() - start_time return (delta < _CLICK_SPEED) def end_anim_func(anim_stopped): stage.preview.set_click_visible(False) if not anim_stopped: stage.next_action() stage.anim = Anim(update_func, end_anim_func) stage.anim.start()
def _init_lose(self): # If the player is stuck, wait a little while, then signal the activity # to display the stuck dialog. start_time = time.time() def update_func(): delta = time.time() - start_time return (delta <= _STUCK_DELAY) def end_anim_func(anim_stopped): if not anim_stopped: self.emit('show-stuck', 1) self._anim = Anim(update_func, end_anim_func) self._anim.start()
def get_win_anim(self, end_anim_func): self._set_current_drawer(self._win_drawer) self._win_drawer.init() length = self._win_drawer.get_anim_length() start_time = time.time() def update_func(): delta = time.time() - start_time self._win_drawer.set_anim_time(min(delta, length)) return (delta <= length) def local_end_anim_func(anim_stopped): self._win_drawer.set_anim_time(length) end_anim_func(anim_stopped) return Anim(update_func, local_end_anim_func)
def action(stage): win_drawer = stage.preview.win_drawer stage.preview.set_drawer(win_drawer) win_drawer.set_win_state(True, color) length = win_drawer.get_anim_length() start_time = time.time() def update_func(): delta = time.time() - start_time win_drawer.set_anim_time(min(delta, length)) return (delta <= length) def local_end_anim_func(anim_stopped): win_drawer.set_anim_time(length) if not anim_stopped: stage.next_action() stage.anim = Anim(update_func, local_end_anim_func) stage.anim.start()
def get_removal_anim(self, board, contiguous, end_anim_func): self._set_current_drawer(self._removal_drawer) self._removal_drawer.init(board, contiguous) self._removal_drawer.set_anim_time(0.0) start_time = time.time() def update_func(start_time_ref=[start_time]): delta = time.time() - start_time_ref[0] length = self._removal_drawer.get_anim_length() if delta > length: if not self._removal_drawer.next_stage(): return False start_time_ref[0] = time.time() delta = 0.0 self._removal_drawer.set_anim_time(delta) return True def local_end_anim_func(anim_stopped): self._set_current_drawer(self._board_drawer) end_anim_func(anim_stopped) return Anim(update_func, local_end_anim_func)
def undo_to_solvable_state(self): # Undoes the player's moves until the puzzle is in a solvable state. # # Actually, we undo moves until the player's moves so far match the # beginning of a list of moves known to solve the puzzle, as given by # the puzzle generator. Since each puzzle can potentially be solved # through many different sequences of moves, we will almost certainly # be undoing more moves than we need to. One possible improvement # would be to write a generic puzzle solver that can test some of the # player's later board states for solvability, so that we don't need to # undo as many moves. self._hide_stuck() self._stop_animation() if len(self._undo_stack) == 0: return start_time = time.time() def update_func(start_time_ref=[start_time]): delta = time.time() - start_time_ref[0] if delta > _UNDO_DELAY: self._undo_last_move() moves = self._get_moves_so_far() if moves == self._winning_moves[:len(moves)]: return False start_time_ref[0] = time.time() return True def end_anim_func(anim_stopped): moves = self._get_moves_so_far() while moves != self._winning_moves[:len(moves)]: self._undo_last_move() moves = self._get_moves_so_far() self._anim = Anim(update_func, end_anim_func) self._anim.start()