pygame-KidsCanCode系列jumpy-part17-mask-collide碰撞检测
这节我们研究下pygame的几种碰撞检测模式:
如上图,左侧是默认的检测模式:基于矩形的检测(这也是性能最好的模式), 右侧是基于圆形的检测(性能略差于矩形检测)。
矩形检测法虽然性能好,但是缺点也很明显:检测不准确,上图中"飞机与目标"从视觉上看,根本没碰到。
为了改进,pygame给这二种模式,新增了xxx_ratio的方法,允许指定检测时,指定二个目标的叠加程度,只有达到指定的叠加值,才认为是真正碰撞到了,参考下图:
注:ratio的值越大,表示叠加的部分越少!
我们写一个小程序来测试一下:
1 import pygame 2 from os import path 3 from xml.dom.minidom import parse 4 5 SIZE = (WIDTH, HEIGHT) = (265, 320) 6 FPS = 45 7 8 BLACK = 0, 0, 0 9 WHITE = 255, 255, 255 10 11 pygame.init() 12 pygame.mixer.init() 13 14 screen = pygame.display.set_mode(SIZE) 15 pygame.display.set_caption("My Game") 16 clock = pygame.time.Clock() 17 18 spritesheet_image_file_name = path.join(path.dirname(__file__), "../img/spritesheet_jumper.png") 19 spritesheet_xml_file_name = path.join(path.dirname(__file__), "../img/spritesheet_jumper.xml") 20 spritesheet_image = pygame.image.load(spritesheet_image_file_name) 21 spritesheet_image.set_colorkey(BLACK) 22 spritesheet_dom_tree = parse(spritesheet_xml_file_name) 23 root_textures = spritesheet_dom_tree.documentElement 24 sub_textures = root_textures.getElementsByTagName("SubTexture") 25 dic_image = {} 26 27 28 def get_image_rect(img_name): 29 if dic_image.get(img_name): 30 return dic_image[img_name] 31 for texture in sub_textures: 32 name = texture.getAttribute("name") 33 if img_name == name: 34 dic_image[img_name] = pygame.Rect( 35 int(texture.getAttribute("x")), 36 int(texture.getAttribute("y")), 37 int(texture.getAttribute("width")), 38 int(texture.getAttribute("height")) 39 ) 40 return dic_image[img_name] 41 42 43 def get_image(img_name): 44 rect = get_image_rect(img_name); 45 image = pygame.Surface((rect.width, rect.height)) 46 image.blit(spritesheet_image, (0, 0), rect) 47 image.set_colorkey(BLACK) 48 return image 49 50 51 class Demo(pygame.sprite.Sprite): 52 def __init__(self, image, pos): 53 pygame.sprite.Sprite.__init__(self) 54 self.image = image 55 self.rect = self.image.get_rect() 56 self.rect.x = pos[0] 57 self.rect.y = pos[1] 58 59 60 running = True 61 pos1 = (20, 5) 62 pos2 = (125, 110) 63 64 demo1 = Demo(get_image("bunny1_walk1.png"), pos1) 65 demo2 = Demo(get_image("bunny2_stand.png"), pos2) 66 67 all_sprites = pygame.sprite.LayeredUpdates() 68 all_sprites.add(demo1, layer=2) 69 all_sprites.add(demo2, layer=1) 70 71 group2 = pygame.sprite.Group() 72 group2.add(demo2) 73 74 while running: 75 clock.tick(FPS) 76 77 for event in pygame.event.get(): 78 if event.type == pygame.QUIT: 79 running = False 80 if event.type == pygame.KEYDOWN: 81 if event.key == pygame.K_LEFT: 82 demo1.rect.x += -3 83 if event.key == pygame.K_RIGHT: 84 demo1.rect.x += 3 85 if event.key == pygame.K_UP: 86 demo1.rect.y += -3 87 if event.key == pygame.K_DOWN: 88 demo1.rect.y += 3 89 90 screen.fill(BLACK) 91 92 all_sprites.draw(screen) 93 94 pygame.draw.rect(screen, (0, 255, 0), demo2.rect, 1) 95 pygame.draw.rect(screen, (255, 0, 0), demo1.rect, 1) 96 97 font = pygame.font.SysFont("Menlo", 25, True) 98 99 # 默认的检测模式(rect) 100 if pygame.sprite.spritecollide(demo1, group2, False): 101 pos_txt = font.render("hit:true", 1, (255, 255, 128)) 102 else: 103 pos_txt = font.render("hit:false", 1, (255, 255, 128)) 104 screen.blit(pos_txt, (150, 10)) 105 106 pygame.display.update() 107 108 pygame.quit()
View Code
这是默认的Rect检测模式。把100行换成:
# 矩形检测(至少要重叠1-0.7=30%才算发生了碰撞)if pygame.sprite.spritecollide(demo1, group2, False, pygame.sprite.collide_rect_ratio(0.7)):
再看下效果:
继续,换成圆形检测试下:
# 圆形检测(至少要重叠1-0.7=30%才算发生了碰撞)if pygame.sprite.spritecollide(demo1, group2, False, pygame.sprite.collide_circle_ratio(0.7)):
那么,有没有一种方法能做到精确检测呢?当然有,有一种基于mask(在绘图软件中,也称为遮罩或蒙版)的检测方法,类似把背景去掉后,像素级的碰撞检测,当然性能也是最差的。
首先要在Sprite的类上,指定mask:
1 class Demo(pygame.sprite.Sprite): 2 def __init__(self, image, pos): 3 pygame.sprite.Sprite.__init__(self) 4 self.image = image 5 self.rect = self.image.get_rect() 6 self.rect.x = pos[0] 7 self.rect.y = pos[1] 8 #指定蒙版 9 self.mask = pygame.mask.from_surface(self.image)
View Code
然后把检测代码改成:
# 基于mask的检测if pygame.sprite.spritecollide(demo1, group2, False, pygame.sprite.collide_mask):
好了,利用上面学到的知识,把上节的遗留问题:"player与enemy的碰撞检测不准确" 解决一下,效果如下:
优化前 | 优化后 |
源码示例:https://github.com/yjmyzz/kids-can-code/tree/master/part_17
转载于:https://www.cnblogs.com/yjmyzz/p/pygame-kidscancode-part17-mask-collide.html
pygame-KidsCanCode系列jumpy-part17-mask-collide碰撞检测相关推荐
- 用pygame实现网上游戏‘球球情侣‘(用pygame.mask完成碰撞检测)
网上有个'球球情侣'游戏,游戏中有两个不同颜色的球,玩者首先用鼠标画曲线画出球移动的路径,分别右击两个球,使两球沿曲线移动,如果两球碰到一起,进入下一关.编写很多关是游戏公司的事,这里只编写最简单的一 ...
- canvas系列教程06 ——边界检测、碰撞检测
边界检测 边界检测,即检测一个物体所处"运动环境的范围"(也就是边界). 边界限制(避免越界) if (ball.x < ball.radius) {//小球"碰到 ...
- Python中pygame模块pygame.sprite.groupcollision碰撞检测的详解与测试
在游戏开发中,非常重要的编程工作就是进行碰撞检测.在python的pygame模块中的sprite精灵类提供了多种方便快捷的碰撞检测方法.比如矩形碰撞检测.圆形碰撞检测.遮罩碰撞检测,这些方法基本都是 ...
- Pygame详解(十八):mask 模块
pygame.mask Pygame 中处理图形遮罩的模块. 函数 pygame.mask.from_surface() -- 从指定 Surface 对象中返回一个 Mask pygame.ma ...
- 90.pygame游戏-玩个球(play the ball)最终版
文章目录 游戏部分截图 游戏操作说明 代码 所有图片素材 音乐素材 下载链接 游戏部分截图 游戏操作说明 1.鼠标上下左右晃动,在摩擦板中摩擦,会使得灰色求变绿色 2.上下左右(W,S,A,D)四个键 ...
- pygame只能编写游戏_游戏框架搭建
游戏框架搭建 目标 -- 使用 面相对象 设计 飞机大战游戏类 目标 明确主程序职责 实现主程序类 准备游戏精灵组 01. 明确主程序职责 回顾 快速入门案例,一个游戏主程序的 职责 可以分为两个部分 ...
- 用Python和Pygame写游戏-从入门到精通(1)
From: http://eyehere.net/2011/python-pygame-novice-professional-1/ 博客刚开,打算做一个Pygame的系列,翻译自Will McGug ...
- python中的pygame模块使用方法_Pygame的基本使用
Pygame有很多模块,每个模块又有很多方法,在此不能够逐一讲解,所以,我们通过一个实例来学习Pygame,然后再分解代码,讲解代码中的模块. 例:制作一个跳跃的小球游戏. 创建一个游戏窗口,然后在窗 ...
- mask rcnn 超详细代码解读(一)
mask r-cnn 代码解读(一) 文章目录 1 代码架构 2 model.py 的结构 3 train过程代码解析 3.1 Resnet Graph 3.2 Region Proposal Net ...
- 用Python和Pygame写游戏-从入门到精通
博客刚开,打算做一个Pygame的系列,翻译自Will McGugan的<Beginning Game Development with Python and Pygame –From Novi ...
最新文章
- linux zabbix_agentd命令 监控服务器参数 简介
- 【错误记录】Google Play 上架报错 ( 您还没有为此轨道选择任何国家或地区。至少要添加 1 个国家或地区才能发布此版本)
- 必须掌握的八个【cmd 命令行】[
- 【Scratch】青少年蓝桥杯_每日一题_2.23_小猫来回走
- 这就是搜索引擎--读书笔记五--索引的建立与更新
- 程序读取计算机设备管理器中各设备的状态(启用/禁用)?(转自大富翁)
- narwal无法连接机器人_库卡机器人控制系统主机出现MFC3故障维修
- 支持百万级TPS,Kafka是怎么做到的?
- Ansible 详细用法部署安装
- 数据结构与算法分析:第1、2章:引论和算法分析
- Mysql基础之 事务
- 判断日期yyyymmdd
- 如何用计算机管理员权限,怎么打开管理员权限,电脑怎么用管理员权限
- 利用python通过两点构成的空间直线和平面计算交点
- c语言考试可视化编辑器无法提交,一行代码解决The7升级后可视化编辑器不能正常工作的问题...
- c语言第七章函数实验总结,C语言学习与总结---第七章:函数 [01]
- 程序人生 - Nature封面:脑机接口突破,可将脑中“笔迹”转为屏幕字句,速度创纪录,准确率超高
- 国开计算机专业英语答案,国开电大计算机专业英语阅读(河北)形考三参考答案...
- python 群发邮件数量限制_用邮件群发平台群发邮件的数量有限制吗?一般可以发多少?...
- webpack打包时提示:The following entrypoint(s) combined asset size exceeds the recommended limit
热门文章
- vue项目内存溢出的解决
- Ubuntu 12.04系统天嵌Linux交叉编译开发工具的安装
- 社交口才:处理好人际关系的七种谈话技巧
- 通过Requst进行12306查票(2022-09-10)
- “Physically-Based Rendering for Indoor Scene Understanding Using Convolutional Neural Networks”论文阅读
- Ninth season twentieth episode,Joey held a celebrities party but did not invited his friends!!!!!!
- 企业如何CRM管理软件中受益
- 如何在Abaqus中用扫掠的方法画六面体网格
- win10系统开机出现grub,一步进入window系统
- Ubuntu下,用键盘定义鼠标按键