在好例子网,分享、交流、成长!
您当前所在位置:首页Python 开发实例Python语言基础 → 俄罗斯方块

俄罗斯方块

Python语言基础

下载此实例
  • 开发语言:Python
  • 实例大小:0.01M
  • 下载次数:30
  • 浏览次数:197
  • 发布时间:2021-07-13
  • 实例类别:Python语言基础
  • 发 布 人:yanjinyuan90
  • 文件格式:.py
  • 所需积分:2
 相关标签: 俄罗斯方块

实例介绍

【实例简介】

【实例截图】

【核心代码】
#其实俄罗斯方块的判断没有想象中的那么难 不需要长篇幅的代码编写
#方块
#旋转
#移动
#物块
#形状
#碰撞检测
#绘制
#就这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所示 最新

标签: 俄罗斯方块

实例下载地址

俄罗斯方块

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警