示例#1
0
class Game:
    width = 10
    height = 20
    pause = False
    start = True

    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    GRAY = (190, 190, 190)
    GREEN = (0, 255, 0)
    RED = (255, 0, 0)

    def drawBoard(self, screen, board, width, height):
        for y in range(self.height):
            for x in range(self.width):
                if self.board[y][x]:
                    pygame.draw.rect(self.screen, self.board[y][x].color,
                                     (40 * x, 40 * y, 40, 40))

    def __init__(self):
        pygame.init()

        self.size = (self.width * 40 + 400, self.height * 40)

        self.screen = pygame.display.set_mode(self.size)

        pygame.display.set_caption("Tetris")

        self.clock = pygame.time.Clock()

        self.continueGame = True

        self.steps = 0

    def setUpBoard(self):
        self.gameover = False
        self.board = Board(self.width, self.height)

        d = True
        self.pieceSelect = ['T', 'L', 'I', 'J', 'O', 'S', 'Z']
        self.p = Piece(self.width, self.height,
                       random.choice(self.pieceSelect), self.board)
        self.p.genBoard()
        self.pNext = Piece(self.width, self.height,
                           random.choice(self.pieceSelect), self.board)
        self.pNext.genBoard()
        # for x in range(10):
        #     p.moveDown()
        self.board.addCellsTemp(self.p)
        self.done = False

        self.pNext = Piece(self.width, self.height,
                           random.choice(self.pieceSelect), self.board)
        self.pNext.genBoard()

    def shouldGameTick(self, step):
        level = self.board.level
        if level == 0 or level == 1:
            if step % 48 == 0 and step != 0:
                return True
        elif level == 1:
            if step % 43 == 0 and step != 0:
                return True
        elif level == 2:
            if step % 38 == 0 and step != 0:
                return True
        elif level == 3:
            if step % 33 == 0 and step != 0:
                return True
        elif level == 4:
            if step % 28 == 0 and step != 0:
                return True
        elif level == 5:
            if step % 23 == 0 and step != 0:
                return True
        elif level == 6:
            if step % 18 == 0 and step != 0:
                return True
        elif level == 7:
            if step % 13 == 0 and step != 0:
                return True
        elif level == 8:
            if step % 8 == 0 and step != 0:
                return True
        elif level == 9:
            if step % 6 == 0 and step != 0:
                return True
        elif level <= 12:
            if step % 5 == 0 and step != 0:
                return True
        elif level <= 15:
            if step % 4 == 0 and step != 0:
                return True
        elif level <= 18:
            if step % 3 == 0 and step != 0:
                return True
        elif level <= 28:
            if step % 2 == 0 and step != 0:
                return True
        else:
            return True

    def moveDown(self):
        if not self.board.checkIfSet(self.p):
            self.p.moveDown()
            self.board.addCellsTemp(self.p)
        else:

            self.board.addCells(self.p)
            self.gameover = self.board.checkIfGameOver()
            self.board.checkCompleteRows()
            self.p = self.pNext
            self.pNext = Piece(self.width, self.height,
                               random.choice(self.pieceSelect), self.board)
            self.pNext.genBoard()
            self.board.addCellsTemp(self.p)
            while not self.shouldGameTick(self.steps):
                self.steps += 1
            self.steps += 1

    def hardDrop(self):
        while not self.board.checkIfSet(self.p):
            self.p.moveDown()
            self.board.addCellsTemp(self.p)
        self.board.addCells(self.p)
        self.gameover = self.board.checkIfGameOver()
        if self.gameover:
            x = 1
        self.board.checkCompleteRows()
        self.p = self.pNext
        self.pNext = Piece(self.width, self.height,
                           random.choice(self.pieceSelect), self.board)
        self.pNext.genBoard()
        self.board.addCellsTemp(self.p)
        while not self.shouldGameTick(self.steps):
            self.steps += 1
        self.steps += 1

    def mainLoop(self):
        while self.continueGame:
            self.setUpBoard()
            self.gameLoop()
        # Close the window and quit.
        pygame.quit()

    def gameLoop(self):
        self.steps = 0

        while not self.done:
            hardDrop = False
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.done = True
                    self.continueGame = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        self.done = True
                        self.continueGame = False
                    if event.key == pygame.K_r:
                        self.done = True
                    if not (self.pause or self.gameover or self.start):
                        if event.key == pygame.K_LEFT:
                            self.p.move(1)
                            self.board.addCellsTemp(self.p)
                        if event.key == pygame.K_RIGHT:
                            self.p.move(0)
                            self.board.addCellsTemp(self.p)
                        if event.key == pygame.K_UP:
                            self.p.rotate()
                            self.board.addCellsTemp(self.p)
                        if event.key == pygame.K_DOWN:
                            self.moveDown()
                        if event.key == pygame.K_SPACE:
                            self.hardDrop()
                            hardDrop = True
                    if event.key == pygame.K_p:
                        self.pause = not self.pause
                    if event.key == pygame.K_SPACE:
                        self.start = False
            # --- Game logic should go here
            if not (self.pause or self.gameover or self.start):
                if self.shouldGameTick(self.steps) and not hardDrop:
                    self.moveDown()
            # --- Drawing code should go here
            if self.pause:
                self.screen.fill(self.WHITE)
            elif self.start:
                self.screen.fill(self.GRAY)
            else:
                self.screen.fill(self.BLACK)

            pygame.draw.rect(
                self.screen, (66, 79, 159),
                (self.width * 40, 0, self.width * 40 + 200, self.height * 40))
            self.drawBoard(self.screen, self.board, self.width, self.height)
            self.board.drawGUI(self.screen, self.pNext)
            if self.start:
                self.board.drawTitle(self.screen)
            elif self.pause:
                self.board.drawGUI(self.screen, self.pNext)
            if self.pause:
                self.board.drawPause(self.screen)
            elif self.gameover:
                self.board.drawGameover(self.screen)
            # --- Go ahead and update the screen with what we've drawn.
            pygame.display.flip()

            # --- Limit to 60 frames per second
            self.clock.tick(60)
            self.steps += 1
示例#2
0
class Tetris:
    def __init__(self):
        self.pygame_screen = None
        self.clock = None
        self.font = None
        self.piece = None
        self.squares = []
        self.particles = []
        self.outer_squares = []
        self.drops_per_second = 6
        self.frames_per_second = 30
        self.score = 0
        self.lines = 0
        self.high_score = int(open("files/highscore.txt", "r").read())
        self.background = pygame.image.load('files/images/background4.jpg')
        self.game_running = True
        self.setup()

    def setup(self):
        pygame.init()
        pygame.font.init()
        self.pygame_screen = pygame.display.set_mode((582, 785))
        self.clock = pygame.time.Clock()
        self.font = pygame.font.Font('files/fonts/arial.ttf', 45)

    def splash_screens(self):
        self.splash_screen()
        self.start_screen()

    def start_game(self):
        self.game_loop()

    def splash_screen(self):
        frame_counter = 0
        self.pygame_screen.blit(pygame.image.load('files/images/splash.jpg'),
                                (0, 0))
        while frame_counter < 30 and self.game_running:
            frame_counter += 1
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.game_running = False
            pygame.display.update()
            self.clock.tick(self.frames_per_second)

    def start_screen(self):
        space_pressed = False
        while not space_pressed and self.game_running:
            self.pygame_screen.blit(
                pygame.image.load('files/images/background5.jpg'), (0, 0))
            self.pygame_screen.blit(
                pygame.image.load('files/images/startButton.png'), (231, 360))
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        space_pressed = True
                elif event.type == pygame.QUIT:
                    self.game_running = False
            pygame.display.update()
            self.clock.tick(self.frames_per_second)

    def game_loop(self):
        frame_counter = 1
        self.create_floor()
        self.create_walls()
        self.new_piece()
        while self.game_running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.game_running = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT or event.key == pygame.K_a:
                        self.move_piece_sideways('left')
                    if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
                        self.move_piece_sideways('right')
                    if event.key == pygame.K_UP or event.key == pygame.K_w:
                        self.rotate_piece()
                    if event.key == pygame.K_DOWN or event.key == pygame.K_s:
                        self.move_piece_down()
                    if event.key == pygame.K_SPACE:
                        self.drop_piece()

            if frame_counter % (self.frames_per_second /
                                self.drops_per_second) == 0:
                self.move_piece_down()

            frame_counter += 1

            self.blit_everything()
            pygame.display.update()
            self.clock.tick(self.frames_per_second)

    def create_floor(self):
        for col in range(10):
            self.outer_squares.append(Square(None, 8, col, 18))

    def create_walls(self):
        for row in range(-1, 18):
            self.outer_squares.append(Square(None, 8, -1, row))
        for row in range(-1, 18):
            self.outer_squares.append(Square(None, 8, 10, row))

    def new_piece(self):
        self.piece = Piece(self.pygame_screen)

    def move_piece_down(self):
        if self.can_piece_move_down():
            self.piece.move_down()
            return True
        else:
            self.piece_collide()
            return False

    def move_piece_sideways(self, direction):
        if self.can_piece_move_sideways(direction):
            self.piece.move_sideways(direction)

    def can_piece_move_down(self):
        for piece_square in self.piece.get_squares():
            for board_square in self.squares + self.outer_squares:
                if piece_square.get_column() == board_square.get_column(
                ) and piece_square.get_row() + 1 == board_square.get_row():
                    return False
        return True

    def can_piece_move_sideways(self, direction):
        if direction == 'right':
            direction_number = 1
        else:
            direction_number = -1
        for piece_square in self.piece.get_squares():
            for board_square in self.squares + self.outer_squares:
                if piece_square.get_column(
                ) + direction_number == board_square.get_column(
                ) and piece_square.get_row() == board_square.get_row():
                    return False
        return True

    def rotate_piece(self):
        new_squares = self.can_rotate_piece()
        if new_squares is not False:
            self.piece.rotate(new_squares)

    def can_rotate_piece(self):
        new_squares = self.piece.get_rotate_squares()
        for piece_square in new_squares:
            for board_square in self.squares + self.outer_squares:
                if (piece_square.get_column(),
                        piece_square.get_row()) == (board_square.get_column(),
                                                    board_square.get_row()):
                    return False
        return new_squares

    def piece_collide(self):
        if self.did_lose():
            self.ask_play_again()
        else:
            self.squares += self.piece.get_squares()
            self.check_line_win()
            self.new_piece()

    def blit_everything(self):
        self.pygame_screen.blit(self.background, (0, 0))
        self.piece.blit()
        for square in self.squares:
            square.blit()
        self.blit_scores()
        self.blit_particles()

    def blit_particles(self):
        index = 0
        for i in range(len(self.particles)):
            particle = self.particles[index]
            particle.blit()
            if not particle.blit():
                del self.particles[index]
            else:
                index += 1

    def check_line_win(self):
        row_dictionary = {}
        for square in self.squares:
            square_row = square.get_row()
            if square_row in row_dictionary:
                row_dictionary[square_row] += 1
            else:
                row_dictionary[square_row] = 1
        win_count = 0
        for row in sorted(row_dictionary):
            # row_dictionary[row] = 10 #always win
            if row_dictionary[row] == 10:
                win_count += 1
                self.add_particles(row)
                self.delete_row(row)
                self.drop_rows_down(row)
        if win_count > 0:
            self.lines += win_count
            self.add_to_score(win_count)

    def add_particles(self, line):
        for square in self.squares:
            if square.get_row() == line:
                for row in range(2):
                    for col in range(15):
                        self.particles.append(
                            Particle(self.pygame_screen, col, row, line, 5))

    def delete_row(self, row):
        index = 0
        for i in range(len(self.squares)):
            square = self.squares[index]
            if square.get_row() == row:
                del self.squares[index]
            else:
                index += 1

    def drop_rows_down(self, start):
        for square in self.squares:
            if square.get_row() < start:
                square.move_down()

    def drop_piece(self):
        while self.move_piece_down():
            pass

    def add_to_score(self, win_count):
        new_score = 0
        for i in range(win_count):
            new_score += ((i + 1) * 10)
        self.score += new_score
        if self.score > self.high_score:
            self.high_score = self.score
            open("files/highscore.txt", "w").write(str(self.high_score))

    def blit_scores(self):
        block = self.font.render(str(self.lines), True, (0, 0, 0))
        rect = block.get_rect()
        rect.center = (510, 250)
        self.pygame_screen.blit(block, rect)

        block = self.font.render(str(self.score), True, (0, 0, 0))
        rect = block.get_rect()
        rect.center = (510, 350)
        self.pygame_screen.blit(block, rect)

        block = self.font.render(str(self.high_score), True, (0, 0, 0))
        rect = block.get_rect()
        rect.center = (510, 465)
        self.pygame_screen.blit(block, rect)

    def did_lose(self):
        for square in self.piece.get_squares():
            if square.get_row() < 0:
                return True
        return False

    def ask_play_again(self):
        space_pressed = False
        while not space_pressed and self.game_running:
            self.pygame_screen.blit(
                pygame.image.load('files/images/playAgainButton.png'),
                (231, 360))
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        space_pressed = True
                        self.reset_game()
                elif event.type == pygame.QUIT:
                    self.game_running = False
            pygame.display.update()
            self.clock.tick(self.frames_per_second)

    def reset_game(self):
        self.piece = None
        self.squares = []
        self.score = 0
        self.lines = 0
        self.new_piece()