《Genesis-3D開源遊戲引擎--橫版格鬥遊戲製做教程03:碰撞檢測》

3.碰撞檢測

碰撞檢測的概述:

碰撞在物理學中表現爲兩粒子或物體間極端的相互做用。而在遊戲世界中,遊戲對象在遊戲世界自身並不受物理左右,爲了模擬真實世界的效果,須要開發者爲其添加屬性,以模擬真實事件的運動效果。在遊戲世界裏,當遊戲主角與其它遊戲對象發生碰撞時,都會觸發一個相應的事件發生。這時候就須要開發者先檢測到碰撞現象,即碰撞檢測。在Genesis-3D引擎中,能檢測碰撞發生的方式有兩種:一種是利用碰撞器,一種是利用觸發器。 ide

碰撞檢測原理:

爲須要檢測碰撞事件的物體建立子空Actor,做爲檢測碰撞物體的包裝盒,用於程序對碰撞事件發生的斷定。實時檢測包圍盒之間是否發生交叉、包含等關係時候,如若發生,及斷定檢測碰撞發生,觸發碰撞事件。 函數


圖3-1-1 網站

 

實現方法:
實現整個碰撞事件過程當中,值得開發者花心思的是檢測這一塊內容。舉例:主角攻擊敵人的碰撞檢測事件。在必定範圍內,玩家控制主角攻擊敵人,武器與敵人發生碰撞檢測事件,敵人掉血。原本一系列的程序設定都十分順暢,但這裏要注意,由於碰撞檢測是實時監測,可是碰撞結果掉血在這一過程當中只發生一次,如何在必定事件內,只發生一次碰撞事件的成功檢測,值得開發者考究一下。 3d

步驟1:
碰撞檢測體包圍盒的製做。在場景中建立->空物體(空物體,即空Actor),將空Actor拖動到物體上,成爲其子空Actor。
步驟2:
程序上碰撞提包圍盒的建立以下所示。 code

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  ip

Genesis-3D開源遊戲引擎:遊戲起源,皆因有我!!! 遊戲開發

相關文章
相關標籤/搜索