用python生成一个俄罗斯方块的游戏 要有注释
时间: 2024-03-17 20:47:01 浏览: 72
好的,下面是一个用Python实现俄罗斯方块游戏的代码,并附有注释:
```python
import pygame
import random
# 定义方块的大小
BLOCK_SIZE = 20
# 定义游戏区域的大小
SCREEN_WIDTH = BLOCK_SIZE * 10
SCREEN_HEIGHT = BLOCK_SIZE * 20
# 定义颜色常量
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (128, 128, 128)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# 定义俄罗斯方块的形状
SHAPE_I = [[[1, 1, 1, 1]],
[[1],
[1],
[1],
[1]]]
SHAPE_J = [[[0, 1, 0],
[0, 1, 0],
[1, 1, 0]],
[[1, 0, 0],
[1, 1, 1]]]
SHAPE_L = [[[0, 1, 0],
[0, 1, 0],
[0, 1, 1]],
[[1, 1, 1],
[1, 0, 0]]]
SHAPE_O = [[[1, 1],
[1, 1]]]
SHAPE_S = [[[0, 1, 1],
[1, 1, 0]],
[[1, 0],
[1, 1],
[0, 1]]]
SHAPE_T = [[[0, 1, 0],
[1, 1, 1]],
[[1, 0],
[1, 1],
[1, 0]],
[[1, 1, 1],
[0, 1, 0]],
[[0, 1],
[1, 1],
[0, 1]]]
SHAPE_Z = [[[1, 1, 0],
[0, 1, 1]],
[[0, 1],
[1, 1],
[1, 0]]]
# 所有形状放在一个列表里
SHAPES = [SHAPE_I, SHAPE_J, SHAPE_L, SHAPE_O, SHAPE_S, SHAPE_T, SHAPE_Z]
class Block:
"""方块类"""
def __init__(self, screen, shape):
self.screen = screen
self.shape = shape
self.color = random.choice([RED, GREEN, BLUE])
# 随机选择一个形状
self.current_shape = random.choice(shape)
# 获取当前形状的行数和列数
self.rows = len(self.current_shape)
self.cols = len(self.current_shape[0])
# 随机选择一个起始位置
self.x = random.randint(0, SCREEN_WIDTH // BLOCK_SIZE - self.cols)
self.y = -self.rows
# 记录已经落下的方块
self.frozen_blocks = []
def draw(self):
"""绘制方块"""
for row in range(self.rows):
for col in range(self.cols):
if self.current_shape[row][col] == 1:
x = self.x + col
y = self.y + row
pygame.draw.rect(self.screen, self.color,
(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
def move_down(self):
"""向下移动"""
self.y += 1
def move_left(self):
"""向左移动"""
self.x -= 1
def move_right(self):
"""向右移动"""
self.x += 1
def rotate(self):
"""旋转"""
# 保存旧的形状
old_shape = self.current_shape
# 生成新的形状
new_shape = [[self.current_shape[j][i] for j in range(self.rows - 1, -1, -1)]
for i in range(self.cols)]
# 如果旋转后的形状会与已经落下的方块重叠,则不进行旋转
if self.will_collide(self.x, self.y, new_shape):
self.current_shape = old_shape
else:
self.current_shape = new_shape
self.rows, self.cols = self.cols, self.rows
def will_collide(self, x, y, shape):
"""判断是否会发生碰撞"""
for row in range(len(shape)):
for col in range(len(shape[0])):
if shape[row][col] == 1:
if y + row >= SCREEN_HEIGHT // BLOCK_SIZE or x + col < 0 or x + col >= SCREEN_WIDTH // BLOCK_SIZE:
# 越界
return True
if (x + col, y + row) in self.frozen_blocks:
# 与已经落下的方块重叠
return True
return False
def freeze(self):
"""将方块固定在底部"""
for row in range(self.rows):
for col in range(self.cols):
if self.current_shape[row][col] == 1:
x = self.x + col
y = self.y + row
self.frozen_blocks.append((x, y))
def is_game_over(self):
"""判断游戏是否结束"""
for block in self.frozen_blocks:
if block[1] < 0:
return True
return False
class Game:
"""游戏类"""
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Tetris")
self.clock = pygame.time.Clock()
self.block = Block(self.screen, SHAPES)
self.score = 0
self.font = pygame.font.Font(None, 30)
def run(self):
"""游戏主循环"""
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.block.move_left()
elif event.key == pygame.K_RIGHT:
self.block.move_right()
elif event.key == pygame.K_DOWN:
self.block.move_down()
elif event.key == pygame.K_UP:
self.block.rotate()
# 判断是否发生碰撞
if self.block.will_collide(self.block.x, self.block.y + 1, self.block.current_shape):
self.block.freeze()
self.block = Block(self.screen, SHAPES)
# 判断是否有满行
self.check_full_rows()
# 判断游戏是否结束
if self.block.is_game_over():
self.game_over()
return
# 绘制游戏区域
self.screen.fill(BLACK)
self.draw_grid()
# 绘制已经落下的方块
for block in self.block.frozen_blocks:
pygame.draw.rect(self.screen, GRAY,
(block[0] * BLOCK_SIZE, block[1] * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
# 绘制当前方块
self.block.draw()
# 显示得分
score_text = self.font.render("Score: {}".format(self.score), True, WHITE)
self.screen.blit(score_text, (10, 10))
pygame.display.update()
self.clock.tick(10)
def draw_grid(self):
"""绘制游戏区域的网格"""
for x in range(0, SCREEN_WIDTH, BLOCK_SIZE):
pygame.draw.line(self.screen, GRAY, (x, 0), (x, SCREEN_HEIGHT))
for y in range(0, SCREEN_HEIGHT, BLOCK_SIZE):
pygame.draw.line(self.screen, GRAY, (0, y), (SCREEN_WIDTH, y))
def check_full_rows(self):
"""检查是否有满行"""
full_rows = []
for row in range(SCREEN_HEIGHT // BLOCK_SIZE):
blocks_in_row = [(block[0], block[1]) for block in self.block.frozen_blocks if block[1] == row]
if len(blocks_in_row) == SCREEN_WIDTH // BLOCK_SIZE:
full_rows.append(row)
# 如果有满行,则删除满行并计分
if full_rows:
full_rows.sort(reverse=True)
for row in full_rows:
self.block.frozen_blocks = [(block[0], block[1] + 1) if block[1] < row else block
for block in self.block.frozen_blocks]
self.score += len(full_rows) * 100
def game_over(self):
"""游戏结束"""
game_over_text = self.font.render("Game Over", True, WHITE)
self.screen.blit(game_over_text, (SCREEN_WIDTH // 2 - game_over_text.get_width() // 2, SCREEN_HEIGHT // 2))
pygame.display.update()
pygame.time.delay(2000)
if __name__ == '__main__':
game = Game()
game.run()
```
以上就是一个用Python实现俄罗斯方块游戏的代码,注释也比较详细,希望能够帮助你理解。
阅读全文