游戏一:俄罗斯方块简易版

1984 年,苏联工程师阿列克谢・帕基特诺夫在电脑上敲下一串代码,无意间创造出了风靡全球的游戏 ------ 俄罗斯方块。这个由 "tetra"(希腊语,意为 "四")与 "Tennis"(帕基特诺夫喜爱的网球)组合而成的名字,带着数学与运动的奇妙融合,开启了一场跨越时代的方块冒险。

作为童年的回忆,每个游戏少年都希望有一款自己的俄罗斯方块游戏,接下来我们就开始"tetra"的创作之旅。

成品示例

完整代码

import pygame

import random

初始化 Pygame

pygame.init()

定义颜色

BLACK = (0, 0, 0)

WHITE = (255, 255, 255)

GRAY = (128, 128, 128)

RED = (255, 0, 0)

游戏窗口设置

WIDTH = 300

HEIGHT = 600

BLOCK_SIZE = 30

screen = pygame.display.set_mode((WIDTH, HEIGHT))

pygame.display.set_caption("俄罗斯方块")

定义方块形状

SHAPES = [

\[1, 1, 1, 1\]\], \[\[1, 1\], \[1, 1\]\], \[\[1, 1, 0\], \[0, 1, 1\]\], \[\[0, 1, 1\], \[1, 1, 0\]\], \[\[1, 1, 1\], \[0, 1, 0\]\], \[\[1, 1, 1\], \[1, 0, 0\]\], \[\[1, 1, 1\], \[0, 0, 1\]

]

生成随机方块

def new_piece():

shape = random.choice(SHAPES)

return {

'x': WIDTH // 2 // BLOCK_SIZE - len(shape[0]) // 2,

'y': 0,

'shape': shape

}

绘制方块

def draw_piece(piece):

for y, row in enumerate(piece['shape']):

for x, val in enumerate(row):

if val:

pygame.draw.rect(screen, WHITE, [

(piece['x'] + x) * BLOCK_SIZE,

(piece['y'] + y) * BLOCK_SIZE,

BLOCK_SIZE, BLOCK_SIZE

])

pygame.draw.rect(screen, GRAY, [

(piece['x'] + x) * BLOCK_SIZE,

(piece['y'] + y) * BLOCK_SIZE,

BLOCK_SIZE, BLOCK_SIZE

], 1)

检查方块是否越界或碰撞

def is_collision(board, piece):

for y, row in enumerate(piece['shape']):

for x, val in enumerate(row):

if val:

new_x = piece['x'] + x

new_y = piece['y'] + y

if new_x < 0 or new_x >= WIDTH // BLOCK_SIZE or new_y >= HEIGHT // BLOCK_SIZE or (new_y >= 0 and board[new_y][new_x]):

return True

return False

将方块合并到游戏面板

def merge(board, piece):

for y, row in enumerate(piece['shape']):

for x, val in enumerate(row):

if val:

board[piece['y'] + y][piece['x'] + x] = 1

return board

检查并消除满行

def clear_lines(board):

full_lines = []

for y, row in enumerate(board):

if all(row):

full_lines.append(y)

for line in full_lines:

del board[line]

board = [[0] * (WIDTH // BLOCK_SIZE)] + board

return board, len(full_lines)

初始化游戏面板

board = [[0] * (WIDTH // BLOCK_SIZE) for _ in range(HEIGHT // BLOCK_SIZE)]

score = 0

font = pygame.font.Font(None, 36)

主游戏循环

running = True

current_piece = new_piece()

clock = pygame.time.Clock()

fall_time = 0

fall_speed = 0.3

... 前面的代码保持不变 ...

while running:

控制方块下落速度

fall_time += clock.get_rawtime()

clock.tick()

if fall_time / 1000 >= fall_speed:

fall_time = 0

修改变量名,避免和函数名冲突

new_piece_data = {

'x': current_piece['x'],

'y': current_piece['y'] + 1,

'shape': current_piece['shape']

}

if not is_collision(board, new_piece_data):

current_piece = new_piece_data

else:

board = merge(board, current_piece)

board, cleared_lines = clear_lines(board)

score += cleared_lines * 100

current_piece = new_piece()

if is_collision(board, current_piece):

running = False

for event in pygame.event.get():

if event.type == pygame.QUIT:

running = False

elif event.type == pygame.KEYDOWN:

if event.key == pygame.K_LEFT:

修改变量名,避免和函数名冲突

new_piece_data = {

'x': current_piece['x'] - 1,

'y': current_piece['y'],

'shape': current_piece['shape']

}

if not is_collision(board, new_piece_data):

current_piece = new_piece_data

elif event.key == pygame.K_RIGHT:

修改变量名,避免和函数名冲突

new_piece_data = {

'x': current_piece['x'] + 1,

'y': current_piece['y'],

'shape': current_piece['shape']

}

if not is_collision(board, new_piece_data):

current_piece = new_piece_data

elif event.key == pygame.K_DOWN:

修改变量名,避免和函数名冲突

new_piece_data = {

'x': current_piece['x'],

'y': current_piece['y'] + 1,

'shape': current_piece['shape']

}

if not is_collision(board, new_piece_data):

current_piece = new_piece_data

elif event.key == pygame.K_UP:

简单的旋转逻辑

rotated_shape = list(map(list, zip(*reversed(current_piece['shape']))))

修改变量名,避免和函数名冲突

new_piece_data = {

'x': current_piece['x'],

'y': current_piece['y'],

'shape': rotated_shape

}

if not is_collision(board, new_piece_data):

current_piece = new_piece_data

screen.fill(BLACK)

... 后面的代码保持不变 ...

绘制游戏面板

for y, row in enumerate(board):

for x, val in enumerate(row):

if val:

pygame.draw.rect(screen, WHITE, [

x * BLOCK_SIZE,

y * BLOCK_SIZE,

BLOCK_SIZE, BLOCK_SIZE

])

pygame.draw.rect(screen, GRAY, [

x * BLOCK_SIZE,

y * BLOCK_SIZE,

BLOCK_SIZE, BLOCK_SIZE

], 1)

draw_piece(current_piece)

绘制得分

score_text = font.render(f"Score: {score}", True, RED)

screen.blit(score_text, (10, 10))

pygame.display.flip()

pygame.quit()

相关推荐
2601_9503160617 分钟前
塞尔达攻略+塞尔达设定集+塞尔达传说攻略
游戏·pdf·电视盒子
号码认证服务1 小时前
“二次放号”来电有旧标记?为新启用的企业号码开通认证
游戏·金融·社交电子·健康医疗·娱乐·传媒·教育电商
皮皮虾12342 小时前
龙珠激斗多开自动挂机搬砖攻略教程
网络·游戏
开开心心就好2 小时前
带可视化界面的目录文件合并工具
java·运维·科技·游戏·tomcat·自动化·powerpoint
wanhengidc2 小时前
云手机 游戏多开不卡顿
运维·服务器·网络·安全·web安全·游戏·智能手机
StarChainTech2 小时前
先享后付,正在悄悄改变电商的“信任游戏”
大数据·人工智能·游戏·微信小程序·小程序·软件需求
FairGuard手游加固2 小时前
FairGuard全链路反外挂方案,破解游戏安全困局
大数据·安全·游戏
邪修king2 小时前
UE5 TA 核心修炼:材质与纹理艺术全解 —— 从 PBR 理论到工业级材质实战
c++·后端·游戏·ue5·材质
草木深雨纷纷18 小时前
星露谷物语整合包手机版下载2026最新版下载分享(里奇赛德村+东斯卡普|拖拉机|自动化+主题美化+功能+汉化+SVE)
游戏·智能手机·游戏程序
笨鸟先飞的橘猫1 天前
基于Skynet的分布式游戏场景题:大型MMO的跨服战场系统设计
分布式·学习·游戏·面试·lua