很高兴为您解答这个问题。以下是Python小游戏之300行代码实现俄罗斯方块的源代码:
```python
import pygame
import random
# 初始化游戏
pygame.init()
# 颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# 屏幕大小
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 800
# 方块大小
BLOCK_SIZE = 30
# 方块类型及其形状
BLOCKS = {
"I": [(0, 0), (1, 0), (2, 0), (3, 0)],
"J": [(0, 0), (0, 1), (1, 1), (2, 1)],
"L": [(2, 0), (0, 1), (1, 1), (2, 1)],
"O": [(0, 0), (1, 0), (0, 1), (1, 1)],
"S": [(1, 0), (2, 0), (0, 1), (1, 1)],
"T": [(1, 0), (0, 1), (1, 1), (2, 1)],
"Z": [(0, 0), (1, 0), (1, 1), (2, 1)]
}
# 方向
DIRECTIONS = {
"LEFT": (-1, 0),
"RIGHT": (1, 0),
"DOWN": (0, 1),
"UP": (0, -1)
}
# 游戏状态
STATE_RUNNING = 0
STATE_PAUSED = 1
STATE_GAME_OVER = 2
# 字体
FONT = pygame.font.SysFont(None, 50)
class Block:
def __init__(self, x, y, block_type):
self.x = x
self.y = y
self.block_type = block_type
self.shape = BLOCKS[block_type]
self.color = self.get_color()
def get_color(self):
if self.block_type == "I":
return BLUE
elif self.block_type == "J":
return RED
elif self.block_type == "L":
return GREEN
elif self.block_type == "O":
return BLUE
elif self.block_type == "S":
return RED
elif self.block_type == "T":
return GREEN
elif self.block_type == "Z":
return BLUE
def move(self, direction):
dx, dy = DIRECTIONS[direction]
self.x += dx
self.y += dy
def rotate(self):
new_shape = []
for x, y in self.shape:
new_x = y
new_y = -x
new_shape.append((new_x, new_y))
self.shape = new_shape
class Board:
def __init__(self):
self.width = SCREEN_WIDTH // BLOCK_SIZE
self.height = SCREEN_HEIGHT // BLOCK_SIZE
self.grid = [[BLACK for _ in range(self.width)] for _ in range(self.height)]
self.current_block = self.generate_new_block()
self.next_block = self.generate_new_block()
self.score = 0
self.state = STATE_RUNNING
def generate_new_block(self):
block_type = random.choice(list(BLOCKS.keys()))
x = self.width // 2 - 2
y = 0
return Block(x, y, block_type)
def update(self):
if self.state == STATE_RUNNING:
if self.is_valid(self.current_block, 0, 1):
self.current_block.move("DOWN")
else:
self.lock_block()
self.clear_lines()
self.current_block = self.next_block
self.next_block = self.generate_new_block()
if not self.is_valid(self.current_block, 0, 0):
self.state = STATE_GAME_OVER
def lock_block(self):
for x, y in self.current_block.shape:
self.grid[self.current_block.y + y][self.current_block.x + x] = self.current_block.color
def clear_lines(self):
lines_cleared = 0
for y in range(self.height):
if all([self.grid[y][x] != BLACK for x in range(self.width)]):
for y1 in range(y, 0, -1):
for x in range(self.width):
self.grid[y1][x] = self.grid[y1 - 1][x]
for x in range(self.width):
self.grid[0][x] = BLACK
lines_cleared += 1
self.score += lines_cleared ** 2
def move_current_block(self, direction):
if self.is_valid(self.current_block, *DIRECTIONS[direction]):
self.current_block.move(direction)
def rotate_current_block(self):
if self.is_valid(self.current_block, 0, 0, True):
self.current_block.rotate()
def is_valid(self, block, dx, dy, rotated=False):
if rotated:
new_shape = []
for x, y in block.shape:
new_x = y
new_y = -x
new_shape.append((new_x, new_y))
else:
new_shape = block.shape
for x, y in new_shape:
new_x = block.x + x + dx
new_y = block.y + y + dy
if not (0 <= new_x < self.width and 0 <= new_y < self.height):
return False
if self.grid[new_y][new_x] != BLACK:
return False
return True
def draw(self, screen):
for y in range(self.height):
for x in range(self.width):
pygame.draw.rect(screen, self.grid[y][x],
(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 0)
for x, y in self.current_block.shape:
pygame.draw.rect(screen, self.current_block.color,
((self.current_block.x + x) * BLOCK_SIZE, (self.current_block.y + y) * BLOCK_SIZE,
BLOCK_SIZE, BLOCK_SIZE), 0)
text = FONT.render(f"Score: {self.score}", True, WHITE)
screen.blit(text, (10, 10))
text = FONT.render("Next Block:", True, WHITE)
screen.blit(text, (400, 10))
for x, y in self.next_block.shape:
pygame.draw.rect(screen, self.next_block.color,
((x + 16) * BLOCK_SIZE, (y + 3) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 0)
def main():
# 创建屏幕
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Tetris")
# 创建时钟
clock = pygame.time.Clock()
# 创建棋盘
board = Board()
# 游戏循环
while True:
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
board.move_current_block("LEFT")
elif event.key == pygame.K_RIGHT:
board.move_current_block("RIGHT")
elif event.key == pygame.K_DOWN:
board.move_current_block("DOWN")
elif event.key == pygame.K_UP:
board.rotate_current_block()
elif event.key == pygame.K_SPACE:
board.state = STATE_PAUSED if board.state == STATE_RUNNING else STATE_RUNNING
# 更新游戏状态
board.update()
# 绘制屏幕
screen.fill(BLACK)
board.draw(screen)
# 显示屏幕
pygame.display.update()
# 控制帧率
clock.tick(10)
if __name__ == "__main__":
main()
```
希望能够帮到您!