完整代码如下:
import pygame
import random
import sys
# 游戏设置
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 500
GRID_WIDTH = 10
GRID_HEIGHT = 20
BLOCK_SIZE = 20
NEXT_WIDTH = 5
NEXT_HEIGHT = 5
NEXT_X = WINDOW_WIDTH - 100
NEXT_Y = 50
FPS = 30
# 颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
PURPLE = (255, 0, 255)
CYAN = (0, 255, 255)
# 方块类型
SHAPE_I = [
['X', 'X', 'X', 'X']
]
SHAPE_J = [
['X', ' ', ' '],
['X', 'X', 'X']
]
SHAPE_L = [
[' ', ' ', 'X'],
['X', 'X', 'X']
]
SHAPE_O = [
['X', 'X'],
['X', 'X']
]
SHAPE_S = [
[' ', 'X', 'X'],
['X', 'X', ' ']
]
SHAPE_T = [
[' ', 'X', ' '],
['X', 'X', 'X']
]
SHAPE_Z = [
['X', 'X', ' '],
[' ', 'X', 'X']
]
SHAPES = [SHAPE_I, SHAPE_J, SHAPE_L, SHAPE_O, SHAPE_S, SHAPE_T, SHAPE_Z]
COLORS = [CYAN, BLUE, ORANGE, YELLOW, GREEN, PURPLE, RED]
# 游戏状态
START = "start"
PLAYING = "playing"
GAMEOVER = "gameover"
# 方块类
class Block:
def __init__(self, shape, rotation, color, x=0, y=0):
self.shape = shape
self.rotation = rotation
self.color = color
self.x = x
self.y = y
def move_down(self):
self.y += 1
def move_up(self):
self.y -= 1
def move_left(self):
self.x -= 1
def move_right(self):
self.x += 1
def rotate(self):
self.rotation = (self.rotation + 1) % len(self.shape)
def rotate_back(self):
self.rotation = (self.rotation - 1) % len(self.shape)
# 俄罗斯方块类
class Tetris:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Tetris")
self.clock = pygame.time.Clock()
self.grid = [[BLACK for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
self.current_block = None
self.next_block = None
self.score = 0
self.state = START
def start(self):
self.grid = [[BLACK for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
self.current_block = self.get_new_block()
self.next_block = self.get_new_block()
self.score = 0
self.state = PLAYING
def get_new_block(self):
shape
shape = random.choice(SHAPES)
color = random.choice(COLORS)
rotation = 0
x = (GRID_WIDTH - len(shape[0])) // 2
y = 0
return Block(shape, rotation, color, x, y)
def update(self):
if self.state == PLAYING:
self.current_block.move_down()
if self.check_collision():
self.current_block.move_up()
self.place_block()
self.clear_lines()
self.current_block = self.next_block
self.next_block = self.get_new_block()
if self.check_collision():
self.state = GAMEOVER
def check_collision(self):
for y in range(len(self.current_block.shape)):
for x in range(len(self.current_block.shape[0])):
if self.current_block.shape[y][x] == 'X':
x_pos = self.current_block.x + x
y_pos = self.current_block.y + y
if x_pos < 0 or x_pos >= GRID_WIDTH or y_pos >= GRID_HEIGHT or self.grid[y_pos][x_pos] != BLACK:
return True
return False
def place_block(self):
for y in range(len(self.current_block.shape)):
for x in range(len(self.current_block.shape[0])):
if self.current_block.shape[y][x] == 'X':
x_pos = self.current_block.x + x
y_pos = self.current_block.y + y
self.grid[y_pos][x_pos] = self.current_block.color
def clear_lines(self):
lines_cleared = 0
for y in range(GRID_HEIGHT):
if all([c != BLACK for c in self.grid[y]]):
self.grid.pop(y)
self.grid.insert(0, [BLACK for _ in range(GRID_WIDTH)])
lines_cleared += 1
self.score += lines_cleared * 100
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.current_block.rotate()
if self.check_collision():
self.current_block.rotate_back()
if event.key == pygame.K_DOWN:
self.current_block.move_down()
if self.check_collision():
self.current_block.move_up()
if event.key == pygame.K_LEFT:
self.current_block.move_left()
if self.check_collision():
self.current_block.move_right()
if event.key == pygame.K_RIGHT:
self.current_block.move_right()
if self.check_collision():
self.current_block.move_left()
def draw(self):
self.screen.fill(WHITE)
self.draw_grid()
self.draw_block(self.current_block)
self.draw_next_block(self.next_block)
self.draw_score()
pygame.display.update()
def draw_grid(self):
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
pygame.draw.rect(self.screen, self.grid[y][x], (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
def draw_block(self, block):
for y in range(len(block.shape)):
for x in range(len(block.shape[0])):
if block.shape[y][x] == 'X':
x_pos = block.x + x
y_pos = block.y + y
pygame.draw.rect(self.screen, block.color, (x_pos * BLOCK_SIZE, y_pos * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
def draw_next_block(self, block):
if block:
for y
for x in range(len(block.shape[0])):
if block.shape[y][x] == 'X':
x_pos = x + GRID_WIDTH + 1
y_pos = y + GRID_HEIGHT - 1
pygame.draw.rect(self.screen, block.color, (x_pos * BLOCK_SIZE, y_pos * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
def draw_score(self):
font = pygame.font.SysFont('arial', 30)
text = font.render('Score: ' + str(self.score), True, BLACK)
self.screen.blit(text, (GRID_WIDTH * BLOCK_SIZE + BLOCK_SIZE, 10))
def run(self):
while True:
self.clock.tick(FPS)
self.handle_events()
self.update()
self.draw()
if __name__ == '__main__':
game = Tetris()
game.run()
这个代码实现了一个基本的俄罗斯方块游戏,包括方块的下落、旋转、移动、碰撞检测,行的清除以及得分的计算和显示等功能。玩家可以通过键盘上下左右键来操作方块的移动和旋转。游戏会随着玩家的得分不断增加难度。
当方块无法下落时,游戏就会结束,并且在游戏窗口中显示最终得分。如果玩家想重新开始游戏,可以直接关闭游戏窗口并重新运行程序即可。
希望这个示例能够帮助你更好地理解如何使用 Python 和 Pygame 实现一个简单的俄罗斯方块游戏。