예제 #1
0
파일: states.py 프로젝트: hubrys/tytrys
class GameState(TytrysState):
    """Game Logic

    """

    def __init__(self, window):
        super(GameState, self).__init__(window)
        # These lines are so that I don't have to stare at warnings
        # restart sets these to the right values
        self.board = Board(10, 22)
        self.next_piece = random_tetromino(0, 0)
        self.current_piece = random_tetromino(5, 20)
        self.drop_time = .5
        self.current_key = -1
        self.lines_to_next_level = 15
        self.level = 1
        self.score = 0
        self.view_modified = True

        self._restart()
        self.board_window = window.derwin(
            self.board.height, self.board.width + 2, 0, 0)
        self.info_window = window.derwin(
            self.board.height, 8, 0, self.board.width + 2)

    def _restart(self):
        """Restart game with default values"""
        self.board = Board(10, 22)
        self.next_piece = random_tetromino(0, 0)
        self.current_piece = random_tetromino(5, 20)
        self.drop_time = .5
        self.current_key = -1
        self.lines_to_next_level = 15
        self.level = 1
        self.score = 0
        self.view_modified = True

    def process_messages(self):
        while not self.messages.empty():
            if self.messages.get() == "restart":
                self._restart()
                self.window.clear()

    def handle_user_input(self):
        direction = None
        key_pressed = self.window.getch()
        if key_pressed in (ord('j'), ord('J'), curses.KEY_LEFT):
            direction = Direction.Left
        elif key_pressed in (ord('l'), ord('L'), curses.KEY_RIGHT):
            direction = Direction.Right
        elif key_pressed in (ord('i'), ord('I'), curses.KEY_UP):
            direction = Direction.CCW
        elif key_pressed in (ord('k'), ord('K'), curses.KEY_DOWN):
            direction = Direction.CW
        elif key_pressed in (ord('q'), ord('Q')):
            self.view_modified = True
            game.switch_to_state("paused")
        elif key_pressed == ord(' '):
            self.drop_current_piece()

        if direction is not None:
            if direction == Direction.CCW or direction == Direction.CW:
                if self.board.are_valid_coordinates(
                        self.current_piece.rotate_result(direction)):
                    renderer.clear_tetromino(self.current_piece,
                                             self.board_window)
                    self.view_modified = True
                    self.current_piece.rotate(direction)
            else:
                if self.board.are_valid_coordinates(
                        self.current_piece.move_result(direction)):
                    renderer.clear_tetromino(self.current_piece,
                                             self.board_window)
                    self.view_modified = True
                    self.current_piece.move(direction)

    def drop_current_piece(self):
        self.view_modified = True
        renderer.clear_tetromino(self.current_piece, self.board_window)
        while self.board.are_valid_coordinates(
                self.current_piece.move_result(Direction.Down)):
            self.current_piece.move(Direction.Down)

    def draw(self):
        if self.view_modified:
            self.view_modified = False
            renderer.draw_board(self.board, self.board_window)
            renderer.draw_tetromino(self.current_piece, self.board_window)
            self.board_window.refresh()
            self._draw_info()

    def _draw_info(self):
        self.info_window.border()
        self.info_window.addstr(1, 1, "Tytrys")
        self.info_window.hline(2, 1, ord('_'), 6)
        self.info_window.addstr(4, 1, "Next:")
        self.next_piece.set_location(3, 14) # little hacky
        renderer.draw_tetromino(self.next_piece, self.info_window)
        self.info_window.addstr(10, 1, "Score:")
        self.info_window.addstr(11, 1, str(self.score))
        self.info_window.addstr(14, 1, "Level:")
        self.info_window.addstr(15, 3, str(self.level))
        self.info_window.addstr(18, 1, "Lines:")
        self.info_window.addstr(19, 1, str(self.lines_to_next_level) + "  ")
        self.info_window.refresh()

    def update(self, delta):
        self.elapsed_time += delta
        self.handle_user_input()

        if self.elapsed_time >= self.drop_time:
            if self.board.are_valid_coordinates(
                    self.current_piece.move_result(Direction.Down)):
                renderer.clear_tetromino(self.current_piece, self.board_window)
                self.current_piece.move(Direction.Down)
            else:
                renderer.clear_tetromino(self.next_piece, self.info_window)
                try:
                    self.board.lock_tetromino(self.current_piece)
                    self.current_piece = self.next_piece
                    self.current_piece.set_location(5, 20)
                    self.next_piece = random_tetromino(0, 0)

                    rows_removed = self.board.clear_full_rows()
                    if rows_removed:
                        self.lines_to_next_level -= rows_removed
                        self.score += sum(range(rows_removed + 1)) * 100
                        if self.lines_to_next_level <= 0:
                            self.score += 1000 * self.level
                            self.lines_to_next_level = 15
                            self.level += 1
                            self.drop_time *= .75
                except RuntimeError:
                    game.add_state_and_switch("game over",
                                              GameOverState(self.window,
                                                            self.score))

            self.view_modified = True
            self.elapsed_time -= self.drop_time