# 导入必要的库
import pygame
import random

# 初始化pygame
pygame.init()

# 定义常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
BLOCK_SIZE = 30
FONT_SIZE = 36
FPS = 60

# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)

# 定义方块形状
SHAPES = [
    [[1, 1, 1], [0, 1, 0]],
    [[2, 2], [2, 2]],
    [[0, 3, 3], [3, 3, 0]],
    [[4, 4, 0], [0, 4, 4]],
    [[5, 5, 5, 5]],
    [[6, 6, 6], [0, 0, 6]],
    [[7, 7, 7], [7, 0, 0]],
]

# 定义方块颜色
COLORS = [
    BLUE,
    YELLOW,
    GREEN,
    RED,
    WHITE,
    (255, 165, 0),
    (128, 0, 128),
]

# 定义方块类
class Block:
    def __init__(self, x, y, shape):
        self.x = x
        self.y = y
        self.shape = shape
        self.color = COLORS[SHAPES.index(shape)]
        self.rotation = 0

    def rotate(self):
        self.rotation = (self.rotation + 1) % len(self.shape)

    def get_matrix(self):
        return self.shape[self.rotation]

    def get_size(self):
        return len(self.get_matrix()), len(self.get_matrix()[0])

    def get_color(self):
        return self.color

# 定义游戏类
class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("俄罗斯方块")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.Font(None, FONT_SIZE)
        self.score = 0
        self.board = [[0] * (SCREEN_WIDTH // BLOCK_SIZE) for _ in range(SCREEN_HEIGHT // BLOCK_SIZE)]
        self.current_block = Block(3, 0, random.choice(SHAPES))
        self.next_block = Block(0, 0, random.choice(SHAPES))
        self.game_over = False

    def draw_block(self, x, y, color):
        pygame.draw.rect(self.screen, color, (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))

    def draw_board(self):
        for y, row in enumerate(self.board):
            for x, val in enumerate(row):
                if val > 0:
                    self.draw_block(x, y, COLORS[val - 1])

    def draw_current_block(self):
        matrix = self.current_block.get_matrix()
        size_x, size_y = self.current_block.get_size()
        for y in range(size_y):
            for x in range(size_x):
                if matrix[y][x] > 0:
                    self.draw_block(self.current_block.x + x, self.current_block.y + y, self.current_block.get_color())

    def draw_next_block(self):
        matrix = self.next_block.get_matrix()
        size_x, size_y = self.next_block.get_size()
        for y in range(size_y):
            for x in range(size_x):
                if matrix[y][x] > 0:
                    self.draw_block(x + SCREEN_WIDTH // BLOCK_SIZE + 2, y + SCREEN_HEIGHT // BLOCK_SIZE // 2, self.next_block.get_color())

    def draw_score(self):
        score_text = self.font.render("Score: {}".format(self.score), True, WHITE)
        self.screen.blit(score_text, (10, 10))

    def check_collision(self, block, dx=0, dy=0):
        matrix = block.get_matrix()
        size_x, size_y = block.get_size()
        for y in range(size_y):
            for x in range(size_x):
                if matrix[y][x] > 0:
                    if block.x + x + dx < 0 or block.x + x + dx >= SCREEN_WIDTH // BLOCK_SIZE:
                        return True
                    if block.y + y + dy >= SCREEN_HEIGHT // BLOCK_SIZE:
                        return True
                    if self.board[block.y + y + dy][block.x + x + dx] > 0:
                        return True
        return False

    def merge_block(self, block):
        matrix = block.get_matrix()
        size_x, size_y = block.get_size()
        for y in range(size_y):
            for x in range(size_x):
                if matrix[y][x] > 0:
                    self.board[block.y + y][block.x + x] = matrix[y][x]

    def remove_lines(self):
    lines_removed = 0
    y = SCREEN_HEIGHT // BLOCK_SIZE - 1
    while y >= 0:
        if all(self.board[y]):
            lines_removed += 1
            for y2 in range(y, 0, -1):
                self.board[y2] = self.board[y2 - 1][:]
            self.board[0] = [0] * (SCREEN_WIDTH // BLOCK_SIZE)
        else:
            y -= 1
    self.score += lines_removed * 100


    def update(self):
        if not self.check_collision(self.current_block, dy=1):
            self.current_block.y += 1
        else:
            self.merge_block(self.current_block)
            self.remove_lines()
            self.current_block = self.next_block
            self.next_block = Block(0, 0, random.choice(SHAPES))
            if self.check_collision(self.current_block):
                self.game_over = True

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.game_over = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT and not self.check_collision(self.current_block, dx=-1):
                    self.current_block.x -= 1
                if event.key == pygame.K_RIGHT and not self.check_collision(self.current_block, dx=1):
                    self.current_block.x += 1
                if event.key == pygame.K_UP:
                    self.current_block.rotate()
                    if self.check_collision(self.current_block):
                        self.current_block.rotate()
                        self.current_block.rotate()
                        self.current_block.rotate()
                if event.key == pygame.K_DOWN and not self.check_collision(self.current_block, dy=1):
                    self.current_block.y += 1

    def run(self):
        while not self.game_over:
            self.screen.fill(BLACK)
            self.draw_board()
            self.draw_current_block()
            self.draw_next_block()
            self.draw_score()
            pygame.display.update()
            self.handle_events()
            self.update()
            self.clock.tick(FPS)
        pygame.quit()

if __name__ == "__main__":
    game = Game()
    game.run()

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐