此代码定义了俄罗斯方块游戏中的方块和游戏逻辑,同时使用 pygame 库实现了游戏的图形界面。你可以运行此代码,用上下左右键来控制方块的移动和旋转。
import pygame
import random
# 初始化 Pygame
pygame.init()
# 定义常量
WIDTH = 300
HEIGHT = 600
BLOCK_SIZE = 30
BOARD_WIDTH = WIDTH // BLOCK_SIZE
BOARD_HEIGHT = HEIGHT // BLOCK_SIZE
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
CYAN = (0, 255, 255)
YELLOW = (255, 255, 0)
MAGENTA = (255, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
ORANGE = (255, 165, 0)
# 形状定义
SHAPES = [
[[1, 1, 1, 1]],
[[1, 1], [1, 1]],
[[1, 1, 0], [0, 1, 1]],
[[0, 1, 1], [1, 1, 0]],
[[1, 1, 1], [0, 1, 0]],
[[1, 1, 1], [1, 0, 0]],
[[1, 1, 1], [0, 0, 1]]
]
SHAPE_COLORS = [CYAN, YELLOW, MAGENTA, GREEN, RED, BLUE, ORANGE]
class Block:
def __init__(self, x, y, shape):
self.x = x
self.y = y
self.shape = shape
self.color = random.choice(SHAPE_COLORS)
def move_down(self):
self.y += 1
def move_left(self):
self.x -= 1
def move_right(self):
self.x += 1
def rotate(self):
self.shape = list(map(list, zip(*self.shape[::-1])))
class Tetris:
def __init__(self):
self.board = [[0] * BOARD_WIDTH for _ in range(BOARD_HEIGHT)]
self.current_block = Block(BOARD_WIDTH // 2 - len(SHAPES[0][0]) // 2, 0, random.choice(SHAPES))
def is_collision(self, block):
for y, row in enumerate(block.shape):
for x, cell in enumerate(row):
if cell:
new_x = block.x + x
new_y = block.y + y
if new_x < 0 or new_x >= BOARD_WIDTH or new_y >= BOARD_HEIGHT or (
new_y >= 0 and self.board[new_y][new_x]):
return True
return False
def merge_block(self, block):
for y, row in enumerate(block.shape):
for x, cell in enumerate(row):
if cell:
self.board[block.y + y][block.x + x] = 1
def clear_lines(self):
full_lines = []
for i, row in enumerate(self.board):
if all(row):
full_lines.append(i)
for line in full_lines:
del self.board[line]
self.board = [[0] * BOARD_WIDTH] + self.board
def new_block(self):
self.current_block = Block(BOARD_WIDTH // 2 - len(SHAPES[0][0]) // 2, 0, random.choice(SHAPES))
if self.is_collision(self.current_block):
return False
return True
def move_down(self):
new_block = Block(self.current_block.x, self.current_block.y + 1, self.current_block.shape)
if self.is_collision(new_block):
self.merge_block(self.current_block)
self.clear_lines()
return self.new_block()
else:
self.current_block.move_down()
return True
def move_left(self):
new_block = Block(self.current_block.x - 1, self.current_block.y, self.current_block.shape)
if not self.is_collision(new_block):
self.current_block.move_left()
def move_right(self):
new_block = Block(self.current_block.x + 1, self.current_block.y, self.current_block.shape)
if not self.is_collision(new_block):
self.current_block.move_right()
def rotate(self):
new_shape = list(map(list, zip(*self.current_block.shape[::-1])))
new_block = Block(self.current_block.x, self.current_block.y, new_shape)
if not self.is_collision(new_block):
self.current_block.rotate()
# 创建窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Tetris")
# 创建游戏对象
game = Tetris()
clock = pygame.time.Clock()
fall_time = 0
fall_speed = 0.3
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
game.move_left()
elif event.key == pygame.K_RIGHT:
game.move_right()
elif event.key == pygame.K_DOWN:
game.move_down()
elif event.key == pygame.K_UP:
game.rotate()
# 自动下落
fall_time += clock.get_rawtime()
clock.tick()
if fall_time / 1000 >= fall_speed:
if not game.move_down():
running = False
fall_time = 0
# 绘制背景
screen.fill(BLACK)
# 绘制网格
for i in range(BOARD_WIDTH):
for j in range(BOARD_HEIGHT):
pygame.draw.rect(screen, WHITE,
(i * BLOCK_SIZE, j * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 1)
# 绘制当前方块
for y, row in enumerate(game.current_block.shape):
for x, cell in enumerate(row):
if cell:
pygame.draw.rect(screen, game.current_block.color,
((game.current_block.x + x) * BLOCK_SIZE, (game.current_block.y + y) * BLOCK_SIZE,
BLOCK_SIZE, BLOCK_SIZE))
# 绘制已固定的方块
for y, row in enumerate(game.board):
for x, cell in enumerate(row):
if cell:
pygame.draw.rect(screen, SHAPE_COLORS[0], (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
pygame.display.flip()
pygame.quit()
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。