- 1、本文档共6页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
93基于距离的碰撞检测
9.3基于距离的碰撞检测
本节开始,我们就摆脱了内置 hitTest 方法,而是将碰撞检测掌握在自己手里。这就要用两个物体间的距离来判断碰撞的发生。
举个现实中的例子,如果你那辆车与我这辆车有 100 米的距离,我们就知道这两辆车离得足够远,不可能发生碰撞。然而,如果我们的车都有 6 米宽和 12 米长,而我这辆车的中心点与你那辆车的中心点只有 5 米,那么肯定会有些金属被撞弯,保险单会变长。换句话讲,除非车子的某些部分被撞掉以外,两辆车不可能并到一起。这就是整个距离碰撞检测的思想。我们要确认使两个物体分开的最小距离,再看看当前距离,比较两者的大小。如果当前距离小于最小距离,就知道物体间发生了碰撞。
hitTestObject 方法在矩形上使用效果最好,但在处理其它图形时就退化了,而我们这种方法则在处理圆形时效果最好。要是处理的图形与圆形有偏差,则精确度就会有所降低。但是这里会遇到与 hitTest 中矩形边界相反的问题:明明发生了碰撞,却没有响应,这是因为它们的中心点还不够近。
9.3.1简单的基于距离的碰撞检测
让我们从最理想的状态开始:两个圆形。依然可以使用 Ball 类。(大家现在也许明白了为什么“重用”一词通常与面向对象编程联系在一起了吧。)在应用距离碰撞检测时,圆的注册点应该在中心点上,Ball 类正好符合要求。先要创建两个小球,并设置其中一个为可拖拽的。然后在 enterFrame 函数中进行碰撞检测。到这儿为止,程序与本章的第一个例子相同。只是在判断碰撞时,不是使用if(ball1.hitTestObject(ball2)),而是在 if 语句中判断距离。我们已经学习了计算两个物体间距离的方法,回忆一下第三章的勾股定理。所以,程序开始应该是这样的:
var dx:Number = sprite2.x - sprite1.x;
var dy:Number = sprite2.y - sprite1.y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
OK,现在距离已经有了,如何进行判断呢?请看图 9-4。
图 9-4 碰撞的距离
图中我们看到两个Sprite发生了碰撞,每个Sprite都占60 像素宽,那么每个半径就是 30。因此,在它们相互碰撞时,实际相差 60 个像素。啊哈!这就是答案。对于两个大小相同的圆来说,如果距离小于直径,就会产生碰撞。本例代码 (Distance.as) 与 ObjectHisTest.as非常相似,设置 onEnterFrame 方法为:
private function onEnterFrame(event:Event):void {
var dx:Number = ball2.x - ball1.x;
var dy:Number = ball2.y - ball1.y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
// 默认 ball 的直径为 80 (半径为 40)
if (dist 80) {
trace(hit);
}
}
测试后,我们发现这回碰撞的结果与接近小球的角度无关。在没有接触到目标球时不会产生碰撞。但是在代码中使用数值表示距离显然不太合适,因为这样的话每次改变 ball 的大小都要重新修改代码。况且,如果两个小球的大小不同怎么办?我们需要将这个方法抽象成可以适应任何情况的公式。
如图 9-5 所示。 两个大小不同的 ball,相互碰撞。左边的小球 60 像素,右边的 40 像素。我们可以用程序检察它们的 width 属性。第一个 ball 的半径为30, 另一个半径为20。
所以,它们碰撞时的距离实际应为 50。在 Ball 类里面,已经设置了半径(radius)属性,可以直接拿来判断。
图 9-5 两个不同体积物体的碰撞距离
思路已经有了,距离就是两个小球的半径之和。现在可以删除手工加入的数字了,代码如下(文档类 Distance2.as):
private function onEnterFrame(event:Event):void {
var dx:Number = ball2.x - ball1.x;
var dy:Number = ball2.y - ball1.y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
if (dist ball1.radius + ball2.radius) {
trace(hit);
}
}
实验一下,设置小球的大小(将 radius 传入 Ball 的第一个参数中),观察执行结果。在前面例子中,我是这样写的:
b
您可能关注的文档
最近下载
- 作业设计研讨活动记录.doc
- 2025国家电投校园招聘笔试备考题库及答案解析.docx
- 2021-2022学年五年级上学期综合实践活动(劳动教育)第6课巧做糖画教案.docx
- 创业意识与创业技巧:了解企业登记注册流程.pptx
- 山东省淄博市2023年高一上学期《英语》期中试卷与参考答案.pdf
- 大学生职业规划大赛成长赛道 (修订).pptx
- 2018重庆市建设工程混凝土与砂浆配合比表.pdf
- WhyNothingWorks.doc VIP
- 住院医师规范化培训基地标准(2022年版)--皮肤科专业基地细则.docx
- JB∕T 2436.2-2020 导线用铜压接端头 第2部分:10mm2~300mm2导线用铜压接端头.pdf
文档评论(0)