回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

[mind+python] 垃圾分类小游戏 简单

头像 地下铁 2021.09.06 1333 0

概述

大家好,我是来自汕头金园实验中学的一名学生。这是我第一次参加这样的活动,请各位老师指正。

当前,国家正在大力进行垃圾分类行动,以保护我们的绿水青山。所以,做好垃圾分类势在必行。这让我联想到接水果游戏,为何不用人人用过都说好的Mind+的Python模式做一个游戏呢?于是我用turtle库制作了一款垃圾分类游戏(无硬件)。

设计思路

用按键控制垃圾桶类型,屏幕顶端掉下不同类型的垃圾,只有垃圾桶与垃圾匹配才可接到垃圾,接到的垃圾数到一定值才算胜利。

步骤1 基础程序编写

1. 引入turtle库和创建画布

2. 存储文件变量以及创建画笔

3. 添加画笔形状

4. 用左右键控制垃圾桶,设置垃圾从高处掉落

5. 设置AD键控制垃圾桶左右移动

6. 判定垃圾桶和垃圾类型

7. 设置接到垃圾的程序

8. 设置没接到垃圾的程序

9. 设置胜利和失败标准与胜利和失败界面

10. 额外程序:连续接到垃圾的奖励、超级垃圾和其他函数(为了方便调用)

步骤2 界面设置

1. 设置难度选择按钮以及不同难度的游戏

2. 编写规则

3. 设置选择界面(“开始游戏”按钮与“查看规则”按钮)

4. 设置欢迎界面

通过以上几个步骤,一款规则简单但挑战性强的垃圾回收游戏就制作完成了。

最后特别感谢地下铁老师在这款游戏制作中给予我的大力支持!

以下是程序和程序效果的一些图片和视频:

project-image
代码
import turtle as tt#引入海龟库
from turtle import Turtle as t
import time,random
wn=tt.Screen()#创建屏幕
wn.title('垃圾分类游戏')#设置标题
#文件名变量
file_pke=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\p1.gif'
file_pqi=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\p2.gif'
file_pchu=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\p3.gif'
file_phai=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\p4.gif'
file_rke=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\rke.gif'
file_rqi=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\rqi.gif'
file_rchu=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\rchu.gif'
file_rhai=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\rhai.gif'
file_pb=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\bomb1.gif'
file_e,file_m=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\easy.gif',r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\medium.gif'
file_h=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\hard.gif'
file_bgn=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\begin_game.gif'
file_r=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\rules.gif'
file_bg=r'D:\Users\asus\Desktop\TXEDU\Visual\rubbish\bgpic.png'
#创建画笔
a,person,Tt,T=t(visible=False),t(visible=False),t(visible=False),t(visible=False)
a.speed(0),person.speed(0)
Tt.speed(0),T.speed(0)
#添加形状
tt.addshape(file_pke)
tt.addshape(file_pqi)
tt.addshape(file_pchu)
tt.addshape(file_phai)
tt.addshape(file_pb)
tt.addshape(file_e)
tt.addshape(file_m)
tt.addshape(file_h)
tt.addshape(file_rke)
tt.addshape(file_rqi)
tt.addshape(file_rchu)
tt.addshape(file_rhai)
tt.addshape(file_r)
tt.addshape(file_bgn)
#函数定义
def fly(x,y,pd=True,pen=T):#移动
    pen.pu()#抬笔
    pen.setpos(x,y)
    if pd:
        pen.pd()#落笔
def leftmove():#左移(左键)
    person.goto(person.xcor()-10,person.ycor())
def rightmove():#右移(右键)
    person.goto(person.xcor()+10,person.ycor())
def leftmove1():#左移(A键)
    person.goto(person.xcor()-45,person.ycor())
def rightmove1():#右移(D键)
    person.goto(person.xcor()+45,person.ycor())
def clear(x,y,Pen=T,rewrite=False,text='',Align='left',size=8):#清除
    Pen.clear()
    fly(x,y,pen=Pen)
    if rewrite:
        Pen.write(text,align=Align,font=('Arial',size,'normal'))
def setdire():#设置左右移动
    tt.onkeypress(leftmove,'Left')
    tt.onkeypress(rightmove,'Right')
    tt.onkey(leftmove1,'a')
    tt.onkey(rightmove1,'d')
#改变垃圾桶形状
def shapeke():#可回收垃圾
    person.shape(file_pke)        
def shapeqi():#其他垃圾
    person.shape(file_pqi)    
def shapechu():#厨余垃圾
    person.shape(file_pchu)    
def shapehai():#有害垃圾
    person.shape(file_phai)

def preparations():#准备工作
    a.speed(0),person.speed(0),T.speed(0)#速度调至最快
    T.pencolor('black')#调整画笔颜色为黑色
    setdire()
    T.ht()#隐藏画笔

def rint(a,b):#随机数
    return random.randint(a,b)   
def main(lst,a,b):#不在列表中的随机数
    i=rint(a,b)
    if i not in lst:
        return i
    else:
        return main(lst,a,b)
def inmain(lst,a,b):#在列表中的随机数
    i=rint(a,b)
    if i in lst:
        return i
    else:
        return inmain(lst,a,b)
def bye(x=None,y=None):#离开
    wn.bye()
def reset():#重置
    wn.reset()
    T.ht(),Tt.ht(),a.ht(),person.ht()
    T.speed(0),Tt.speed(0),a.speed(0),person.speed(0)


def begin(x=None,y=None):#设置“开始游戏”界面
    reset()
    wn.bgpic(file_bg)#设置背景图片
    #设置按钮
    a.shape(file_e)
    person.shape(file_m)
    T.shape(file_h)
    fly(0,150,False,a)#移动位置
    fly(0,50,False,person)
    fly(0,-50,False)
    a.st(),person.st(),T.st()#显示按钮
    #设置按钮功能
    a.onclick(easy_game)
    person.onclick(medium_game)
    T.onclick(hard_game)
    #设置返回键
    fly(0,-180,pen=Tt)
    Tt.color('white')
    Tt.write('还想看规则?单击海龟返回选择界面',align='center')
    fly(0,-220,False,Tt)
    Tt.shape('turtle')
    Tt.shapesize(3,3)
    Tt.st()
    Tt.onclick(choose)

    wn.exitonclick()#点击关闭

def papl_game(rub_num=20,lives=3,aspeed=15,mode=1):#游戏主程序
    wn.bgpic('nopic')#设置背景图为空
    #设置垃圾桶形状
    tt.onkeypress(shapeke,'1')
    tt.onkeypress(shapeqi,'2')
    tt.onkey(shapechu,'3')
    tt.onkey(shapehai,'4')
    tt.listen()#开始监听键盘
    x=rub_num+lives
    a.shape(file_rke),person.shape(file_pke)#调整垃圾、垃圾桶形状
    a.st(),person.st()
    times=0#总次数
    apples=0#接到的垃圾数
    papl=0#连续接到垃圾次数
    rke_lst=[rint(0,x) for _ in range(int(rub_num/4))]#可回收垃圾出现次数的列表(第几次出现)
    rqi_lst=[main(rke_lst,0,x) for _ in range(int(rub_num/4))]#其他垃圾
    rchu_lst=[main(rke_lst+rqi_lst,0,x) for _ in range(int(rub_num/4))]#厨余垃圾
    def choose_lst():#选择列表函数
        i=rint(0,2)
        a=[]
        a.append(rke_lst)
        a.append(rqi_lst)
        a.append(rchu_lst)
        return a[i]
    srub_lst=[rint(0,x) for _ in range(mode*2)]#超级垃圾出现次数的列表

    a_is_a=0#记录垃圾类型
    p_is_p=0#记录垃圾桶类型
    #显示垃圾数和生命值
    fly(-300,280)
    T.write('垃圾数是:0',False,font=('Arial',15,'normal'))
    fly(-150,280,pen=Tt)
    Tt.write('生命值是:{}'.format(lives),False,font=('Arial',15,'normal'))
    fly(0,-200,False,person)#垃圾桶就位
    fly(random.randint(-310,310),250,False,a)#垃圾就位
    while True:
        #判定垃圾类型
        if times in rke_lst:
            a.shape(file_rke)
            a_is_a=1
        elif times in rqi_lst:
            a.shape(file_rqi)
            a_is_a=2
        elif times in rchu_lst:
            a.shape(file_rchu)
            a_is_a=3
        else:
            a.shape(file_rhai)
            a_is_a=4
        #判定垃圾桶类型
        if person.shape()==file_pke:
            p_is_p=1
        elif person.shape()==file_pqi:
            p_is_p=2
        elif person.shape()==file_pchu:
            p_is_p=3
        else:
            p_is_p=4
        a.st()
        #判定是否为超级垃圾;垃圾向下掉
        if times in srub_lst:
            fly(a.xcor(),a.ycor()-45,False,a)
        else:
            fly(a.xcor(),a.ycor()-aspeed,False,a)
        
        if abs(a.distance(person))<=40:#接到垃圾后的程序
            if a_is_a==p_is_p:#如果类型匹配
                #垃圾重置          
                a.ht()
                a.goto(random.randint(-310,310),250)
                clear(-300,280)
                if times in srub_lst:#判定是否为超级垃圾
                    apples+=10#增加垃圾数
                    clear(-150,280,Pen=Tt)
                    lives+=1#增加生命值
                    Tt.write('生命值是:{}'.format(lives),False,font=('Arial',15,'normal')) 
                else:
                    apples+=1
                papl+=1#增加连续次数
                fly(-300,280)
                T.write('垃圾数是:{}'.format(apples),False,font=('Arial',15,'normal'))
                times+=1#总次数增加
                continue
            else:
                a.ht()
                a.goto(rint(-310,310),250)
                clear(-150,280,Pen=Tt)
                lives-=1
                papl=0
                Tt.write('生命值是:{}'.format(lives),False,font=('Arial',15,'normal'))
                person.shape(file_pb)
                time.sleep(1)
                times+=1
                person.shape(file_pke)
            

        if a.ycor()<=-280:#如果触地没有接到
            a.ht()
            a.goto(random.randint(-310,310),250)
            if times not in srub_lst:#不是超级垃圾
                clear(-300,280)
                apples-=4#减少垃圾数
                if -4<apples<0:
                    apples=0
                if -4==apples:
                    apples=0
                    clear(-150,280,Pen=Tt)
                    lives-=1#减少生命值
                    Tt.write('生命值是:{}'.format(lives),False,font=('Arial',15,'normal'))
                T.write('垃圾数是:{}'.format(apples),False,font=('Arial',15,'normal'))
                #对出现次数列表进行添加
                rke_lst.append(rint(x+1,x+4))
                rqi_lst.append(main(rke_lst,x+1,x+4))
                rchu_lst.append(main(rke_lst+rchu_lst,x+1,x+4))
                x+=4
                papl=0
            times+=1
            continue
        if papl==8:
            #增加生命值
            clear(-150,280,Pen=Tt)
            lives+=1
            Tt.write('生命值是:{}'.format(lives),False,font=('Arial',15,'normal'))
            #选择一个出现次数列表进行添加
            y=choose_lst()
            y.append(x+1)
            x+=1
            papl=0#连续次数清零
        if lives==0:#如果生命值归零(失败)
            a.ht(),person.ht()#隐藏垃圾和垃圾桶
            Tt.clear(),clear(0,0)#清除字幕
            T.pencolor('red')#改变画笔T的颜色为红色
            T.write('你输了',False,align='center',font=('Arial',60,'normal'))#屏幕显示“你输了”
            
            Tt.shape('turtle')#把画笔Tt的形状改为乌龟
            Tt.shapesize(5,5)#设置画笔Tt的大小为5cm*5cm
            fly(-100,-100,pen=Tt)#移动Tt
            time.sleep(3)
            T.reset(),T.ht()
            T.write('点击海龟返回,点击圆退出',False,align='center',font=('Arial',30,'normal'))
            fly(100,-100)
            T.color('red'),T.shape('circle'),T.shapesize(5,5)
            Tt.st(),T.st()
            
            Tt.onclick(choose)#点海龟返回选择界面
            T.onclick(bye)#点圆圈退出
            wn.exitonclick()
            break   
        
        if apples>=rub_num:#如果垃圾数达标(胜利)
            a.ht(),person.ht()#隐藏垃圾和垃圾桶
            Tt.clear(),clear(0,0)#清除字幕
            T.pencolor('yellow')
            T.write('你赢了',False,align='center',font=('Arial',60,'normal'))
            
            Tt.shape('turtle')
            Tt.shapesize(5,5)
            fly(-100,-100,False,Tt)
            time.sleep(3)
            T.reset(),T.ht()
            T.write('点击海龟返回,点击圆退出',False,align='center',font=('Arial',30,'normal'))
            fly(100,-100)
            T.color('yellow'),T.shape('circle'),T.shapesize(5,5)
            Tt.st(),T.st()
            
            Tt.onclick(choose)
            T.onclick(bye)
            wn.exitonclick()
            break


def easy_game(x=None,y=None):#简单模式
    reset()
    preparations()
    papl_game(rub_num=25)#25个垃圾达标
    
def medium_game(x=None,y=None):#中等模式
    reset()
    preparations()
    papl_game(rub_num=40,lives=5,aspeed=rint(20,22),mode=2)
    #40个垃圾达标,5条命,垃圾掉落速度为20到22像素 
def hard_game(x=None,y=None):#困难模式
    reset()
    preparations() 
    papl_game(rub_num=55,lives=3,aspeed=rint(25,35),mode=3)
    #55个垃圾达标,3条命,垃圾掉落速度为25到35像素
def rules(x=None,y=None):#定义规则界面
    reset()#重置
    wn.bgpic('nopic')#设置背景图为空
    fly(-400,-180)#移动画笔T
    T.pencolor('red')
    T.write('''
    · 用键盘左、右键控制垃圾桶接垃圾,当接到的垃圾数到达一定值时就可过关。
      (简单:25;中等:40;困难:55)
    · 也可以用A、D键控制,区别是左右键可长按(此时垃圾会定住)但步幅小,
      用AD键控制不可长按但步幅大。(用AD键时记得按Shift调成英文模式!)
    · 生命有限,扣完即失败。(简单:3;中等:5;困难:3)
    · 注意以下垃圾桶和垃圾的对应关系,只有垃圾桶接到其相对应的垃圾时,才
      能成功接到垃圾,否则垃圾桶会爆炸!
      
            按1键————蓝色垃圾桶(可回收垃圾)————纸箱
            按2键————黄色垃圾桶(其他垃圾)————烟头
            按3键————绿色垃圾桶(厨余垃圾)————苹果核
            按4键————红色垃圾桶(有害垃圾)————电池

    · 有个别垃圾掉下速度很快,它们是超级垃圾,接到它相当于接到_10_个
      普通垃圾,而且可以补生命值! 
    · 没有接到垃圾会扣4分(除超级垃圾);垃圾桶爆炸会扣生命值;
      分一旦扣完,再扣分就会扣生命值!
    · 连续接垃圾成功8次可以补生命值(未接到超级垃圾不会中断,
      接不到普通垃圾、接错垃圾会中断)
    · 阅读完规则,请点击下方的乌龟返回选择界面''',font=('Arial',15,'normal'))
    #设置返回键
    fly(0,-250,False,Tt)
    Tt.color('orange')
    Tt.shape('turtle')
    Tt.shapesize(5,5)
    Tt.st()
    Tt.onclick(choose)#返回选择界面
    #点击关闭
    wn.exitonclick()
def choose(x=None,y=None):#定义选择界面

    reset()
    wn.bgpic(file_bg)
    fly(0,70,False)
    fly(0,-70,False,Tt)
    T.shape(file_bgn)
    Tt.shape(file_r)
    T.onclick(begin),Tt.onclick(rules)#设置开始按钮和规则按钮
    T.st(),Tt.st()
    fly(0,-200,pen=a)
    a.pencolor('white')
    a.write('单击其他位置退出',align='center')
    wn.exitonclick()


#欢迎界面
fly(0,0)
T.pencolor('red')
T.write('您好!欢迎您进入垃圾分类游戏!',align='center',font=('Arial',25,'normal'))
#开始运行
time.sleep(1)
T.reset(),T.ht()
choose()

评论

user-avatar