使用Python開發經典俄羅斯方塊游戲
在這篇教程中,我們將學習如何使用Python和Pygame庫開發一個經典的俄羅斯方塊游戲。這個項目將幫助你理解游戲開發的基本概念,包括圖形界面、用戶輸入處理、碰撞檢測等重要內容。
項目概述
我們將實現以下功能:
- 創建游戲主窗口和網格系統
- 實現不同形狀的方塊(Tetromino)
- 添加方塊旋轉和移動功能
- 實現行消除機制
- 添加分數系統
- 實現游戲結束判定
所需知識
- Python基礎編程
- Pygame庫的基本使用
- 面向對象編程概念
- 基本的游戲開發原理
完整代碼實現
import pygame
import random# 初始化Pygame
pygame.init()# 顏色定義
COLORS = [(0, 0, 0), # 黑色(背景)(120, 37, 179), # 紫色(100, 179, 179), # 青色(80, 34, 22), # 褐色(80, 134, 22), # 綠色(180, 34, 22), # 紅色(180, 34, 122), # 粉色
]# 方塊形狀定義
SHAPES = [[[1, 5, 9, 13], [4, 5, 6, 7]], # I[[1, 2, 5, 9], [0, 4, 5, 6], [1, 5, 9, 8], [4, 5, 6, 10]], # J[[1, 2, 6, 10], [5, 6, 7, 9], [2, 6, 10, 11], [3, 5, 6, 7]], # L[[1, 2, 5, 6]], # O[[5, 6, 8, 9], [1, 5, 6, 10]], # S[[1, 4, 5, 6], [1, 4, 5, 9], [4, 5, 6, 9], [1, 5, 6, 9]], # T[[4, 5, 9, 10], [2, 6, 5, 9]] # Z
]class Tetris:def __init__(self, height, width):self.height = heightself.width = widthself.field = []self.score = 0self.state = "start"self.figure = Noneself.x = 0self.y = 0self.init_field()def init_field(self):self.field = []for i in range(self.height):new_line = []for j in range(self.width):new_line.append(0)self.field.append(new_line)def new_figure(self):self.figure = Figure(3, 0)def intersects(self):intersection = Falsefor i in range(4):for j in range(4):if i * 4 + j in self.figure.image():if (i + self.figure.y > self.height - 1 orj + self.figure.x > self.width - 1 orj + self.figure.x < 0 orself.field[i + self.figure.y][j + self.figure.x] > 0):intersection = Truereturn intersectiondef freeze(self):for i in range(4):for j in range(4):if i * 4 + j in self.figure.image():self.field[i + self.figure.y][j + self.figure.x] = self.figure.colorself.break_lines()self.new_figure()if self.intersects():self.state = "gameover"def break_lines(self):lines = 0for i in range(1, self.height):zeros = 0for j in range(self.width):if self.field[i][j] == 0:zeros += 1if zeros == 0:lines += 1for i1 in range(i, 1, -1):for j in range(self.width):self.field[i1][j] = self.field[i1-1][j]self.score += lines ** 2def go_space(self):while not self.intersects():self.figure.y += 1self.figure.y -= 1self.freeze()def go_down(self):self.figure.y += 1if self.intersects():self.figure.y -= 1self.freeze()def go_side(self, dx):old_x = self.figure.xself.figure.x += dxif self.intersects():self.figure.x = old_xdef rotate(self):old_rotation = self.figure.rotationself.figure.rotate()if self.intersects():self.figure.rotation = old_rotationclass Figure:def __init__(self, x, y):self.x = xself.y = yself.type = random.randint(0, len(SHAPES) - 1)self.color = random.randint(1, len(COLORS) - 1)self.rotation = 0def image(self):return SHAPES[self.type][self.rotation]def rotate(self):self.rotation = (self.rotation + 1) % len(SHAPES[self.type])# 游戲參數設置
GAME_HEIGHT = 20
GAME_WIDTH = 10
TILE_SIZE = 30
GAME_RES = GAME_WIDTH * TILE_SIZE, GAME_HEIGHT * TILE_SIZE
FPS = 60# 初始化游戲窗口
pygame.init()
screen = pygame.display.set_mode(GAME_RES)
pygame.display.set_caption("俄羅斯方塊")
clock = pygame.time.Clock()# 創建游戲對象
game = Tetris(GAME_HEIGHT, GAME_WIDTH)
counter = 0
pressing_down = Falsewhile True:if game.figure is None:game.new_figure()counter += 1if counter > 100000:counter = 0if counter % (FPS // (game.score + 1) // 2 + 1) == 0 or pressing_down:if game.state == "start":game.go_down()for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()exit()if event.type == pygame.KEYDOWN:if event.key == pygame.K_UP:game.rotate()if event.key == pygame.K_DOWN:pressing_down = Trueif event.key == pygame.K_LEFT:game.go_side(-1)if event.key == pygame.K_RIGHT:game.go_side(1)if event.key == pygame.K_SPACE:game.go_space()if event.key == pygame.K_ESCAPE:pygame.quit()exit()if event.type == pygame.KEYUP:if event.key == pygame.K_DOWN:pressing_down = Falsescreen.fill((0, 0, 0))for i in range(game.height):for j in range(game.width):if game.field[i][j] > 0:pygame.draw.rect(screen, COLORS[game.field[i][j]],[j * TILE_SIZE, i * TILE_SIZE, TILE_SIZE - 1, TILE_SIZE - 1])if game.figure is not None:for i in range(4):for j in range(4):if i * 4 + j in game.figure.image():pygame.draw.rect(screen, COLORS[game.figure.color],[(j + game.figure.x) * TILE_SIZE,(i + game.figure.y) * TILE_SIZE,TILE_SIZE - 1, TILE_SIZE - 1])pygame.display.flip()clock.tick(FPS)
代碼詳解
1. 基礎設置和常量定義
import pygame
import random# 顏色定義
COLORS = [(0, 0, 0), # 黑色(背景)(120, 37, 179), # 紫色# ... 其他顏色
]# 方塊形狀定義
SHAPES = [[[1, 5, 9, 13], [4, 5, 6, 7]], # I形# ... 其他形狀
]
這部分代碼定義了:
- 游戲使用的顏色列表
- 七種不同的俄羅斯方塊形狀
- 每種形狀的旋轉狀態
2. Tetris類
Tetris類是游戲的核心,包含了以下主要功能:
- 游戲場地初始化
- 方塊生成和移動
- 碰撞檢測
- 消行處理
- 游戲狀態管理
3. Figure類
Figure類負責管理方塊對象,包括:
- 方塊的位置
- 方塊的類型和顏色
- 方塊的旋轉狀態
4. 游戲主循環
主循環處理:
- 用戶輸入
- 游戲狀態更新
- 畫面渲染
游戲功能
-
基本操作
- 左右方向鍵:移動方塊
- 上方向鍵:旋轉方塊
- 下方向鍵:加速下落
- 空格鍵:直接落到底部
-
計分系統
- 同時消除的行數越多,得分越高
- 分數影響方塊下落速度
-
游戲結束條件
- 新方塊無法放置時游戲結束
運行效果
運行代碼后,你將看到:
- 一個黑色背景的游戲窗口
- 不同顏色的方塊隨機出現
- 方塊可以移動和旋轉
- 完整的行會被消除
- 游戲分數實時更新
擴展優化建議
你可以通過以下方式改進這個游戲:
-
界面優化
- 添加開始菜單
- 顯示下一個方塊預覽
- 添加分數顯示界面
- 添加游戲結束畫面
-
功能增強
- 添加音效
- 實現方塊陰影提示
- 添加暫停功能
- 實現存檔功能
-
游戲性提升
- 添加難度級別
- 實現連擊獎勵機制
- 添加特殊方塊效果
注意事項
- 運行前確保已安裝Python和Pygame庫
- 可以通過pip安裝Pygame:
pip install pygame
- 游戲參數(如窗口大小、速度等)可以根據需要調整
- 建議在開發時多添加注釋,便于后續維護