找回密码
 中文实名注册
搜索
查看: 117|回复: 0

俄罗斯方块(高清版)

[复制链接]

17

主题

21

回帖

1624

积分

金牌会员

积分
1624
发表于 2025-7-19 15:27:29 | 显示全部楼层 |阅读模式
[Python] 纯文本查看 复制代码
import pygame
import random
import sys

# 初始化pygame
pygame.init()

# ------ 游戏参数 ------
SCREEN_WIDTH, SCREEN_HEIGHT = 300, 600
BLOCK_SIZE = 30  # 每个方块大小
GRID_WIDTH, GRID_HEIGHT = SCREEN_WIDTH // BLOCK_SIZE, SCREEN_HEIGHT // BLOCK_SIZE

# 颜色定义
BLACK = (0, 0, 0)
GRAY = (128, 128, 128)
WHITE = (255, 255, 255)
COLORS = [
    (0, 255, 255),  # I - 青色
    (0, 0, 255),    # J - 蓝色
    (255, 165, 0),  # L - 橙色
    (255, 255, 0),  # O - 黄色
    (0, 255, 0),    # S - 绿色
    (128, 0, 128),  # T - 紫色
    (255, 0, 0)     # Z - 红色
]

# 7种方块形状,使用二维列表(1表示方块)
SHAPES = [
    [[1, 1, 1, 1]],           # I
    [[1, 0, 0], [1, 1, 1]],   # J
    [[0, 0, 1], [1, 1, 1]],   # L
    [[1, 1], [1, 1]],         # O
    [[0, 1, 1], [1, 1, 0]],   # S
    [[0, 1, 0], [1, 1, 1]],   # T
    [[1, 1, 0], [0, 1, 1]]    # Z
]

# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("俄罗斯方块")

clock = pygame.time.Clock()

# 创建空网格


def create_grid(locked_positions={}):
    grid = [[BLACK for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
    for (x, y), color in locked_positions.items():
        if y >= 0:
            grid[y][x] = color
    return grid

# 画网格线


def draw_grid(surface):
    for y in range(GRID_HEIGHT):
        pygame.draw.line(surface, GRAY, (0, y * BLOCK_SIZE),
                         (SCREEN_WIDTH, y * BLOCK_SIZE))
    for x in range(GRID_WIDTH):
        pygame.draw.line(surface, GRAY, (x * BLOCK_SIZE, 0),
                         (x * BLOCK_SIZE, SCREEN_HEIGHT))

# 画窗口内容


def draw_window(surface, grid, score=0):
    surface.fill(BLACK)

    # 画所有方块
    for y in range(GRID_HEIGHT):
        for x in range(GRID_WIDTH):
            color = grid[y][x]
            if color != BLACK:
                pygame.draw.rect(surface, color, (x*BLOCK_SIZE,
                                 y*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))

    draw_grid(surface)

    # 显示分数
    font = pygame.font.SysFont('comicsans', 30)
    score_text = font.render(f"分数: {score}", True, WHITE)
    surface.blit(score_text, (10, 10))

    pygame.display.update()

# 方块类


class Piece:
    def __init__(self, x, y, shape_idx):
        self.x = x
        self.y = y
        self.shape_idx = shape_idx
        self.shape = SHAPES[shape_idx]
        self.color = COLORS[shape_idx]
        self.rotation = 0

    def get_shape(self):
        # 根据旋转返回当前形状
        shape = self.shape
        for _ in range(self.rotation % 4):
            shape = [list(row) for row in zip(*shape[::-1])]  # 顺时针旋转90度
        return shape

    def positions(self):
        positions = []
        shape = self.get_shape()
        for i, row in enumerate(shape):
            for j, val in enumerate(row):
                if val:
                    positions.append((self.x + j, self.y + i))
        return positions

# 检查方块位置是否有效


def valid_space(piece, grid):
    accepted_positions = [[(x, y) for x in range(
        GRID_WIDTH) if grid[y][x] == BLACK] for y in range(GRID_HEIGHT)]
    accepted_positions = [pos for sub in accepted_positions for pos in sub]
    for pos in piece.positions():
        if pos not in accepted_positions:
            if pos[1] >= 0:
                return False
    return True

# 检查是否游戏结束


def check_lost(locked_positions):
    for (x, y) in locked_positions:
        if y < 1:
            return True
    return False

# 消除满行


def clear_rows(grid, locked):
    cleared = 0
    for y in range(GRID_HEIGHT-1, -1, -1):
        if BLACK not in grid[y]:
            cleared += 1
            # 删除该行所有锁定方块
            for x in range(GRID_WIDTH):
                try:
                    del locked[(x, y)]
                except:
                    pass
            # 向上移动所有锁定方块
            keys = sorted(locked.keys(), key=lambda k: k[1])
            for key in keys[::-1]:
                x, y2 = key
                if y2 < y:
                    locked[(x, y2 + 1)] = locked.pop(key)
    return cleared


def main():
    locked_positions = {}
    grid = create_grid(locked_positions)

    current_piece = Piece(GRID_WIDTH//2 - 2, 0,
                          random.randint(0, len(SHAPES)-1))
    next_piece = Piece(GRID_WIDTH//2 - 2, 0, random.randint(0, len(SHAPES)-1))

    fall_time = 0
    fall_speed = 0.5
    score = 0

    run = True
    while run:
        grid = create_grid(locked_positions)
        fall_time += clock.get_rawtime()
        clock.tick()

        # 自动下落
        if fall_time / 1000 >= fall_speed:
            fall_time = 0
            current_piece.y += 1
            if not valid_space(current_piece, grid):
                current_piece.y -= 1
                # 固定方块
                for pos in current_piece.positions():
                    locked_positions[pos] = current_piece.color
                current_piece = next_piece
                next_piece = Piece(GRID_WIDTH//2 - 2, 0,
                                   random.randint(0, len(SHAPES)-1))

                # 清除满行
                cleared = clear_rows(grid, locked_positions)
                if cleared > 0:
                    score += cleared * 10

                if check_lost(locked_positions):
                    run = False

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    current_piece.x -= 1
                    if not valid_space(current_piece, grid):
                        current_piece.x += 1
                elif event.key == pygame.K_RIGHT:
                    current_piece.x += 1
                    if not valid_space(current_piece, grid):
                        current_piece.x -= 1
                elif event.key == pygame.K_DOWN:
                    current_piece.y += 1
                    if not valid_space(current_piece, grid):
                        current_piece.y -= 1
                elif event.key == pygame.K_UP:
                    current_piece.rotation = (current_piece.rotation + 1) % 4
                    if not valid_space(current_piece, grid):
                        current_piece.rotation = (
                            current_piece.rotation - 1) % 4
                elif event.key == pygame.K_SPACE:
                    # 直接硬下落
                    while valid_space(current_piece, grid):
                        current_piece.y += 1
                    current_piece.y -= 1

        # 在网格上画当前方块
        for pos in current_piece.positions():
            x, y = pos
            if y >= 0:
                grid[y][x] = current_piece.color

        draw_window(screen, grid, score)

    # 游戏结束
    screen.fill(BLACK)
    font = pygame.font.SysFont('comicsans', 40)
    text = font.render("游戏结束!分数: " + str(score), True, WHITE)
    screen.blit(text, (SCREEN_WIDTH//2 - text.get_width() //
                2, SCREEN_HEIGHT//2 - text.get_height()//2))
    pygame.display.update()
    pygame.time.wait(3000)
    pygame.quit()


if __name__ == "__main__":
    main()

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 中文实名注册

本版积分规则

快速回复 返回顶部 返回列表