首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用pygame模块做一个电子鱼缸:鱼类型的编写

大家好,欢迎收看思路实验室出品的Python入门教程,我是室长。

在上一期我们配置好了鱼缸的背景和前景水草,现在可以往鱼缸里放鱼了。不过在上一期结尾我们留了一个坑,就是如何应对输入事件。现在我们点击游戏窗口就会卡死,因为我们没有告诉程序如何应对输入事件。

为了避免每一帧都会打印出一个列表,室长这里展示只打印了非空列表,也就是有操作时记录下的结果。可以看到记录下了各种各样的事件,比如鼠标移动,鼠标点击和放开,按键的按下和抬起,甚至窗口处于非活动状态和窗口关闭都作为了独立事件。

在写了这几行代码之后,我们即便对窗口进行操作也不会出现未响应的情况了。但是接着问题又出现了:窗口关不上了。

这其实原因也很简单,那就是我们只接收了事件,但没有告诉程序如何去处理事件。关闭窗口的操作很简单:一旦触发事件就结束程序。所以可以这样写:

这样我们再去点击窗口右上角的x,就可以正确关闭窗口了。

在一个游戏中需要处理的事件会很多,我们不妨把这一部分代码写入函数中,方便进行修改:

接下来我们就可以向鱼缸里放鱼了。其实放鱼本身和放背景、放水草没有什么区别,但是鱼应该是会游动的,每帧的位置都不一样,所以我们要为鱼的游动编写函数。鱼应当有不同的样子,不同的大小,不同的游动速度和游动习惯,但又会有一些共同点,所以我们把鱼编写为类,然后让不同的鱼来继承这个鱼类。

那这个鱼基类应该有什么呢?首先要有位置和目标点,这两点决定了鱼的游动路线。其次是朝向,朝左,朝右?45°仰望天空?接着还有状态,正常游动?休息一下?抢食?追躲其他鱼?最后还可以添加一些养成的元素,比如鱼的名字、饱食度、健康程度等其他通用的属性。这里为了优先编写鱼的运动函数,优先编写位置和目的地,朝向的话只根据位置和目标点进行计算:

有了位置和目的地,我们就可以计算路径和游动距离了:

那么每一帧的移动应该怎样计算呢?这就是数学问题了。通常我们认为鱼游泳的速度和距离无关,那么不管横竖斜,它每一帧游动的距离应该是固定的。但pygame只接收横纵坐标参数,我们需要把各种方向的移动转换成横纵坐标的参数。设每帧游动距离为1,那么:

代码可以写成这样:

需要注意以下几点:

由于游动方向可上可下,可左可右,所以直接用目标坐标减去出发点坐标就可以了,不需要取绝对值;

这里把两点之间的距离存为了函数内的变量,但如果以后需要根据距离做一些其他的操作那么可以把它存为类变量;

movement变量最好在初始化时声明一下;

实际计算出的移动向量可能比较小,但屏幕像素位置又只能取整数,因此在四舍五入的情况下有可能移动向量为(0,0),即原地不动。这时运动就无法进行下去。所以在这种情况下需要为其乘以一个系数,保证运动能够进行,这也可以设置为不同鱼的速度。

这样,鱼类的运动函数就写好了。那么我们就可以编写鱼的子类了。具体的鱼类需要有贴图、速度、习性等属性,我们也可以把这些属性先在基类中声明,在子类初始化时赋上正确的值,这样我们调用基类方法时如果调用这些属性也没有问题:

那么下一步的操作就很明晰了,生成鱼实例,然后每一帧调用一下move方法,再根据loc属性把贴图bia到相应的位置。后边的部分可以写成类方法,任何子类都可以使用:

可以看到鱼已经动起来了,但是效果并不尽如人意:

1.有残影

2.鱼只是像在水中漂着,鱼身子的角度不随运动而变化

3.游到目的地之后就不动了,需要重设目标点

4.游动速度不稳定

那么在下一期中我们将会解决这些问题。如果这篇文章对你有所帮助,希望能帮室长点个赞和在看,你的鼓励是室长进步的动力!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20221011A07RZK00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券