实例介绍
【实例截图】
#其实俄罗斯方块的判断没有想象中的那么难 不需要长篇幅的代码编写
#方块
#旋转
#移动
#物块
#形状
#碰撞检测
#绘制
#就这7个类
#引入必要模块:
import pygame,sys,random,time
#物块的形状是一个二维数组 通俗的讲 就是列表集
#[x,y]定义:[一个列表的第一个值表示行row,第二个值表示列column]
#一个物块的形状由四个方块组成 四个方块对应四个位置
#每个位置(x,y)用一个列表表示 四个位置组成一个物块形状的列表
#7个列表对应7种形状,7种形状组成一个总列表 形状的初始定义位置为0行,0列
#左下角为原点,向上为y正,向右为x正 与背景的原点不同!
#如: 形状Z:[[0,0],[0,-1],[-1,0],[-1,1]]
#Z的定义位置=[第0行第0列,第0行第-1列,第-1行第0列,第-1行第1列]
#如果空间想象能力较差 可以画图理解7种物块形状是如何规定的
#如果至此 仍不能理解二维数组 请百度python二维数组了解更多
#形式不唯一 这里只是7种形状的某一种初始坐标显示方式
all_block=[[[0,0],[0,-1],[0,1],[0,2]], #物块形状为I
[[0,0],[0,1],[1,1],[1,0]], #物块形状为O
[[0,0],[0,-1],[-1,0],[-1,1]], #物块形状为Z
[[0,0],[0,1],[-1,-1],[-1,0]], #物块形状为S
[[0,0],[0,1],[1,0],[0,-1]], #物块形状为T
[[0,0],[1,0],[-1,0],[1,-1]], #物块形状为L
[[0,0],[1,0],[-1,0],[1,1]]] #物块形状为J
#对于背景: 背景也是一个二维数组 左上角为原点,向下为y正,向右为x正 与形状的原点不同!
#定义:0表示不绘制 1表示绘制 如: [0,0,0,0,0,..]则该行不绘制
#[0,1,0,1,0,...] 则该行第一列不绘制 第二列绘制 第三个列不绘制...
#设置游戏有22行10列 所以每行为[0*10] 即[0,0,0,0,0,0,0,0,0,0]
#游戏窗口显示第1~20行 不绘制 所以窗口每行每列为0
#窗口外的底部为第0行 要作为最初底部的碰撞检测 绘制 所以第0行每列为1
#窗口外的顶部为第21行 用来储存物块初始位置 不绘制 所以第21行每列为0
background=[[0 for column in range(0,10)]for row in range(0,22)]#创造列表集
background[0]=[1 for column in range(0,10)]#把第0层修改为[1*10]
#全局变量:
select_block=list(random.choice(all_block)) #从7个形状里随机挑选一个形状
block_initial_position=[21,5] #物块的初始行列位置[第21行,第5列]
times=0 #计时
score=[0] #得分
gameover=[] #游戏结束
press=False #按键加快下落速度
#游戏设置
pygame.init() #pygame初始化
screen=pygame.display.set_mode((250,500)) #250*500的窗口大小 如果更改数值 下叙代码也要做相应的更改
#游戏函数: 在while循环里重复调用
def block_move_down():
y_drop=block_initial_position[0] #即y_drop=21
x_move=block_initial_position[1] #即x_move=5
y_drop-=1 #物块下落速度 相对于背景原点 y_drop-=1即y_drop=y_drop-1
for row,column in select_block: #对于选择的物块的形状里的每一方块的行列位置:
row =y_drop #对于当前选择的物块每一方块的行位置加上y_drop
#如select_block[0]的行为0 21,0 20,0 19...
column =x_move #对于当前选择的物块每一方块的列位置加上x_move
#select_block[0]的列为0 2(如果横向移动的距离=2),0 (-1)(如果横向移动的距离=-1)
#print(background)#有了这行代码 应该更容易理解游戏显示原理
if background[row][column]==1: #二维数组检测 对于当前物块的行列
break #如果该物块的行列的二维数组值已经等于1就打断该for循环 直接进行下一个环节
else: #for循环剩下的工作:如果不满足for中的if条件 就刷新block_initial_position
block_initial_position.clear() #即block_initial_position=[]
block_initial_position.extend([y_drop,x_move]) #即block_initial_position=[y_drop,x_move]
return #结束该函数的调用 直接进入下一个环节
#如果新位置已经被占用 通过break结束上个for循环 再继续向下执行 如果新位置未被占用 通过return结束该函数
y_drop,x_move=block_initial_position #在上一个环节中更改了block_initial_position 所以重新引入
for row,column in select_block: #对于选择的物块的形状里的每一方块的行列位置:
background[y_drop row][x_move column]=1
#把物块所停留的的位置从0改成1 当位置变成1时 屏幕显示停靠的物块
complete_row=[] #完成的行
for row in range(1,21): #1到20行 即窗口范围
if 0 not in background[row]: #判断第row行是否为方块全占满 如果占满 就增加到complete_row
complete_row.append(row) #增加的是row这行的数字 方便处理
complete_row.sort(reverse=True) #把background中相应的行pop后 会引起complete_row索引变化
#对其降序排列 倒着删除
for row in complete_row: #对于complete_row中的每一个
background.pop(row) #background删掉row行
background.append(list(0 for column in range(0,10))) #随删随补
score[0] =len(complete_row) #得分为完成的行的长度
pygame.display.set_caption('Tetris,Score:' str(score[0]) ' Tonymot') #直接把得分打在窗口标题上
select_block.clear()
select_block.extend(list(random.choice(all_block))) #至此一个物块的操作结束
block_initial_position.clear() #所以select_block,block_initial_position都要重新装填
block_initial_position.extend([20,5])
y_drop,x_move=block_initial_position #在上面的环节中更改了block_initial_position 所以重新引入
for row,column in select_block:
if background[y_drop row][x_move column]:
print(ground[row][column]) #如果background的每一行都有方块 就说明方块已经叠加到窗口顶部
gameover.append(1) #所以游戏在此结束 给gameover增加任意字节 在后面的gameover检测中用到
#else: #如果不满足for中的If条件 就说明方块还未叠加到窗口顶部
# return #所以结束该函数 这两行代码可有可无
def new_draw():
y_drop,x_move=block_initial_position #即y_drop=21,x_move=5
for row,column in select_block: #对于选择的物块的形状里的每一方块的行列位置:
row =y_drop #对于当前选择的物块每一方块的行位置加上y_drop
column =x_move #对于当前选择的物块每一方块的列位置加上x_move
pygame.draw.rect(screen,(255,165,0),(column*25,500-row*25,23,23))#窗口动态方块绘制
#(255,165,0)表示橙色 column*25,500-row*25表示一个方块的位置 23,23表示一个方块的长宽
for row in range(0,20): #创建20行
for column in range(0,10): #创建10列
bottom_block=background[row][column]
#第row行第column列#500表示窗口的高 前两个表示绘制的位置 后两个表示长宽
if bottom_block:#窗口底部的静态方块绘制
pygame.draw.rect(screen,(0,0,255),(column*25,500-row*25,23,23))
#(0,0,255)表示蓝色 column*25,500-row*25表示一个方块的位置 23,23表示一个方块的长宽
def move_left_right(n):
#n=-1表示向左 n=1表示向右
y_drop,x_move=block_initial_position #同上面 不赘述
x_move =n
for row,column in select_block:
row =y_drop
column =x_move
if column<0 or column>9 or background[row][column]: #前两个防止物块移出窗口
#后一个检测动态与静态的碰撞
break
else: #更新位置
block_initial_position.clear()
block_initial_position.extend([y_drop,x_move])
def rotate():
y_drop,x_move=block_initial_position
rotating_position=[(-column,row)for row,column in select_block]
#旋转90° 方块的每个坐标位置都要改变 如果空间想象能力较差 可以画图理解坐标位置的变换
for row,column in rotating_position:
row =y_drop
column =x_move
if column<0 or column>9 or background[row][column]: #检测原理和左右移动一样 不赘述
break
else: #更新位置
select_block.clear()
select_block.extend(rotating_position)
while True:
screen.fill((255,255,255)) #窗口背景为白色
for event in pygame.event.get(): #处理游戏事件
if event.type==pygame.QUIT: #点X退出
sys.exit()
elif event.type==pygame.KEYDOWN and event.key==pygame.K_LEFT: #←键左移
move_left_right(-1)
elif event.type==pygame.KEYDOWN and event.key==pygame.K_RIGHT: #→键右移
move_left_right(1)
elif event.type==pygame.KEYDOWN and event.key==pygame.K_UP: #↑键旋转
rotate()
elif event.type==pygame.KEYDOWN and event.key==pygame.K_DOWN: #↓键加速下落
press=True
elif event.type==pygame.KEYUP and event.key==pygame.K_DOWN:
press=False
if press: #按键时
times =10 #加快物块下落速度
if times>=50: #50为时间间隔
block_move_down() #物块下落
times=0 #重置时间
else: #未按键时
times =1 #默认下落速度
if gameover: #如果gameover有了任意字节 游戏结束
sys.exit() #退出游戏
new_draw() #窗口整体重新绘制
pygame.time.Clock().tick(50) #控制游戏整体绘制速度
pygame.display.flip() #屏幕更新
#Python Pygame 俄罗斯方块(Tetris)
#运行需要安装pygame模块
#OK 完整代码教程到这里就结束了 演示视频可以参照AV55272839
#如何将代码一步一步的简化到85行 就不进行演示了
#把本文件的代码注释和不必要的空格和缩进去掉,不必要的重复代码删掉,冗长的代码简写
#剩下的代码就是AV55272839所示的85行 或者更少 如course.py所示 最新
标签: 俄罗斯方块
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论