博主介绍: 27dCnc
专题 : python项目详细讲解
☆*: .。. o(≧▽≦)o .。.:*☆
游戏区域的表示:使用二维数组或列表来表示游戏区域的网格。每个元素可以表示一个方块的状态,如是否被占据。
方块的表示与移动:定义不同形状的方块,并使用坐标来表示方块在游戏区域中的位置。实现方块的移动(左右移动、旋转)以及碰撞检测,确保方块在合法范围内移动。
方块的下落与固定:实现方块的自动下落和手动下落功能,以及判断方块是否需要固定在游戏区域中。
行消除:检测并消除已填满的行,更新游戏区域的状态,并计算得分。
游戏结束条件:判断游戏是否结束,例如当方块堆积到游戏区域的顶部时。
用户输入与界面交互:监听用户的键盘输入或者鼠标点击等事件,响应用户的操作,并更新游戏区域的状态。
游戏循环:使用游戏循环来控制游戏的进行,包括更新游戏状态、绘制游戏界面、处理用户输入等。
pygame是图形化页面可以用于
绘制窗口
和绘制方块
用相应坐标表示方块类型
- backgroud 用于储存方块绘制坐标
- gameover 用于储存下落完成的方块
- press 用于控制加速
pygame.init() 用于初始化
pygame.display.set_mode((400, 800)) 设置窗口大小
list(random.choice(all_block)) 下落方块random.choice(all_block)
随机在all_block
方块中选择
详细解释
首先,通过
for row, column in select_block:
遍历select_block
列表中的每个元素,其中每个元素都是一个包含方块位置信息的列表,例如[row, column]
。
然后,将
row
和column
分别加上变量y
和x
的值。这里的y
和x
可能表示方块在背景中的偏移量,用于确定方块的实际位置。
接下来,通过
if backgroud[row][column] == 1:
条件语句判断背景中对应位置的值是否为 1。如果是,说明当前方块与背景中已有的方块重叠,即发生碰撞。
如果发生碰撞,将值为 1 的元素添加到
gameover
列表中,以表示游戏结束。
综上所述,这段代码的逻辑是遍历选中的方块中的每个位置,将其与背景中对应位置的值进行比较,如果发生碰撞,则将游戏结束的标志(值为 1)添加到
gameover
列表中。
pygame.draw.rect(screen, (255, 165, 0), (column * 40, 800 - row * 40, 38, 38))
用pygame的绘制函数绘制方块大小和方块颜色
分别用俩for一个用于绘制动态block
一个用于绘制静态block
用一个数组储存旋转后的方块顺便规定旋转的范围,控制方块移动范围
方块自动下落
键盘输入事件:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
press = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
rotate() # 代码无法向下加速的原因是在处理pygame.KEYUP事件时,判断按键是否为向下键时使用了错误的语句。
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT: # 具体来说,在代码中,当检测到键盘按键释放事件(pygame.KEYUP)时,
# 判断按键是否为向下键时应该使用event.key
# 而不是event.type。
move(1) # 因此,将event.type改为event.key即可解决这个问题
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
move(-1)
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
press = False
通过键盘输入事件可以让方块移动手动移动
以下是一些在Pygame中常用的函数和模块:
pygame.init():初始化Pygame库。
pygame.display.set_mode():创建游戏窗口。
pygame.event.get():获取所有待处理的事件。
pygame.event.pump():处理所有待处理的事件。
pygame.key.get_pressed():检测按键状态。
pygame.draw.rect():绘制矩形。
pygame.draw.polygon():绘制多边形。
pygame.draw.line():绘制线段。
pygame.time.Clock():控制游戏帧率。
pygame.font.Font():加载字体文件。
pygame.font.render():渲染文本。
pygame.mixer.Sound():加载声音文件。
pygame.mixer.music.load():加载音乐文件。
pygame.mixer.music.play():播放音乐。
pygame.image.load():加载图像文件。
pygame.transform.scale():缩放图像。
这些函数和模块是Pygame库中常用的功能,可以帮助你实现俄罗斯方块游戏的各个方面,如绘制游戏界面、处理用户输入、播放音效和音乐等。你可以根据具体需求,在代码中适时调用这些函数和模块来完成相应的功能。
这些就是pygame我们要用的函数
代码
import pygame, sys
import random
# 物块的形状是二维数组
all_block = [
[[0, 0], [0, 1], [0, 2], [0, 3], ], # 一个物体4个方块组成 长方形
[[0, 0], [0, 1], [1, 0], [1, 1], ], # 7个列表表示7种形状 正方形
[[0, 0], [1, 0], [0, 1], [0, 2], ], # 7字型
[[0, 0], [0, 1], [0, -1], [0, -2], ], # 倒7字型
[[0, 0], [0, 1], [1, 1], [1, 2], ], # Z字型
[[0, 0], [0, -1], [1, -1], [1, -2], ], # 倒z字型
[[0, 0], [0, 1], [0, -1], [1, 0]], # T字型
]
backgroud = [[0 for column in range(0, 10)] for row in range(0, 23)] # 创造列表集
backgroud[0] = [1 for colum in range(0, 10)] # 把0层修改为[1*10]
# 设置全局变量
# select_block = list(random.choice(all_block)) # 从7个形状中随机选择一种
initial_position = [21, 5]
times = 0 # 计时
score = [0] # 得分 系统出错
gameover = [] # 游戏结束
press = False # 按键加速
# 初始化
pygame.init()
screen = pygame.display.set_mode((400, 800)) # 设置窗口大小
select_block = list(random.choice(all_block))
def block_down():
global select_block # 将global改为全局变量
y, x = initial_position # initial_position = [21, 5]
y -= 1 # 表示相距的间隔
for row, column in select_block: # 调节方块下落的位置
row += y
column += x
if backgroud[row][column]: # 注意
break
else:
initial_position.clear() # 刷新对初始位置进行更新
initial_position.extend([y, x]) # [x,y]定义:[一个列表集,第一个值表示1行row,第二个值表示column
return
y, x = initial_position
for row, column in select_block:
row += y # 对当前选择的方块
column += x
backgroud[row][column] = 1 # 这个是是将背景网格中指定位置的值修改为1
complete_row = [] # 用来存储静态的block就是完成一行后,将静态block存储在数组中
# 然后通过删除数组元素达到消除方块的效果
# 下面代码用于处理和检测背景网格中是不是有完整的行
for row in range(1, 21): # 通过循环遍历背景网格中的每一行
if 0 not in backgroud[row]: # 条件判断是否存在值为0的元素,如果不存在,则表示该行是完整的。
complete_row.append(row) # 如果一行是完整的将其行号row添加到complete_row中
for row in complete_row: # 再次循环对每一行进行遍历
backgroud.pop(row) # 将完整的行移除
backgroud.append(list(0 for _ in range(0, 10))) # 注意 移除行后在网格底部添加一个新行就是为让网格大小保持不变
score[0] += len(complete_row) # 计算消除行数并记录
pygame.display.set_caption('你现在的分数是 ' + str(score[0]) + '分') # 显示消除行数显示标题中
# text = font.render("Score: " + str(score[0]), True, (0, 0, 0))
initial_position.clear() # 清空 initial_position列表中的元素
select_block = list(random.choice(all_block)) # 随机选择一个方块
initial_position.extend(select_block) # 将选中的方块赋值给initial_position,initial_position里面存储着随机选择的方块
initial_position.clear() # 当动态的block变成静态block清楚initial_position中存储的上个方块的信息然后为重新加载方块做准备
initial_position.extend([20, 5]) # 将[20,5]添加到initial_position中[20,5]代表下落的初始坐标
y, x = initial_position
for row, column in select_block: # 用于确定方块的偏移量
row += y
column += x
if backgroud[row][column] == 1: # 判断静态block对应位置是否为1如果是说明当前方块于背景中已有方块重叠
gameover.append(1)
# 这段代码的逻辑是遍历选中的方块中的每个位置,将其与背景中对应位置的值进行比较,如果发生碰撞,则将游戏结束的标志(值为 1)
# TODO:
# 详细解释
# 首先,通过 `for row, column in select_block:` 遍历 `select_block` 列表中的每个元素,其中每个元素都是一个包含方块位置信息的列表,例如 `[row, column]`。
#
# 然后,将 `row` 和 `column` 分别加上变量 `y` 和 `x` 的值。这里的 `y` 和 `x` 可能表示方块在背景中的偏移量,用于确定方块的实际位置。
#
# 接下来,通过 `if backgroud[row][column] == 1:` 条件语句判断背景中对应位置的值是否为 1。如果是,说明当前方块与背景中已有的方块重叠,即发生碰撞。
#
# 如果发生碰撞,将值为 1 的元素添加到 `gameover` 列表中,以表示游戏结束。
#
# 综上所述,这段代码的逻辑是遍历选中的方块中的每个位置,将其与背景中对应位置的值进行比较,如果发生碰撞,则将游戏结束的标志(值为 1)添加到 `gameover` 列表中。
def draw_block():
y, x = initial_position
for row, column in select_block:
row += y
column += x
pygame.draw.rect(screen, (255, 165, 0), (column * 40, 800 - row * 40, 38, 38))
for row in range(1, 21):
for column in range(0, 10):
if backgroud[row][column] == 1:
pygame.draw.rect(screen, (0, 0, 255), (column * 40, 800 - row * 40, 38, 38))
def rotate():
y, x = initial_position
# select_block = list(random.choice(all_block))
rotating_position = [(-colum, row) for row, colum in select_block] # 计算方块旋转后的位置
for row, colum in rotating_position:
row += y
colum += x
if colum < 0 or colum > 9 or backgroud[row][colum]:
break
else:
select_block.clear()
select_block.extend(rotating_position)
def move(d):
y, x = initial_position
# select_block = list(random.choice(all_block))
x += d
for row, colum in select_block:
row += y
colum += x
if colum < 0 or colum > 9 or backgroud[row][colum]:
break
else:
initial_position.clear()
initial_position.extend([y, x])
while True:
screen.fill((255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
press = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
rotate() # 代码无法向下加速的原因是在处理pygame.KEYUP事件时,判断按键是否为向下键时使用了错误的语句。
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT: # 具体来说,在代码中,当检测到键盘按键释放事件(pygame.KEYUP)时,
# 判断按键是否为向下键时应该使用event.key
# 而不是event.type。
move(1) # 因此,将event.type改为event.key即可解决这个问题
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
move(-1)
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
press = False
if times % 60 == 0:
block_down()
times += 1
if press:
times += 10
if gameover:
sys.exit()
draw_block()
pygame.time.Clock().tick(400)
# 创建字体对象
font = pygame.font.Font(None, 36)
# 创建显示文本
text = font.render("Score: " + str(score[0]), True, (0, 0, 0))
# 创建显示区域然后显示
screen.blit(text, (10, 10))
# 刷新
pygame.display.update()
pygame.display.flip()
# 俄罗斯方块基本类
# 方块
# 旋转
# 移动
# 物块
# 形状
# 碰撞检测
# 绘制
我创建的相关文章
提供先进的推理,复杂的指令,更多的创造力。
如果此文对你有帮助的话,欢迎关注、点赞、⭐收藏、✍️评论,支持一下博主~