2019独角兽企业重金招聘Python工程师标准>>>

3.碰撞检测

碰撞检测的概述:

碰撞在物理学中表现为两粒子或物体间极端的相互作用。而在游戏世界中,游戏对象在游戏世界自身并不受物理左右,为了模拟真实世界的效果,需要开发者为其添加属性,以模拟真实事件的运动效果。在游戏世界里,当游戏主角与其它游戏对象发生碰撞时,都会触发一个相应的事件发生。这时候就需要开发者先检测到碰撞现象,即碰撞检测。在Genesis-3D引擎中,能检测碰撞发生的方式有两种:一种是利用碰撞器,一种是利用触发器。

碰撞检测原理:

为需要检测碰撞事件的物体创建子空Actor,作为检测碰撞物体的包装盒,用于程序对碰撞事件发生的判定。实时检测包围盒之间是否发生交叉、包含等关系时候,如若发生,及判定检测碰撞发生,触发碰撞事件。


图3-1-1

实现方法:
实现整个碰撞事件过程中,值得开发者花心思的是检测这一块内容。举例:主角攻击敌人的碰撞检测事件。在一定范围内,玩家控制主角攻击敌人,武器与敌人发生碰撞检测事件,敌人掉血。本来一系列的程序设定都十分顺畅,但这里要注意,因为碰撞检测是实时监测,但是碰撞结果掉血在这一过程中只发生一次,如何在一定事件内,只发生一次碰撞事件的成功检测,值得开发者考究一下。

步骤1:
碰撞检测体包围盒的制作。在场景中创建->空物体(空物体,即空Actor),将空Actor拖动到物体上,成为其子空Actor。
步骤2:
程序上碰撞提包围盒的创建如下所示。

01//玩家碰撞体的创建,三部分:左手、右手和身体
02public override void OnLoad()
03{
04 Actor leftActor = ActorManager.FindActiveActor("BBCollider_LeftCollider");
05 Actor rightActor = ActorManager.FindActiveActor("BBCollider_RightCollider");
06 Actor playerActor = ActorManager.FindActiveActor("BBCollider_Player");
07 playerCollder.RegistFun(playerActor,BBCollideHitCallBack);
08 leftCollder.RegistFun(leftActor ,BBCollideCallBack);
09 rightCollder.RegistFun(rightActor,BBCollideCallBack);
10 Logic.BBCollideMgr.Instance.Register(leftCollder);
11 Logic.BBCollideMgr.Instance.Register(rightCollder);
12 Logic.BBCollideMgr.Instance.Register(playerCollder);
13}
14//敌人的碰撞体创建分两部分:武器和身体。
15public override void OnLoad()//武器
16{
17 Logic.BBCollder weaponCollder = new Logic.BBCollder();
18 Actor weaponCollderActor = Owner;
19 if (weaponCollderActor != null)
20 {
21  weaponCollder.RegistFun(weaponCollderActor, BBCollideATKCallBack);
22  Logic.BBCollideMgr.Instance.Register(weaponCollder);
23 }
24}
25
26public override void OnLoad()//敌人
27{
28 string ownerNum = Owner.Name.Substring(TriggerNameHead.Length);
29 EnemyParent = ActorManager.FindActiveActor(EnemyParentNameHead + ownerNum);
30 Name = "BBCollider_Enemy001";
31 Logic.BBCollder collder = new Logic.BBCollder();
32 Actor collderActor = Owner;
33 if (collderActor != null)
34 {
35  collder.RegistFun(collderActor, BBCollideCallBack);
36  Logic.BBCollideMgr.Instance.Register(collder);
37 }
38}
步骤3:
碰撞检测。
view sourceprint?
01//实时监测碰撞状态
02public void Tick(float elapseTime)
03{
04 //遍历碰撞体容器,检测每两个碰撞体间碰撞状态
05 int iCollidersCount = Colliders.Count;
06 for (int ii = 0; ii < iCollidersCount; ++ii)
07 {
08  for (int jj = ii + 1; jj < iCollidersCount; ++jj)
09  {
10   RemoveBeCollidedActor(Colliders[ii], Colliders[jj]);
11   BoundingBox bbi = Colliders[ii].ColliderActor.WorldBoundingBox;
12   BoundingBox bbj = Colliders[jj].ColliderActor.WorldBoundingBox;
13   if (ClipStatus.Outside != bbi.Contains(bbj) && ClipStatus.Outside != bbj.Contains(bbi))
14   {
15    if (Colliders[jj].ColliderActor.IsActive && !Colliders[ii].IsContainsBeCollidedActor(Colliders[jj].ColliderActor))
16    {
17     Colliders[ii].Call(Colliders[jj].ColliderActor);
18     Colliders[ii].AddBeCollidedActor(Colliders[jj].ColliderActor);
19    }
20
21    if (Colliders[ii].ColliderActor.IsActive && !Colliders[jj].IsContainsBeCollidedActor(Colliders[ii].ColliderActor))
22    {
23     Colliders[jj].Call(Colliders[ii].ColliderActor);
24     Colliders[jj].AddBeCollidedActor(Colliders[ii].ColliderActor);
25    }
26   }
27  }
28 }
29}
30//移除碰撞对象
31private void RemoveBeCollidedActor(BBCollder actor, BBCollder beCollided)
32{
33 BoundingBox actorBox = actor.ColliderActor.WorldBoundingBox;
34 BoundingBox beCollidedBox = beCollided.ColliderActor.WorldBoundingBox;
35 if (ClipStatus.Outside == actorBox.Contains(beCollidedBox))
36 {
37  actor.RemoveBeCollidedActor(beCollided.ColliderActor);
38 }
39  if (ClipStatus.Outside == beCollidedBox.Contains(actorBox))
40 {
41  beCollided.RemoveBeCollidedActor(actor.ColliderActor);
42 }
43}
44
45//定义BBCollder类
46public class BBCollder
47{
48 public void RegistFun(Actor self, callback fun)
49 {
50  _colliderActor = self;
51  _callback = fun;
52 }
53 public void Call(Actor other)
54 {
55  _callback(other);
56 }
57//
58public void RemoveBeCollidedActor(Actor beCollidedActor)
59{
60 if (_beCollidedActors.Contains(beCollidedActor))
61 {
62  _beCollidedActors.Remove(beCollidedActor);
63 }
64}
65public bool IsContainsBeCollidedActor(Actor beCollidedActor)
66{
67 return _beCollidedActors.Contains(beCollidedActor);
68}
69public delegate void callback(Actor other);//注册回调函数???
70private callback _callback;
71private Actor _colliderActor;
72private List<actor> _beCollidedActors = new List<actor>(); //碰撞中Actor列表</actor></actor>
步骤4:
碰撞效果。举例:主角攻击敌人,敌人掉血。
01public void BBCollideHitCallBack (Actor other)
02{
03 if (other.Name.StartsWith ("BBCollider_EnemyATK"))
04 {
05 EnemyState state = Logic.EnemyMgr.Instance.EnemyState(other.Parent.Name);
06 bool judget = Logic.EnemyMgr.Instance.GetEnemyJudge(other.Parent.Name);
07  if (state == EnemyState.Attack && judget
08&& !Logic.LogicMgr.Instance.CurPlayer.CheckDefenseState()
09&& !Logic.LogicMgr.Instance.CurPlayer.CheckDieState())
10  {
11   int playerHP = Logic.PlayerDateMgr.Instance.HP;
12   playerHP --;
13   Logic.PlayerDateMgr.Instance.SetHP(playerHP);
14   Logic.LogicMgr.Instance.CurPlayer.State = Logic.CharacterState.Hurt;
15  }
16 }
17}

引擎官方网站:http://www.genesis-3d.com.cn/

官方论坛:http://bbs.9tech.cn/genesis-3d/

官方千人大群:59113309   135439306

YY频道-游戏开发大讲堂(完全免费,定期开课):51735288

Genesis-3D开源游戏引擎:游戏起源,皆因有我!!!

转载于:https://my.oschina.net/Genesis3D/blog/192866

《Genesis-3D开源游戏引擎--横版格斗游戏制作教程03:碰撞检测》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. 暑期集训5:并查集 线段树 练习题G: HDU - 1754
  2. 走在技术前沿,今年最火的top5 +Java开源项目
  3. Throwable是java.lang包中一个专门用来处理异常的类
  4. cisco dhcp vlan vrrp ospf 实验
  5. python的try和except_python的try...except
  6. Fragment专辑(三):Fragment的添加(add)和替换(replace)的不同
  7. Silverlight:应用程序模型
  8. 图片格式转换工具与方法
  9. RabbitMq(七) Topic模式介绍及代码示例
  10. 杀毒软件杀毒后桌面图标为什么都成打开方式了
  11. 探讨:软件厂商Kaseya事件是不是软件供应链攻击?
  12. jquery中的过滤filter not的用法以及可以添加this
  13. 一步步写 CMOS 驱动模块 ELDD 学习笔记
  14. 同网段的VLAN隔离
  15. Jvisualvm监控远程SpringBoot项目
  16. 数学原理(The Principles of Mathmatics)
  17. java CANUSB_周立功USBCAN-II 上位机开发(MFC)
  18. mysql超键 候选键_菜鸟学数据库——超键、候选键、主键、外键
  19. 放大器的频率特性(2)-- 共源极的频率特性
  20. dwcs6 mysql站点_在Dreamweaver CS6中如何新建站点的方法

热门文章

  1. fidder配合夜神模拟器进行抓包
  2. 服务器dns显示fec,服务器dns地址fec0
  3. java实现svm svm的java实现
  4. C/C++日志库-log4cplus(log4j的C++版本)
  5. 请问什么叫纹波?怎样测量纹波?
  6. 和云服务器同步文件,和云服务器同步文件
  7. AMiner论文推荐
  8. ThinkPHP5.0 中使用荣联云通讯
  9. MPEG4和DivX的问题解答荟萃
  10. Word格式处理控件Aspose.Words for .NET水印处理教程——如何添加和删除水印