百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

pygame中groupcollision碰撞检测详解与测试

liebian365 2025-01-20 14:34 21 浏览 0 评论

在游戏开发中,非常重要的编程工作就是进行碰撞检测。在python的pygame模块中的sprite精灵类提供了多种方便快捷的碰撞检测方法。比如矩形碰撞检测、圆形碰撞检测、遮罩碰撞检测,这些方法基本都是单个对单个的物体进行检测,如果涉及到敌我双方都有很多对象时,比如飞机大战中的我方子弹与敌方飞机的碰撞检测,用上述方法可能就得进行循环嵌套,这样略显麻烦。

针对分组对象的碰撞检测,pygame中还有一种简单的碰撞检测方法:pygame.sprite.groupcollision(),网上关于介绍它的详细使用方法的文章不多,我经过反复研究和测试,终于弄清楚了它的使用方法、使用场景以及使用效果,希望对你有参考价值。

一、功能说明

官方文档如下:

Find all sprites that collide between two groups.

groupcollide(group1, group2, dokill1, dokill2, collided = None) -> Sprite_dict

This will find collisions between all the Sprites in two groups. Collision is determined by comparing the Sprite.rect attribute of each Sprite or by using the collided function if it is not None.

Every Sprite inside group1 is added to the return dictionary. The value for each item is the list of Sprites in group2 that intersect.

If either dokill argument is True, the colliding Sprites will be removed from their respective Group.

The collided argument is a callback function used to calculate if two sprites are colliding. It should take two sprites as values and return a bool value indicating if they are colliding. If collided is not passed, then all sprites must have a "rect" value, which is a rectangle of the sprite area, which will be used to calculate the collision.

简要解释如下:

找出两个精灵组中发生碰撞的所有精灵,主要通过比较每个精灵的Sprite.rect属性来实现。参数含义如下:

Group1:第一个精灵组

Group2:第二个精灵组

Dokill1:设置为True或者False,当设置为True时,当发生碰撞时group1中的相应精灵对象将被删除;当设置为False时,不论是否发生碰撞,group1保持不变。

Dokill2:设置为True或者False,当设置为True时,当发生碰撞时group2中的相应精灵对象将被删除,不论是否发生碰撞,group1保持不变。

Collided是个回调函数,使用默认即可。

返回值是个字典,未发生碰撞时,字典为空。发生碰撞时,字典的keys是group1中发生碰撞的对象(一直以为字典的keys值是个字符串之类的东西,没想到还可以是对象),values是一个列表,其元素是group2中与每一个group1发生碰撞的所有对象。

二、实例测试

Groupcollide返回值的形态和使用的理解是个难点,举例说明:比如group1有三架飞机对象p1、p2、p3,group2有八个子弹对象b1、b2、b3、b4、b5、b6、b7、b8,假如p1与b1、b4、b7发生碰撞,p2与b2、b5、b8发生碰撞,groupcollide(group1, group2, 1, 1)返回值是如下的字典:{p1:[b1, b4, b7], p2:[b2, b5, b8]}。

做了个小的测试程序,对上面各种情形进行测试:界面中间布置了四架飞机,上方布置了20颗子弹,子弹从上方匀速往下运行,进行碰撞检测,下图为运行之初的状态显示。

子弹往下运动,调用下面的函数进行碰撞检测:

co_dict = pygame.sprite.groupcollide(plane_list, bullet_list, 1, 1)

发生碰撞之后的状态显示如下,可以看出,四架飞机和14颗发生碰撞的子弹都消失了,因为dokill1和dokill2两个参数都被设置为1,也就是说发生碰撞的飞机和子弹都从plane_list 和bullet_list中删除了,此时plane_list是个空的sprite组了,bullet_list的长度也变成6了(刚开始的长度为20)。

此时打印返回值co_dict结果如下:

{<PlayerPlane Sprite(in 1 groups)>: [<Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>], <PlayerPlane Sprite(in 1 groups)>: [<Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>], <PlayerPlane Sprite(in 1 groups)>: [<Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>], <PlayerPlane Sprite(in 1 groups)>: [<Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>, <Bullet Sprite(in 0 groups)>]}

从上可以看出,返回值是个字典,其有4个键值对,每个键为发生碰撞的飞机精灵对象,每个值为与某一飞机发生碰撞的子弹精灵对象列表。

从上面的测试结果可以看出,groupcollide不仅可以进行碰撞检测并返回碰撞结果,还可以对参与碰撞检测的对象进行修改,如果将上述函数的dokill1的参数改为0,则plane_list中的飞机保持不变,bullet_list中发生碰撞的子弹被移除了,运行效果如下:

三、实际应用

对于需要分组碰撞检测的情形,比如坦克大战,飞机大战,用groupcollide进行检测就便利多了,只需一行代码就可以代替繁杂的多层循环嵌套了,同时还可以参与碰撞检测的对象进行修改,对于碰撞后消失的对象,不需要另外再进行if判断和手动删除了,确实是一举多得。

对于返回字典的使用,经常会遇到碰撞后需要进行爆炸显示,此时就可以对返回字典进行遍历(既可以对key遍历,也可以对value遍历),对每个对象添加一个爆炸效果即可。

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: