예제 #1
0
    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()
예제 #2
0
    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()
예제 #3
0
    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()
예제 #4
0
    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()
예제 #5
0
    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()
예제 #6
0
    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()
예제 #7
0
    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()
예제 #8
0
    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)
예제 #9
0
    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()
예제 #10
0
    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)
예제 #11
0
파일: entity.py 프로젝트: Hatchet2k4/mannux
 def __init__(self, sprite):
     super(Entity, self).__init__()
     self.sprite = sprite
     self.sprite.isobs = False
     self.x__ = self.sprite.x
     self.y__ = self.sprite.y
     self.w = self.sprite.hotwidth
     self.h = self.sprite.hotheight
     self.state__ = None
     self.vx = 0
     self.vy = 0
     self.left_wall = 0
     self.right_wall = 0
     self.ceiling = 0
     self.floor = 0
     self.check_obs = True
     self.hurtable = False
     self.anim = Anim()
     self.state = self.null_state
     self.touchable = False
     self.destroy = False
     self.active = True
     self.platform = False
예제 #12
0
    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()
예제 #13
0
class ImplodeGame(Gtk.EventBox):
    """Gtk widget for playing the implode game."""

    __gsignals__ = {
        'show-stuck': (GObject.SignalFlags.RUN_LAST, None, (int, )),
    }

    def __init__(self, *args, **kwargs):
        super(ImplodeGame, self).__init__(*args, **kwargs)
        self._animate = True
        self._anim = None

        self._board = None
        # Undo and redo stacks are pairs of (board state, subsequent move).
        self._undo_stack = []
        self._redo_stack = []
        self._winning_moves = []

        self._random = random.Random()
        # self._random.seed(0)
        self._difficulty = 0
        self._size = (8, 6)
        self._seed = 0
        self._fragmentation = 0

        self._grid = gridwidget.GridWidget()
        self._grid.connect('piece-selected', self._piece_selected_cb)
        self._grid.connect('undo-key-pressed', self._undo_key_pressed_cb)
        self._grid.connect('redo-key-pressed', self._redo_key_pressed_cb)
        self._grid.connect('new-key-pressed', self._new_key_pressed_cb)
        self.add(self._grid)

        self.new_game()

    def grab_focus(self):
        self._grid.grab_focus()
        # self._grid.select_center_cell()

    def new_game(self):
        self._hide_stuck()
        self._stop_animation()
        self._seed = self._random.randint(0, 99999)
        size_frag_dict = {
            0: ((8, 6), 0),
            1: ((12, 10), 0),
            2: ((20, 15), 2),
        }
        (self._size, self._fragmentation) = size_frag_dict[self._difficulty]
        self._reset_board()

    def replay_game(self):
        self._hide_stuck()
        self._stop_animation()
        self._reset_board()

    def undo(self):
        self._hide_stuck()
        self._stop_animation()
        if len(self._undo_stack) == 0:
            return

        self._undo_last_move()

    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()

    def _get_moves_so_far(self):
        # Returns a list of the moves so far.
        return [move for (board, move) in self._undo_stack]

    def _undo_last_move(self):
        # Undoes the most recent move and stores the state on the undo stack.
        (board, move) = self._undo_stack.pop()
        self._redo_stack.append((self._board, move))
        self._board = board

        # Force board refresh.
        self._grid.set_board(self._board)
        self._grid.set_win_draw_flag(False)

    def redo(self):
        self._hide_stuck()
        self._stop_animation()
        if len(self._redo_stack) == 0:
            return

        (board, move) = self._redo_stack.pop()
        self._undo_stack.append((self._board, move))
        self._board = board

        # Force board refresh.
        self._grid.set_board(self._board)

        self._check_for_lose_state()

    def set_level(self, level):
        self._difficulty = level

    def get_game_state(self):
        # Returns a dictionary containing the game state, in atomic subobjects.
        def encode_board(board, move):
            # Encodes the given board and move to a state array.
            (w, h) = (board.width, board.height)
            data = []
            for i in range(h):
                for j in range(w):
                    data.append(board.get_value(j, i))
            if move is not None:
                return [w, h] + data + list(move)
            else:
                return [w, h] + data

        return {
            'difficulty': self._difficulty,
            'seed': self._seed,
            'size': self._size,
            'fragmentation': self._fragmentation,
            'board': encode_board(self._board, None),
            'undo_stack': [encode_board(b, m) for b, m in self._undo_stack],
            'redo_stack': [encode_board(b, m) for b, m in self._redo_stack],
            'win_draw_flag': self._grid.get_win_draw_flag(),
            'win_color': self._grid.get_win_color(),
            'winning_moves': self._winning_moves
        }

    def set_game_state(self, state):
        # Sets the game state using a dictionary of atomic subobjects.
        self._hide_stuck()
        self._stop_animation()

        def decode_board(state):
            # Decodes a board (and maybe an appended move) from the given state
            # array.
            b = board.Board()
            (w, h) = (state[0], state[1])
            data = state[2:]
            for i in range(h):
                for j in range(w):
                    b.set_value(j, i, data.pop(0))
            if len(data) == 2:
                # Return appended move.
                return b, tuple(data)
            else:
                return b, None

        self._difficulty = state['difficulty']
        self._seed = state['seed']
        self._size = state['size']
        self._fragmentation = state['fragmentation']
        (self._board, dummy) = decode_board(state['board'])
        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'])
        if 'winning_moves' in state:
            # Prior to version 8, we didn't store the list of winning moves.
            self._winning_moves = [tuple(x) for x in state['winning_moves']]
        else:
            self._winning_moves = []

        self._check_for_lose_state()

    def _reset_board(self):
        # Regenerates the board with the current seed.
        (self._board, self._winning_moves) = \
            boardgen.generate_board(
                seed=self._seed, fragmentation=self._fragmentation,
                max_size=self._size)
        self._grid.set_board(self._board)
        self._grid.set_win_draw_flag(False)
        self._undo_stack = []
        self._redo_stack = []

    def _piece_selected_cb(self, widget, x, y):
        # Handles piece selection.

        # We check contiguous before stopping the animation because we don't
        # want a click on the game board in a losing state to stop the "stuck"
        # animation.
        if len(self._board.get_contiguous(x, y)) < 3:
            return

        self._hide_stuck()
        self._stop_animation()
        # We recalc contiguous here because _stop_animation may modify board
        # contents (e.g. the undo-many animation).
        contiguous = self._board.get_contiguous(x, y)
        if len(contiguous) >= 3:

            def remove_func(anim_stopped=False):
                self._remove_contiguous(contiguous, anim_stopped)

            if self._animate:
                self._anim = self._grid.get_removal_anim(
                    self._board, contiguous, remove_func)
                self._anim.start()
            else:
                remove_func()

    def _undo_key_pressed_cb(self, widget, dummy):
        self.undo()

    def _redo_key_pressed_cb(self, widget, dummy):
        self.redo()

    def _new_key_pressed_cb(self, widget, dummy):
        # Only invoke new command via game pad if board is clear, to prevent
        # terrible accidents.
        if self._board.is_empty():
            self.new_game()

    def _stop_animation(self):
        if self._anim is not None:
            self._anim.stop()

    def _remove_contiguous(self, contiguous, anim_stopped=False):
        # Removes the given set of contiguous blocks from the board.
        self._redo_stack = []
        # We save the player's move as the lexographically smallest coordinate
        # of the piece.
        move = min(contiguous)
        self._undo_stack.append((self._board.clone(), move))
        self._board.clear_pieces(contiguous)
        self._board.drop_pieces()
        self._board.remove_empty_columns()

        # Force board refresh.
        self._grid.set_board(self._board)

        if self._board.is_empty():
            if self._animate and not anim_stopped:
                self._anim = self._grid.get_win_anim(self._init_win)
                self._anim.start()
            else:
                self._init_win()
        else:
            self._check_for_lose_state()

    def _check_for_lose_state(self):
        if not self._board.is_empty():
            all_contiguous = self._board.get_all_contiguous()
            if len(all_contiguous) == 0:
                self._init_lose()

    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._undo_stack = []

    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 _hide_stuck(self):
        self.emit('show-stuck', 0)
예제 #14
0
class ImplodeGame(Gtk.EventBox):
    """Gtk widget for playing the implode game."""

    __gsignals__ = {
        'show-stuck': (GObject.SignalFlags.RUN_LAST, None, (int,)),
    }

    def __init__(self, *args, **kwargs):
        super(ImplodeGame, self).__init__(*args, **kwargs)
        self._animate = True
        self._anim = None

        self._board = None
        # Undo and redo stacks are pairs of (board state, subsequent move).
        self._undo_stack = []
        self._redo_stack = []
        self._winning_moves = []

        self._random = random.Random()
        #self._random.seed(0)
        self._difficulty = 0
        self._size = (8, 6)
        self._seed = 0
        self._fragmentation = 0

        self._grid = gridwidget.GridWidget()
        self._grid.connect('piece-selected', self._piece_selected_cb)
        self._grid.connect('undo-key-pressed', self._undo_key_pressed_cb)
        self._grid.connect('redo-key-pressed', self._redo_key_pressed_cb)
        self._grid.connect('new-key-pressed', self._new_key_pressed_cb)
        self.add(self._grid)

        self.new_game()

    def grab_focus(self):
        self._grid.grab_focus()
        #self._grid.select_center_cell()

    def new_game(self):
        self._hide_stuck()
        self._stop_animation()
        self._seed = self._random.randint(0, 99999)
        size_frag_dict = {
            0: (( 8,  6), 0),
            1: ((12, 10), 0),
            2: ((20, 15), 2),
        }
        (self._size, self._fragmentation) = size_frag_dict[self._difficulty]
        self._reset_board()

    def replay_game(self):
        self._hide_stuck()
        self._stop_animation()
        self._reset_board()

    def undo(self):
        self._hide_stuck()
        self._stop_animation()
        if len(self._undo_stack) == 0:
            return

        self._undo_last_move()

    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()

    def _get_moves_so_far(self):
        # Returns a list of the moves so far.
        return [move for (board, move) in self._undo_stack]

    def _undo_last_move(self):
        # Undoes the most recent move and stores the state on the undo stack.
        (board, move) = self._undo_stack.pop()
        self._redo_stack.append((self._board, move))
        self._board = board

        # Force board refresh.
        self._grid.set_board(self._board)
        self._grid.set_win_draw_flag(False)

    def redo(self):
        self._hide_stuck()
        self._stop_animation()
        if len(self._redo_stack) == 0:
            return

        (board, move) = self._redo_stack.pop()
        self._undo_stack.append((self._board, move))
        self._board = board

        # Force board refresh.
        self._grid.set_board(self._board)

        self._check_for_lose_state()

    def set_level(self, level):
        self._difficulty = level

    def get_game_state(self):
        # Returns a dictionary containing the game state, in atomic subobjects.
        def encode_board(board, move):
            # Encodes the given board and move to a state array.
            (w, h) = (board.width, board.height)
            data = []
            for i in range(h):
                for j in range(w):
                    data.append(board.get_value(j, i))
            if move is not None:
                return [w, h] + data + list(move)
            else:
                return [w, h] + data
        return {
            'difficulty' : self._difficulty,
            'seed' : self._seed,
            'size' : self._size,
            'fragmentation' : self._fragmentation,
            'board' : encode_board(self._board, None),
            'undo_stack': [encode_board(b,m) for b,m in self._undo_stack],
            'redo_stack': [encode_board(b,m) for b,m in self._redo_stack],
            'win_draw_flag': self._grid.get_win_draw_flag(),
            'win_color': self._grid.get_win_color(),
            'winning_moves' : self._winning_moves
        }

    def set_game_state(self, state):
        # Sets the game state using a dictionary of atomic subobjects.
        self._hide_stuck()
        self._stop_animation()
        def decode_board(state):
            # Decodes a board (and maybe an appended move) from the given state
            # array.
            b = board.Board()
            (w, h) = (state[0], state[1])
            data = state[2:]
            for i in range(h):
                for j in range(w):
                    b.set_value(j, i, data.pop(0))
            if len(data) == 2:
                # Return appended move.
                return b, tuple(data)
            else:
                return b, None
        self._difficulty = state['difficulty']
        self._seed = state['seed']
        self._size = state['size']
        self._fragmentation = state['fragmentation']
        (self._board, dummy) = decode_board(state['board'])
        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'])
        if 'winning_moves' in state:
            # Prior to version 8, we didn't store the list of winning moves.
            self._winning_moves = [tuple(x) for x in state['winning_moves']]
        else:
            self._winning_moves = []

        self._check_for_lose_state()

    def _reset_board(self):
        # Regenerates the board with the current seed.
        (self._board, self._winning_moves) = \
                boardgen.generate_board(seed=self._seed,
                                        fragmentation=self._fragmentation,
                                        max_size=self._size)
        self._grid.set_board(self._board)
        self._grid.set_win_draw_flag(False)
        self._undo_stack = []
        self._redo_stack = []

    def _piece_selected_cb(self, widget, x, y):
        # Handles piece selection.

        # We check contiguous before stopping the animation because we don't
        # want a click on the game board in a losing state to stop the "stuck"
        # animation.
        if len(self._board.get_contiguous(x, y)) < 3:
            return

        self._hide_stuck()
        self._stop_animation()
        # We recalc contiguous here because _stop_animation may modify board
        # contents (e.g. the undo-many animation).
        contiguous = self._board.get_contiguous(x, y)
        if len(contiguous) >= 3:
            def remove_func(anim_stopped=False):
                self._remove_contiguous(contiguous, anim_stopped)
            if self._animate:
                self._anim = self._grid.get_removal_anim(self._board,
                                                         contiguous,
                                                         remove_func)
                self._anim.start()
            else:
                remove_func()

    def _undo_key_pressed_cb(self, widget, dummy):
        self.undo()

    def _redo_key_pressed_cb(self, widget, dummy):
        self.redo()

    def _new_key_pressed_cb(self, widget, dummy):
        # Only invoke new command via game pad if board is clear, to prevent
        # terrible accidents.
        if self._board.is_empty():
            self.new_game()

    def _stop_animation(self):
        if self._anim is not None:
            self._anim.stop()

    def _remove_contiguous(self, contiguous, anim_stopped=False):
        # Removes the given set of contiguous blocks from the board.
        self._redo_stack = []
        # We save the player's move as the lexographically smallest coordinate
        # of the piece.
        move = min(contiguous)
        self._undo_stack.append((self._board.clone(), move))
        self._board.clear_pieces(contiguous)
        self._board.drop_pieces()
        self._board.remove_empty_columns()

        # Force board refresh.
        self._grid.set_board(self._board)

        if self._board.is_empty():
            if self._animate and not anim_stopped:
                self._anim = self._grid.get_win_anim(self._init_win)
                self._anim.start()
            else:
                self._init_win()
        else:
            self._check_for_lose_state()

    def _check_for_lose_state(self):
        if not self._board.is_empty():
            all_contiguous = self._board.get_all_contiguous()
            if len(all_contiguous) == 0:
                self._init_lose()

    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._undo_stack = []

    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 _hide_stuck(self):
        self.emit('show-stuck', 0)
예제 #15
0
파일: entity.py 프로젝트: Hatchet2k4/mannux
class Entity(object):
    #sprite is an ika Sprite
    def __init__(self, sprite):
        super(Entity, self).__init__()
        self.sprite = sprite
        self.sprite.isobs = False
        self.x__ = self.sprite.x
        self.y__ = self.sprite.y
        self.w = self.sprite.hotwidth
        self.h = self.sprite.hotheight
        self.state__ = None
        self.vx = 0
        self.vy = 0
        self.left_wall = 0
        self.right_wall = 0
        self.ceiling = 0
        self.floor = 0
        self.check_obs = True
        self.hurtable = False
        self.anim = Anim()
        self.state = self.null_state
        self.touchable = False
        self.destroy = False
        self.active = True
        self.platform = False

        # Hack so that ika can detect entity collisions for us.
        #ika.Map.entities[id(self.sprite)] = self.sprite

    def draw(self):
        pass

    def touch(self, entity):
        pass

    def set_animation_state(self, first, last, delay, loop=True, reset=True):
        # Reverse order.
        if first > last:
            strand = range(last, first + 1)
            strand.reverse()
            self.anim.set_anim(make_anim(strand, delay), loop, reset)
        else:
            self.anim.set_anim(make_anim(range(first, last + 1), delay), loop,
                               reset)

    def animation(self):
        self.anim.update(1)
        self.sprite.specframe = self.anim.cur_frame

    def update(self):
        # Because it could have been destroyed already.
        if self.sprite is None:
            return
        self.state__()
        self.animation()
        self.x += self.vx
        self.y += self.vy
        self.sprite.x = int(self.x)
        self.sprite.y = int(self.y)
        if self.check_obs:
           self.check_obstructions()
        if self.destroy:
           # Must put this at the end of the update.
           self._destroy()

    def null_state(self):
        """Default entity state.

        The entity does nothing at all in this state.
        """
        while True:
            yield None

    def _destroy(self):
        self.visible = False
        self.active = False
        #self.sprite = None
        e.engine.RemoveEntity(self)

    def check_obstructions(self):
        x = int(self.x)
        y = int(self.y)
        layer = 1
        self.left_wall = self.check_v_line(x + self.vx - 2, y,
                                           y + self.sprite.hotheight - 2)
        self.right_wall = self.check_v_line(x + self.sprite.hotwidth +
                                            self.vx + 1, y,
                                            y + self.sprite.hotheight - 2)
        self.ceiling = self.check_h_line(x + 1, y + self.vy,
                                         x + self.sprite.hotwidth - 1)
        self.floor = self.check_h_line(x, y + self.sprite.hotheight + self.vy,
                                       x + self.sprite.hotwidth - 1)




    def detect_collision(self): #entity collisions, not currently used in default entity code
        result = []

        for entity in e.engine.entities:
            top = bottom = left = right = False
            etop = entity.y
            ebottom = entity.y + entity.sprite.hotheight
            eleft = entity.x
            eright = entity.x + entity.sprite.hotwidth

            if entity is not self and entity.sprite and \
                ebottom > self.y and etop < self.y + self.sprite.hotheight and \
                eright > self.x and  eleft < self.x + self.sprite.hotwidth:
                   #within bounding box. Check if it's the top, bottom, left, or right side being collided with.
                   if ebottom > self.y and ebottom < self.y + (self.sprite.hotheight/2): top = True #entity touching top side
                   if etop < self.y + self.sprite.hotheight and top > self.y + (self.sprite.hotheight/2): bottom = True
                   if eright > self.x and eright < self.x + (self.sprite.hotwidth/2): left = True
                   if eleft < self.x + self.sprite.hotwidth and eleft < self.x + (self.sprite.hotheight/2): right = True

                   result.append((entity, top, bottom, left, right))
        return result

    def check_v_line(self, x1, y1, y2):
        x1 = int(x1)
        y1 = int(y1)
        y2 = int(y2)
        for y in range(y1, y2, 4):
            if self.get_obstruction(x1, y, self.layer):
                return True
        return self.get_obstruction(x1, y2, self.layer)

    def check_h_line(self, x1, y1, x2):
        x1 = int(x1)
        y1 = int(y1)
        x2 = int(x2)
        for x in range(x1, x2, 4):
            if self.get_obstruction(x, y1, self.layer):
                return True
        return self.get_obstruction(x2, y1, self.layer)

    def get_obstruction(self, x, y, layer):
        return ika.Map.GetObs(int(x / ika.Map.tilewidth),
                              int(y / ika.Map.tileheight), layer)

    def _set_state(self, new_state):
        self.state__ = new_state().next

    def _set_x(self, value):
        self.sprite.x = self.x__ = value

    def _set_y(self, value):
        self.sprite.y = self.y__ = value

    def _set_layer(self, value):
        self.sprite.layer = value

    def _set_position(self, (x, y)):
        self.x, self.y = x, y