Python写俄罗斯方块300行
时间: 2023-06-10 12:07:51 浏览: 86
以下是一个简单的 Python 实现俄罗斯方块的代码,共约 300 行:
```
import pygame
import random
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (128, 128, 128)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
CYAN = (0, 255, 255)
MAGENTA = (255, 0, 255)
# 游戏参数
BLOCK_SIZE = 30
BOARD_WIDTH = 10
BOARD_HEIGHT = 20
SCREEN_WIDTH = BLOCK_SIZE * (BOARD_WIDTH + 6)
SCREEN_HEIGHT = BLOCK_SIZE * BOARD_HEIGHT
# 方块定义
SHAPES = {
"I": [[1, 1, 1, 1]],
"J": [[1, 0, 0], [1, 1, 1]],
"L": [[0, 0, 1], [1, 1, 1]],
"O": [[1, 1], [1, 1]],
"S": [[0, 1, 1], [1, 1, 0]],
"T": [[0, 1, 0], [1, 1, 1]],
"Z": [[1, 1, 0], [0, 1, 1]]
}
# 游戏状态定义
IDLE = 0
START = 1
PLAYING = 2
PAUSED = 3
GAME_OVER = 4
class Board:
def __init__(self, width, height):
self.width = width
self.height = height
self.grid = [[0 for x in range(width)] for y in range(height)]
self.current_shape = None
self.current_x = 0
self.current_y = 0
self.score = 0
self.level = 1
self.lines_cleared = 0
self.next_shape = None
def new_shape(self):
shape = random.choice(list(SHAPES.keys()))
self.current_shape = SHAPES[shape]
self.current_x = self.width // 2 - len(self.current_shape[0]) // 2
self.current_y = 0
def move(self, dx, dy):
if self.current_shape is None:
return False
x = self.current_x + dx
y = self.current_y + dy
if x < 0 or x + len(self.current_shape[0]) > self.width or \
y < 0 or y + len(self.current_shape) > self.height:
return False
for i in range(len(self.current_shape)):
for j in range(len(self.current_shape[i])):
if self.current_shape[i][j] and self.grid[y+i][x+j]:
return False
self.current_x = x
self.current_y = y
return True
def rotate(self):
if self.current_shape is None:
return False
new_shape = []
for i in range(len(self.current_shape[0])):
new_row = []
for j in range(len(self.current_shape)):
new_row.append(self.current_shape[len(self.current_shape)-j-1][i])
new_shape.append(new_row)
if self.current_x + len(new_shape[0]) > self.width or \
self.current_y + len(new_shape) > self.height:
return False
for i in range(len(new_shape)):
for j in range(len(new_shape[i])):
if new_shape[i][j] and self.grid[self.current_y+i][self.current_x+j]:
return False
self.current_shape = new_shape
return True
def drop(self):
if self.current_shape is None:
return False
while self.move(0, 1):
pass
return True
def place(self):
if self.current_shape is None:
return False
for i in range(len(self.current_shape)):
for j in range(len(self.current_shape[i])):
if self.current_shape[i][j]:
self.grid[self.current_y+i][self.current_x+j] = 1
self.current_shape = None
return True
def clear_lines(self):
lines_cleared = 0
for i in range(self.height):
if all(self.grid[i]):
lines_cleared += 1
for j in range(i, 0, -1):
self.grid[j] = self.grid[j-1][:]
self.grid[0] = [0] * self.width
self.lines_cleared += lines_cleared
self.score += lines_cleared ** 2 * 100
self.level = (self.lines_cleared // 10) + 1
def update(self):
if self.current_shape is None:
self.new_shape()
if not self.move(0, 1):
self.place()
self.clear_lines()
self.next_shape = SHAPES[random.choice(list(SHAPES.keys()))]
def draw(self, surface):
for i in range(self.height):
for j in range(self.width):
if self.grid[i][j]:
pygame.draw.rect(surface, GRAY, (j*BLOCK_SIZE, i*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
if self.current_shape is not None:
for i in range(len(self.current_shape)):
for j in range(len(self.current_shape[i])):
if self.current_shape[i][j]:
pygame.draw.rect(surface, GRAY, ((self.current_x+j)*BLOCK_SIZE, (self.current_y+i)*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
if self.next_shape is not None:
for i in range(len(self.next_shape)):
for j in range(len(self.next_shape[i])):
if self.next_shape[i][j]:
pygame.draw.rect(surface, GRAY, ((self.width+j+2)*BLOCK_SIZE, (i+2)*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
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.board = Board(BOARD_WIDTH, BOARD_HEIGHT)
self.state = IDLE
self.font = pygame.font.SysFont(None, 48)
self.score_text = self.font.render("Score: 0", True, WHITE)
self.level_text = self.font.render("Level: 1", True, WHITE)
self.lines_text = self.font.render("Lines: 0", True, WHITE)
def start(self):
self.state = START
def pause(self):
self.state = PAUSED
def resume(self):
self.state = PLAYING
def quit(self):
self.state = GAME_OVER
def run(self):
while self.state != GAME_OVER:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
self.board.rotate()
elif event.key == pygame.K_DOWN:
self.board.move(0, 1)
elif event.key == pygame.K_LEFT:
self.board.move(-1, 0)
elif event.key == pygame.K_RIGHT:
self.board.move(1, 0)
elif event.key == pygame.K_ESCAPE:
if self.state == PLAYING:
self.pause()
elif self.state == PAUSED:
self.resume()
if self.state == START:
self.board = Board(BOARD_WIDTH, BOARD_HEIGHT)
self.state = PLAYING
elif self.state == PLAYING:
self.board.update()
self.screen.fill(BLACK)
self.board.draw(self.screen)
self.score_text = self.font.render("Score: " + str(self.board.score), True, WHITE)
self.level_text = self.font.render("Level: " + str(self.board.level), True, WHITE)
self.lines_text = self.font.render("Lines: " + str(self.board.lines_cleared), True, WHITE)
self.screen.blit(self.score_text, (SCREEN_WIDTH - self.score_text.get_width() - 10, 10))
self.screen.blit(self.level_text, (SCREEN_WIDTH - self.level_text.get_width() - 10, 60))
self.screen.blit(self.lines_text, (SCREEN_WIDTH - self.lines_text.get_width() - 10, 110))
elif self.state == PAUSED:
self.screen.fill(BLACK)
paused_text = self.font.render("PAUSED", True, WHITE)
self.screen.blit(paused_text, ((SCREEN_WIDTH - paused_text.get_width()) // 2, (SCREEN_HEIGHT - paused_text.get_height()) // 2))
pygame.display.update()
self.clock.tick(30)
pygame.quit()
if __name__ == "__main__":
game = Game()
game.start()
game.run()
```
该代码使用了 Pygame 库来实现游戏窗口和图形的绘制,主要分为两个类:Board 和 Game。Board 类表示游戏的主要逻辑,包括方块的移动、旋转、下落和消除等。Game 类则表示游戏的整体流程和状态,包括游戏的开始、暂停、继续和结束等。在代码中还包括了一些常量、颜色定义和游戏参数等。
阅读全文