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

3.碰撞检测

碰撞检测的概述:

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

碰撞检测原理:

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

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

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

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

01

//玩家碰撞体的创建,三部分:左手、右手和身体

02

public 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

//敌人的碰撞体创建分两部分:武器和身体。

15

public 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

 

26

public 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

//实时监测碰撞状态

02

public 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

//移除碰撞对象

31

private 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类

46

public 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

     //

58

public void RemoveBeCollidedActor(Actor beCollidedActor)

59

{

60

 if (_beCollidedActors.Contains(beCollidedActor))

61

 {

62

  _beCollidedActors.Remove(beCollidedActor);

63

 }

64

}

65

public bool IsContainsBeCollidedActor(Actor beCollidedActor)

66

{

67

 return _beCollidedActors.Contains(beCollidedActor);

68

}

69

public delegate void callback(Actor other);//注册回调函数???

70

private callback _callback;

71

private Actor _colliderActor;

72

private List<actor> _beCollidedActors = new List<actor>(); //碰撞中Actor列表</actor></actor>

步骤4:

碰撞效果。举例:主角攻击敌人,敌人掉血。

01

public 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开源游戏引擎:游戏起源,皆因有我!!!

 

你可能感兴趣的:(游戏引擎)