功能介绍

首先我们在屏幕上制作一个碰壁小球游戏,小球在指定区域内不断的碰壁反弹,之后新建一个拦球板对象,用来检测小球是否碰到拦球板,碰到则将积分增加,完成弹球小游戏的功能。课程会分为三个任务的形式进行,下表为课程任务及涉及到的知识点。

实现功能 知识点
任务一:碰壁小球 巩固复习turtle库的两种不同导入方式、Screen函数以及学习随机数randint函数的使用
任务二:生成栏板对象 对象、属性、方法的概念及sleep()函数的使用
任务二:拦球小游戏 巩固学习获取鼠标坐标的方法、逻辑判断语句、多条件判断语句

项目实践

任务一:碰壁小球

1任务分析

前面我们已经学过了turtle库中Screen函数和Turtle函数的使用,这节课我们首先将巩固复习一下他们的用法,利用Screen函数创建一个屏幕,之后新建小球对象,让其在屏幕内不断的进行碰壁反弹运动。那么我们通过什么进行碰壁呢?下图为宽和高为w和h的屏幕。

image 通过上图屏幕我们可以看出判断左右是否碰到壁,其实可以通过检测x轴的坐标是否大于w/2或者小于-w/2来判断,也就是当x轴的坐标大于w/2或者小于-w/2时证明小球碰到了左右壁。而判断上下是否碰到壁,可以通过检测y轴的坐标是否大于h/2或者小于-h/2来判断,也就是当y轴的坐标大于h/2或者小于-h/2时证明小球碰到了上下壁。

2编写程序

from turtle import \*#导入turtle库的所有工具

from random import randint #导入random的randint工具

from time import sleep#导入time的sleep工具

w,h= 480,360#设置屏幕的宽和高

screen = Screen()#把Screen的对象赋值给screen

screen.bgcolor("black")#设置屏蔽背景为黑色

screen.setup(w,h)#初始设置宽和高

screen.bgpic("Background.gif") #背景设置#

#-------------------------

ball=Turtle(shape='circle')#新建ball对象,形状为圆形

ball.speed(0)#设置ball的速度为最快.

ball.penup()#提笔,不留痕迹

ball.color("yellow","yellow")#设置ball的边框颜色填充颜色

x速度 = randint(2,3)#设置初始水平速度

y速度 = randint(2,3)#设置初始垂直速度

while True :#永久循环

    x=ball.xcor() + x速度#获取移动前ball的x坐标值加上小球速度的速度值,得到移动后x坐标值

    y=ball.ycor() + y速度#获取移动前ball的y坐标值加上小球速度的速度值,得到移动后y坐标值

    ball.goto(x,y)#让小球到达坐标为(x,y)的坐标点

    if x>w/2 or x<-w/2:#判断ball是否碰左右边缘的壁

        x速度 = -x速度#如果碰到壁就同一速度反方向弹开

    if y>h/2 or y<-h/2:#判断ball是否碰上下边缘的壁

        y速度 = -y速度#如果碰到壁就同一速度反方向弹开

3运行效果

运行这段程序,我们可以看到弹出了一个星空背景的屏幕,屏幕内有一个黄色小球在不断的进行碰壁反弹运动。 image 任务二:生成拦球杆对象

1任务分析

在任务一中,我们已经绘制了一个星空背景的屏幕,并让黄色小球在不断的进行碰壁反弹运动。这里我们需要生成另一个对象,也就是拦球杆,用来拦下小球。

2编写程序

from turtle import \*#导入turtle库的所有工具

from random import randint #导入random的randint工具

from time import sleep#导入time的sleep工具

w,h= 480,360#设置屏幕的宽和高

screen = Screen()#把Screen的对象赋值给screen

screen.bgcolor("black")#设置屏蔽背景为黑色

screen.setup(w,h)#初始设置宽和高

screen.bgpic("Background.gif") #背景设置#

screen.delay(0)#这里要设为0,否则很卡

#---------------------------------------------------

square =Turtle('square')#创建一个弹球小栏板

square.shapesize(0.5,5)#设定栏板的长宽尺寸,对应像素为高5像素,长为50像素

square.speed(0)#设定栏板速度为最大

square.penup()#抬笔

square.color('blue')#设定颜色为蓝色

square.sety(50-h/2)#固定纵坐标

#----------------------------------------------------

ball=Turtle(shape='circle')#新建ball对象,形状为圆形

ball.speed(0)#设置ball的速度为最快.

ball.penup()#提笔,不留痕迹

ball.color("yellow","yellow")#设置ball的填充和边框颜色

x速度 = randint(2,3)#设置初始水平速度

y速度 = randint(2,3)#设置初始垂直速度

while True :#永久循环

    x=ball.xcor() + x速度#获取移动前ball的x坐标值加上小车速度,得到移动后x坐标值

    y=ball.ycor() + y速度#获取移动前ball的y坐标值加上小车速度,得到移动后y坐标值

    ball.goto(x,y)#让小球到达坐标为(x,y)的坐标点

    if x>w/2 or x<-w/2:#判断ball是否碰左右边缘的壁

        x速度 = -x速度#如果碰到壁就同一速度反方向弹开

    if y>h/2 or y<-h/2:#判断ball是否碰上下边缘的壁

        y速度 = -y速度#如果碰到壁就同一速度反方向弹开

    sleep(0.01)#推迟0.01秒再执行

注意:这里一定要加上sleep(0.01)否则小球会弹得很快,无法看清效果!

3运行效果

运行程序我们发现,呈现的屏幕内小黄球还是在不断的碰壁反弹运动,此可以看到比任务一多了一个蓝色的小栏板。

image

任务三:拦球小游戏

1任务分析

通过任务二我们建立了拦球板,现在我们需要通过鼠标去控制拦球板的运动,之后设置一个计分的变量,让小球碰到篮球板就反弹回去的同时计分加一,如果小球没有碰到篮球板但是碰到了下边界,那么就结束游戏,停止游戏。分为以下两步进行。

第一步:实现鼠标控制小拦板移动 这里我们只需要控制小栏板左右移动,所以我们只需获取小拦板在画布内x坐标就好了。 image

第二步:判断游戏是否继续

其次我们要解决判断游戏是否继续,这里我们可以通过判断小球的横坐标和纵坐标是否在栏板的范围内。下图分别为成功和失败的例图

成功

碰到小栏板需反弹 image

失败

没碰到小栏板,碰到了下边界 image

2编写程序

import turtle#导入turtle库

from random import randint#导入随机数库randint函数

from time import sleep#导入时间库sleep函数

#-------------------------------------------------------

screen = turtle.Screen()#赋值screen对象

w,h= 480,360#设定宽度和高度

screen.setup(w,h)#以设定好的宽度和高度来创建屏幕

screen.bgcolor("green")#设定背景色为绿色

screen.delay(0)#这里要设为0,否则很卡

#---------------------------------------------------

square = turtle.Turtle('square')#创建一个弹球小栏板

square.shapesize(0.5,5)#设定栏板的长宽尺寸,对应像素为高5像素,长为50像素

square.speed(0)#设定栏板速度为最大

square.penup()#抬笔

square.color('blue')#设定颜色为蓝色

square.sety(50-h/2)#固定纵坐标  

#----------------------------------------------------

ball=turtle.Turtle(shape='circle')#创建一个圆球

ball.speed(0)#速度为最快.

ball.penup()#抬笔

ball.color("yellow","yellow")#设定颜色为黄色

xspeed = randint(2,3)#设置初始水平速度

yspeed = randint(2,3)#设置初始垂直速度

#-----------------------------------------------------

root = screen.\_root#获取根窗口对象

cv = screen.\_canvas#获取画布

count = 0#计次数

while True:#永久循环

    mx = root.winfo\_pointerx()#鼠标指针相对于计算机屏幕的x坐标

    rx = cv.winfo\_rootx()#画布到计算机屏幕最左边距离

    bx = mx - rx - 2#画布边框宽度是2,所以要减去2  

    x = bx - screen.window\_width() //2  # 转换成在海龟画图坐标系中x坐标

    square.goto(x,-50)#使栏板移动到指定坐标

    screen.update()#刷新屏幕显示

#-----

    x = ball.xcor() + xspeed#设置小球在水平方向移动x速度

    y= ball.ycor() + yspeed#设置小球在垂直方向移动y速度

    ball.goto(x,y)#设定小球的移动

    if  x>w/2 or x <-w/2:#如果小球跑出左右两侧边界

        xspeed  = - xspeed#设定小球返回   

    elif  y>h/2 :#如果小球过了上边界

        yspeed = - yspeed#设定小球返回

elif  y<-h/2:#如果小球过了下边界

        print("game over")#显示得分

        turtle.done()#画面停止

    else:

         ball.goto(x,y)#设定小球的移动

    squareleftx = square.xcor() - 50#设定栏板的左侧横坐标

    squarerightx = square.xcor() + 50#设定栏板的右侧横坐标

    squareupy = square.ycor() + 5#设定栏板的上方纵坐标

    squaredowny = square.ycor() - 5#设定栏板的下端纵坐标

    if x< squarerightx and x >squareleftx:#如果小球的横坐标在栏板的范围内

        if y < squareupy and y > squaredowny:#如果小球的纵坐标在栏板范围内

            yspeed = - yspeed#反弹

            count=count+1#计次

            print("得分:",count)#显示得分

            screen.update()#刷新屏幕显示

    sleep(0.01)#推迟0.01秒再执行

3运行效果

点击运行程序,我们可以看到小球开始向右上方移动,碰到屏幕的上方,左右两侧及栏板后就反弹。这时,我们可以通过鼠标来控制我们的栏板移动进而接球,栏板与小球每接触一次,我们就记一次得分并显示在终端中。如果小拦板接不到小球,并且小球碰到了下边界,那么游戏就会停止。基于这样的游戏功能让我们一起来试试吧,看看最高能得多少分呢?

项目小结

通过本节课程的学习我们巩固复习turtle库的两种不同导入方式、Screen函数以及学习随机数randint函数的使用完成了碰壁小球游戏。之后建立小栏板对象,理解了对象、属性、方法的概念。最终完成拦球小游戏功能,巩固学习了获取鼠标坐标的方法、逻辑运算符、多条件判断语句等的用法。想一想作为一个游戏是不是还有很多可以加入控制的功能,比如如何增加游戏难度选择和游戏胜利提醒?

项目扩展

尝试换一个背景,然后增加游戏难度设置和游戏胜利提示功能。

参考代码

import turtle#导入turtle库

from random import randint#导入随机数库randint函数

from time import sleep#导入时间库sleep函数

#-------------------------------------------------------

screen = turtle.Screen()#赋值screen对象

w,h= 480,360#设定宽度和高度

screen.setup(w,h)#以设定好的宽度和高度来创建屏幕

screen.bgcolor("green")#设定背景色为绿色

screen.delay(0)#这里要设为0,否则很卡

#---------------------------------------------------

#产生一个输入难度的对话框

difficulty=screen.numinput("难度","请输入游戏的难度(1~5)",minval=1,maxval=5)

square = turtle.Turtle('square')#创建一个弹球小栏板

square.shapesize(0.5,10/difficulty)#设定栏板的长宽尺寸

square.speed(0)#设定栏板速度为最大

square.penup()#抬笔 

square.color('blue')#设定颜色为蓝色

#----------------------------------------------------

ball=turtle.Turtle(shape='circle')#创建一个圆球 

ball.speed(0)#速度为最快.

ball.penup()#抬笔

ball.color("yellow","yellow")#设定颜色为黄色

xspeed = randint(2,3)#设置初始水平速度

yspeed = randint(2,3)#设置初始垂直速度

#-----------------------------------------------------

root = screen._root#获取根窗口对象

cv = screen._canvas#获取画布 

count = 0#计次数



while True:#永久循环

    mx = root.winfo_pointerx()#鼠标指针相对于计算机屏幕的x坐标

    rx = cv.winfo_rootx()#画布到计算机屏幕最左边距离

    x = mx - rx - 2#画布边框宽度是2,所以要减去2  

    x = x - screen.window_width() //2  # 转换成在海龟画图坐标系中x坐标

    square.goto(x,-100/difficulty)#使栏板移动到指定坐标

    screen.update()#刷新屏幕显示

#-----------------------------------------------------

    x = ball.xcor() + xspeed#设置小球在水平方向移动x速度

    y= ball.ycor() + yspeed#设置小球在垂直方向移动y速度

    ball.goto(x,y)#设定小球的移动

    if  x>w/2 or x <-w/2:#如果小球跑出左右两侧边界

        xspeed  = - xspeed#设定小球返回   

    elif  y>h/2 :#如果小球过了上边界

        yspeed = - yspeed#设定小球返回

    elif  y<-h/2:#如果小球过了下边界

        turtle.write("game over",font=("Arial",40,"normal"))#显示失败

    else:

         ball.goto(x,y)#设定小球的移动

    squareleftx = square.xcor() - 10/difficulty*10#设定栏板的左侧横坐标

    squarerightx = square.xcor() + 10/difficulty*10#设定栏板的右侧横坐标

    squareupy = square.ycor() + 5#设定栏板的上方纵坐标

    squaredowny = square.ycor() - 5#设定栏板的下端纵坐标

    if x< squarerightx and x >squareleftx:#如果小球的横坐标在栏板的范围内

        if y < squareupy and y > squaredowny:#如果小球的纵坐标在栏板范围内

            yspeed = - yspeed#反弹

            count=count+1#计次

            print("得分:",count)#显示得分

            screen.update()#刷新屏幕显示

    if count == 5*difficulty:#如果得了50分

        print("victory")#显示获胜

        turtle.exitonclick()#点击退出

    sleep(0.01)#推迟0.01秒再执行


1 条评论

  • @ 2024-6-16 11:57:44
    from turtle import *#导入turtle库的所有工具
    from random import randint #导入random的randint工具
    from time import sleep#导入time的sleep工具
    w,h= 800,600#设置屏幕的宽和高
    screen = Screen()#把Screen的对象赋值给screen
    screen.bgcolor("black")#设置屏蔽背景为黑色
    screen.setup(w,h)#初始设置宽和高
    # screen.bgpic("Background.gif") #背景设置#
    screen.delay(0)#这里要设为0,否则很卡
    #-------------------------
    square =Turtle('square')#创建一个弹球小栏板
    square.shapesize(0.5,5)#设定栏板的长宽尺寸,对应像素为高5像素,长为50像素
    square.speed(0)#设定栏板速度为最大
    square.penup()#抬笔
    square.color('blue')#设定颜色为蓝色
    square.sety(50-h/2)#固定纵坐标
    #-------------------------
    ball=Turtle(shape='circle')#新建ball对象,形状为圆形 square
    ball.speed(0)#设置ball的速度为最快.
    ball.penup()#提笔,不留痕迹
    ball.color("red","blue")#设置ball的边框颜色填充颜色
    x速度 = randint(2,8)#设置初始水平速度
    y速度 = randint(2,8)#设置初始垂直速度
    #-------------------------
    root = screen._root#获取根窗口对象
    cv = screen._canvas#获取画布 
    count = 0#计次数
    while True :#永久循环
        mx = root.winfo_pointerx()#鼠标指针相对于计算机屏幕的x坐标
        rx = cv.winfo_rootx()#画布到计算机屏幕最左边距离
        x = mx - rx - 2#画布边框宽度是2,所以要减去2  
        x = x - screen.window_width() //2  # 转换成在海龟画图坐标系中x坐标
        square.goto(x,50-h/2)#使栏板移动到指定坐标
        screen.update()#刷新屏幕显示
    #-----------------------------------------------------
        x=ball.xcor() + x速度#获取移动前ball的x坐标值加上小球速度的速度值,得到移动后x坐标值
        y=ball.ycor() + y速度#获取移动前ball的y坐标值加上小球速度的速度值,得到移动后y坐标值
        ball.goto(x,y)#让小球到达坐标为(x,y)的坐标点
        
        dx = square.xcor()
        dy = square.ycor()
    #     print(dx,dy)
        print(x,y)
        if y< dy+5+20 and x>dx-50+20 and x<dx+50-20:
            y速度 = -y速度#如果碰到挡板就同一速度反方向弹开
        if x>w/2-20 or x<-w/2+20:#判断ball是否碰左右边缘的壁
            x速度 = -x速度#如果碰到壁就同一速度反方向弹开
        if y>h/2-20 or y<-h/2+20:#判断ball是否碰上下边缘的壁
            y速度 = -y速度#如果碰到壁就同一速度反方向弹开
        sleep(0.01)#推迟0.01秒再执行
    
    
    
    • 1