12 坚持一百秒

图书简介可以看这里:

童晶:《Python游戏趣味编程》新书上架了

本章我们将编写一个坚持一百秒的游戏,玩家通过鼠标控制飞机躲避飞舞的小球,效果如图12-1所示。首先学习面向对象编程的知识,利用类和对象实现一个新版本的小球反弹程序;然后实现飞机控制与失败判定、生命显示、游戏音效等功能;最后学习继承的概念,快速添加一种新的智能小球。

本章案例最终代码一共99行,代码参看:配套资源\第12章\12-4.py,视频效果参看:配套资源\第12章\坚持一百秒.mp4。

import pgzrun  # 导入游戏库
import random  # 导入随机库
WIDTH = 600   # 设置窗口的宽度
HEIGHT = 800  # 设置窗口的高度
time = 0  # 游戏坚持的时间
hero = Actor('hero')  # 导入玩家飞机图片
live = 3 # 飞机一共3条命livePics = []  # 在左上角显示生命符号
for i in range(live):livePic = Actor('hero_small')livePic.x = 40 + i*60livePic.y = 40livePics.append(livePic)class Ball: # 定义小球类x = None  # 小球的x坐标y = None  # 小球的y坐标vx = None  # 小球x方向的速度vy = None  # 小球y方向的速度radius = None  # 小球的半径color = None  # 小球的颜色# 使用构造函数传递参数对对象初始化def __init__(self,x,y,vx,vy,radius,color):self.x = xself.y = yself.vx = vxself.vy = vyself.radius = radiusself.color = colordef draw(self): # 绘制函数# 绘制一个填充圆,坐标(x,y),半径radius,颜色colorscreen.draw.filled_circle((self.x, self.y), self.radius, self.color)def update(self): # 更新小球的位置、速度self.x += self.vx   # 利用x方向速度更新x坐标self.y += self.vy   # 利用y方向速度更新y坐标# 当小球碰到左右边界时,x方向速度反转if self.x > WIDTH-self.radius or self.x < self.radius:self.vx = -self.vx# 当小球碰到上下边界时,y方向速度反转if self.y > HEIGHT-self.radius or self.y < self.radius:self.vy = -self.vyballs = []  # 存储所有小球的信息,初始为空列表def draw():   # 绘制模块,每帧重复执行screen.fill('white')  # 白色背景hero.draw()  # 绘制玩家飞机for i in range(live): # 绘制还有几条生命livePics[i].draw()for ball in balls:ball.draw()   # 绘制小球screen.draw.text(str(time)+'秒', (270, 10), fontsize=50,fontname='s', color='black')if live<=0:clock.unschedule(count)  # 结束函数的计划执行任务screen.draw.text("游戏结束!", (80, 300),fontsize=100, fontname='s', color='red')def update():  # 更新模块,每帧重复操作global liveif live <=0: # 没有生命了,函数返回,不执行returnfor ball in balls:ball.update()  # 更新小球的位置、速度if abs(hero.x - ball.x) < 25 and abs(hero.y - ball.y) < 30:  # 玩家飞机和小球碰撞live -= 1 # 生命减1sounds.explode.play() # 爆炸一条命的音效ball.y = 10 # 当前小球立刻远离飞机,防止重复碰撞if live <= 0: # 生命减完了hero.image = 'blowup'  # 更换游戏玩家的图片为爆炸图片sounds.boom.play()  # 播放玩家飞机爆炸音效def on_mouse_move(pos, rel, buttons):  # 当鼠标移动时执行if live > 0:  # 生命数大于0才执行hero.x = pos[0]  # 玩家飞机的x坐标设为鼠标的x坐标hero.y = pos[1]  # 玩家飞机的y坐标设为鼠标的y坐标def count(): # 此函数每秒运行一次global timetime += 1 # 计时,每秒钟时间+1# 每隔2秒,加一个小球,并且小球数目不超过20if time % 2 == 0 and len(balls) <= 20:x = WIDTH//2   # 设为小球的x坐标y = random.randint(5, HEIGHT//10)   # 设为小球的y坐标vx = random.choice([-3, -2, -1, 1, 2, 3])  # 小球x方向的速度vy = random.randint(1, 3)  # 小球y方向的速度r = 3      # 小球的半径color = 'black'  # 小球的颜色ball = Ball(x, y, vx, vy, r, color)  # 定义ball对象balls.append(ball)  # 把该小球的信息添加到balls中sounds.throw.play()clock.schedule_unique(count, 1)  # 下一次隔1秒调用count()函数count()  # 调用函数运行
pgzrun.go()   # 开始执行游戏

练习12-2:尝试利用新定义的SmartBall类,改进坚持一百秒的游戏,实现效果如图12-5所示,红色小球即为可以主动向飞机靠近的SmartBall对象:

import pgzrun  # 导入游戏库
import random  # 导入随机库
WIDTH = 600   # 设置窗口的宽度
HEIGHT = 800  # 设置窗口的高度time = 0  # 游戏坚持的时间
hero = Actor('hero')  # 导入玩家飞机图片
live = 3 # 飞机一共3条命livePics = []  # 在左上角显示生命符号
for i in range(live):livePic = Actor('hero_small')livePic.x = 40 + i*60livePic.y = 40livePics.append(livePic)class Ball: # 定义小球类x = None  # 小球的x坐标y = None  # 小球的y坐标vx = None  # 小球x方向的速度vy = None  # 小球y方向的速度radius = None  # 小球的半径color = None  # 小球的颜色# 使用构造函数传递参数对对象初始化def __init__(self,x,y,vx,vy,radius,color):self.x = xself.y = yself.vx = vxself.vy = vyself.radius = radiusself.color = colordef draw(self):# 绘制一个填充圆,坐标(x,y),半径radius,颜色colorscreen.draw.filled_circle((self.x, self.y), self.radius, self.color)def update(self): # 更新小球的位置、速度self.x += self.vx   # 利用x方向速度更新x坐标self.y += self.vy   # 利用y方向速度更新y坐标# 当小球碰到左右边界时,x方向速度反转if self.x > WIDTH-self.radius or self.x < self.radius:self.vx = -self.vx# 当小球碰到上下边界时,y方向速度反转if self.y > HEIGHT-self.radius or self.y < self.radius:self.vy = -self.vyclass SmartBall(Ball): # 定义聪明小球类,继承Ball而来targetX = NonetargetY = None# 使用构造函数传递参数对对象初始化def __init__(self, x, y, vx, vy, radius, color,targetX,targetY):super().__init__(x, y, vx, vy, radius, color)self.targetX = targetXself.targetY = targetYdef updateVelforTarget(self): # 根据目标位置更新小球速度if self.targetX > self.x:self.vx = random.randint(1, 2)elif self.targetX < self.x:self.vx = random.randint(-2, -1)if self.targetY > self.y:self.vy = random.randint(1, 2)elif self.targetY < self.y:self.vy = random.randint(-2, -1)balls = []  # 存储所有小球的信息,初始为空列表def draw():   # 绘制模块,每帧重复执行screen.fill('white')  # 白色背景hero.draw()  # 绘制玩家飞机for i in range(live): # 绘制还有几条生命livePics[i].draw()for ball in balls:ball.draw()   # 绘制小球screen.draw.text(str(time)+'秒', (270, 10), fontsize=50,fontname='s', color='black')if live<=0:clock.unschedule(count)  # 结束函数的计划执行任务screen.draw.text("游戏结束!", (80, 300),fontsize=100, fontname='s', color='red')def update():  # 更新模块,每帧重复操作global liveif live <=0: # 没有生命了,函数返回,不执行returnfor ball in balls:ball.update()  # 更新小球的位置、速度if abs(hero.x - ball.x) < 25 and abs(hero.y - ball.y) < 30:  # 玩家飞机和小球碰撞live -= 1 # 生命减1sounds.explode.play() # 爆炸一条命的音效ball.y = 10 # 当前小球立刻远离飞机,防止重复碰撞if live <= 0: # 生命减完了hero.image = 'blowup'  # 更换游戏玩家的图片为爆炸图片sounds.boom.play()  # 播放玩家飞机爆炸音效def on_mouse_move(pos, rel, buttons):  # 当鼠标移动时执行if live > 0:  # 生命数大于0才执行hero.x = pos[0]  # 玩家飞机的x坐标设为鼠标的x坐标hero.y = pos[1]  # 玩家飞机的y坐标设为鼠标的y坐标def count():global timetime += 1 # 计时,每秒钟时间+1x = WIDTH//2   # 设为小球的x坐标y = random.randint(5, HEIGHT//10)   # 设为小球的y坐标vx = random.choice([-3, -2, -1, 1, 2, 3])  # 小球x方向的速度vy = random.randint(1, 3)  # 小球y方向的速度    # 每隔2秒,加一个小球,并且小球数目不超过20if time % 2 == 0 and len(balls) <= 20:r = 3      # 小球的半径color = 'black'  # 小球的颜色ball = Ball(x, y, vx, vy, r, color)  # 定义ball对象balls.append(ball)  # 把该小球的信息添加到balls中sounds.throw.play()# 当普通小球数目达到20个时,再加一种智能小球if time % 20 == 0 and len(balls) >= 10:r = 5      # 小球的半径color = 'red'  # 小球的颜色smartball = SmartBall(x, y, vx, vy, r, color,hero.x, hero.y)  # 定义smartball对象balls.append(smartball)  # 把该小球的信息添加到balls中sounds.shakeeyes.play()for smartball in balls: # 每秒钟更新一次智能小球的速度if isinstance(smartball, SmartBall):  # 判断是智能小球对象smartball.targetX = hero.x  # 智能小球的目标smartball.targetY = hero.ysmartball.updateVelforTarget() # 通过目标更新智能小球的速度           clock.schedule_unique(count, 1)  # 下一次隔1秒调用count()函数count()  # 调用函数运行
pgzrun.go()   # 开始执行游戏

练习12-3:尝试利用面向对象的知识,封装8-8-3.py中的角色行走动画功能,并定义两个不同的角色对象,实现如下的控制效果:

import pgzrun  # 导入游戏库
WIDTH = 1200    # 设置窗口的宽度
HEIGHT = 900   # 设置窗口的高度class Player(): # 定义玩家控制的角色类,带分解动画和移动功能Anims = []  # 所有的分解动作图片,存在列表当中numAnims = None  # 分解动作图片的张数animIndex = None  # 需要显示的动作图片的序号animSpeed = None  # 用于控制行走动画速度player_x = None  # 玩家的x坐标player_y = None   # 玩家的y坐标vx = None   # 玩家x方向的速度# 使用构造函数传递参数对对象初始化,分解动作图像列表,x,y坐标,x方向速度def __init__(self, Anims, player_x, player_y,vx):self.Anims = Animsself.numAnims = len(Anims)  # 分解动作图片的张数self.player_x = player_x  # 设置角色的x坐标self.player_y = player_y  # 设置角色的y坐标self.vx = vx             # 设置玩家x方向的速度self.animIndex = 0  # 需要显示的动作图片的序号self.animSpeed = 0  # 用于控制行走动画速度for i in range(self.numAnims):self.Anims[i].x = player_x  # 设置所有分解动作图片的x坐标self.Anims[i].y = player_y  # 设置所有分解动作图片的y坐标def draw(self):  # 绘制函数self.Anims[self.animIndex].draw()  # 绘制玩家当前分解动作图片def MoveRight(self):  # 向右移动时的一些操作self.player_x += self.vx  # 角色向右移动for i in range(self.numAnims):  # 所有分解动作图片更新x坐标self.Anims[i].x = self.player_xif (self.player_x >= WIDTH):  # 角色走到最右边self.player_x = 0  # 再从最左边出现self.animSpeed += 1  # 用于控制动作动画速度if self.animSpeed % 5 == 0:  # 动作动画速度是移动速度的1/5self.animIndex += 1  # 每一帧分解动作图片序号加1if self.animIndex >= self.numAnims:  # 放完最后一个分解动作图片了self.animIndex = 0  # 再变成第一张分解动作图片# 定义两个Player对象,并初始化
# 两个角色的分解动作图片、初始位置、速度都不一样
player1 = Player([Actor('阿短1'), Actor('阿短2'), Actor('阿短3'),Actor('阿短4'), Actor('阿短5')], WIDTH/10, HEIGHT/4, 5)
player2 = Player([Actor('小可1'), Actor('小可2'), Actor('小可3'),Actor('小可4'), Actor('小可5')], WIDTH/10, 3*HEIGHT/4, 4)def draw():    # 绘制模块,每帧重复执screen.fill('gray')  # 灰色背景player1.draw()  # 绘制角色1player2.draw()  # 绘制角色2def update():  # 更新模块,每帧重复操作if keyboard.right:  # 如果按下键盘右键player1.MoveRight()    # 角色1向右移动player2.MoveRight()    # 角色2向右移动pgzrun.go()  # 开始执行游戏

分步骤代码、图片音效素材、讲解视频可以从异步社区下载:

https://www.epubit.com/bookDetails?id=UB72096d97d6149

分步骤代码也可以直接从这里下载:

联想Filez

这一章主要学习了面向对象编程,包括类和对象、成员变量、成员函数、构造函数、继承等概念,利用这些知识改进了小球反弹程序、实现了坚持一百秒的游戏。读者可以尝试在本章代码基础上继续改进:

1、根据游戏结束时得分的不同显示不同的结束效果;

2、游戏结束时增加游戏重玩的选项;

3、利用继承实现道具类,吃到道具后可以加命或小球速度减慢;

4、碰撞后给飞机一段时间的无敌状态。

读者也可以尝试应用面向对象的知识,改进之前章节的游戏案例。比如可以构建一个基础的飞机类,包括位置、速度、血量、图片、子弹数等成员变量,显示、更新位置速度、伤害减血、发射子弹等成员函数;然后可以利用继承,实现多种我机、敌机效果,实现更加丰富有趣的飞机大战游戏。

《Python游戏趣味编程》第12章 坚持一百秒相关推荐

  1. python趣味编程100_《Python游戏趣味编程》 第8章 勇闯地下一百层

    知乎视频​www.zhihu.com 图书简介可以看这里:童晶:<Python游戏趣味编程>新书上架了​zhuanlan.zhihu.com 本章我们将编写一个勇闯地下一百层的游戏,键盘控 ...

  2. 弟子规python编程游戏_《Python游戏趣味编程》 第11章 消灭星星

    知乎视频​www.zhihu.com 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了​zhuanlan.zhihu.com 消灭星星是一款非常容易上瘾的消除类游戏,只需 ...

  3. python循环绘制六角星_《Python游戏趣味编程》 第3章 美丽的圆圈画

    知乎视频​www.zhihu.com 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了​zhuanlan.zhihu.com 本章我们将利用Python绘制美丽的圆圈画, ...

  4. 《Python游戏趣味编程》 第10章 拼图游戏

    10 拼图游戏 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了 本章我们将编写一个拼图游戏,鼠标先后点击两个小拼图块,交换其坐标,直到全部达到正确位置,效果如图10-1 ...

  5. 《Python游戏趣味编程》 第9章 贪吃蛇

    9 贪吃蛇 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了 本章我们将编写一个贪吃蛇的游戏,效果如图9-1所示.键盘控制小蛇上下左右移动,吃到食物后长度加一:蛇头碰到自 ...

  6. 《Python游戏趣味编程》 第7章 飞机大战

    7 飞机大战 Python游戏开发 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了 本章我们将编写一个飞机大战的游戏,鼠标控制飞机移动.按下鼠标发射子弹,效果如图7-1 ...

  7. 《Python游戏趣味编程》 第6章 见缝插针

    6 见缝插针 Python游戏开发 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了 本章我们将编写一个见缝插针的游戏.按下空格键后发射一根针到圆盘上,所有发射的针跟着圆 ...

  8. 《Python游戏趣味编程》 第4章 疯狂的小圆圈

    4 疯狂的小圆圈 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了 本章我们将实现一个好玩的程序,鼠标点击后,会在点击处出现一些同心圆圈,并在窗口中四处反弹,效果如图4- ...

  9. 《Python游戏趣味编程》 第3章 美丽的圆圈画

    3 美丽的圆圈画 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了 本章我们将利用Python绘制美丽的圆圈画,鼠标点击时圆圈的颜色会随机变化.首先在上一章的基础上,绘制 ...

最新文章

  1. Windows下使用Telnet 命令测试端口号
  2. Cesium环境搭建成功和初步看一下它的示例
  3. Linux内核驱动之延时---内核超时处理【转】
  4. 试卷代号6098计算机应用基础,2231电大《Visual Basic程序设计》试题和答案200507
  5. AssertJ Fest Hamcrest
  6. 【Python CheckiO 题解】Multicolored Lamp
  7. 三款Scrum项目管理工具
  8. Android中用两层AlertDialog来进行弹出选择框信息选择
  9. Linux三剑客grep、sed、awk
  10. 转 - 受益终生的十大经典管理学定律
  11. webstorm破解之jar包破解(2018)
  12. 新冠疫情加速了通信数字化——全球云通信发展分析
  13. 从0开始强化学习——强化学习的简介和分类
  14. MyEclipse中maven项目中WEBROOT目录问题
  15. 语法数学一点不会?可以学编程吗QAQ
  16. 首师大附中科创教育平台 我的刷题记录 0324 99999999海岛帝国:运输资源
  17. 这些年来什么才是最好的投资?
  18. C语言 第一节 简单的C语言
  19. Arch Linux控制台字符间距变大
  20. 莱布尼兹论微积分的基础:关于无穷小量的真实性问题

热门文章

  1. Python之 while循环
  2. ##CSP 201803-2 碰撞的小球(C语言)100分
  3. flask中的static_path和static_path_url和static_folder
  4. ESP32驱动LCD液晶屏选型、262K什么意思?SPI写LCD的GRAM时序、MCU液晶屏驱动IC的寄存器功能
  5. 剑指offer——23.反转链表
  6. extjs 不显示 但是不报错
  7. Python进阶:值传递,引用传递?不存在的,是赋值传递
  8. 中国首张5G电话卡推出,DMA基金会持续为5G助力。
  9. Theme Section HDU - 4763(些许暴力)
  10. OSI七层模型详解 TCP/IP协议