3.碰撞检测

碰撞检测的概述:

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

碰撞检测原理:

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


图3-1-1
 

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

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

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

public override void OnLoad()

{

 Actor leftActor = ActorManager.FindActiveActor("BBCollider_LeftCollider");

 Actor rightActor = ActorManager.FindActiveActor("BBCollider_RightCollider");

 Actor playerActor = ActorManager.FindActiveActor("BBCollider_Player");

 playerCollder.RegistFun(playerActor,BBCollideHitCallBack);

 leftCollder.RegistFun(leftActor ,BBCollideCallBack);

 rightCollder.RegistFun(rightActor,BBCollideCallBack);

 Logic.BBCollideMgr.Instance.Register(leftCollder);

 Logic.BBCollideMgr.Instance.Register(rightCollder);

 Logic.BBCollideMgr.Instance.Register(playerCollder);

}

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

public override void OnLoad()//武器

{

 Logic.BBCollder weaponCollder = new Logic.BBCollder();

 Actor weaponCollderActor = Owner;

 if (weaponCollderActor != null)

 {

  weaponCollder.RegistFun(weaponCollderActor, BBCollideATKCallBack);

  Logic.BBCollideMgr.Instance.Register(weaponCollder);

 }

}

public override void OnLoad()//敌人

{

 string ownerNum = Owner.Name.Substring(TriggerNameHead.Length);

 EnemyParent = ActorManager.FindActiveActor(EnemyParentNameHead + ownerNum);

 Name = "BBCollider_Enemy001";

 Logic.BBCollder collder = new Logic.BBCollder();

 Actor collderActor = Owner;

 if (collderActor != null)

 {

  collder.RegistFun(collderActor, BBCollideCallBack);

  Logic.BBCollideMgr.Instance.Register(collder);

 }

}
步骤3:
碰撞检测。
view sourceprint? //实时监测碰撞状态 public void Tick(float elapseTime) {  //遍历碰撞体容器,检测每两个碰撞体间碰撞状态  int iCollidersCount = Colliders.Count;  for (int ii = ; ii < iCollidersCount; ++ii)  {   for (int jj = ii + ; jj < iCollidersCount; ++jj)   {    RemoveBeCollidedActor(Colliders[ii], Colliders[jj]);    BoundingBox bbi = Colliders[ii].ColliderActor.WorldBoundingBox;    BoundingBox bbj = Colliders[jj].ColliderActor.WorldBoundingBox;    if (ClipStatus.Outside != bbi.Contains(bbj) && ClipStatus.Outside != bbj.Contains(bbi))    {     if (Colliders[jj].ColliderActor.IsActive && !Colliders[ii].IsContainsBeCollidedActor(Colliders[jj].ColliderActor))     {      Colliders[ii].Call(Colliders[jj].ColliderActor);      Colliders[ii].AddBeCollidedActor(Colliders[jj].ColliderActor);     }     if (Colliders[ii].ColliderActor.IsActive && !Colliders[jj].IsContainsBeCollidedActor(Colliders[ii].ColliderActor))     {      Colliders[jj].Call(Colliders[ii].ColliderActor);      Colliders[jj].AddBeCollidedActor(Colliders[ii].ColliderActor);     }    }   }  } } //移除碰撞对象 private void RemoveBeCollidedActor(BBCollder actor, BBCollder beCollided) {  BoundingBox actorBox = actor.ColliderActor.WorldBoundingBox;  BoundingBox beCollidedBox = beCollided.ColliderActor.WorldBoundingBox;  if (ClipStatus.Outside == actorBox.Contains(beCollidedBox))  {   actor.RemoveBeCollidedActor(beCollided.ColliderActor);  }   if (ClipStatus.Outside == beCollidedBox.Contains(actorBox))  {   beCollided.RemoveBeCollidedActor(actor.ColliderActor);  } } //定义BBCollder类 public class BBCollder {  public void RegistFun(Actor self, callback fun)  {   _colliderActor = self;   _callback = fun;  }  public void Call(Actor other)  {   _callback(other);  } // public void RemoveBeCollidedActor(Actor beCollidedActor) {  if (_beCollidedActors.Contains(beCollidedActor))  {   _beCollidedActors.Remove(beCollidedActor);  } } public bool IsContainsBeCollidedActor(Actor beCollidedActor) {  return _beCollidedActors.Contains(beCollidedActor); } public delegate void callback(Actor other);//注册回调函数??? private callback _callback; private Actor _colliderActor; private List<actor> _beCollidedActors = new List<actor>(); //碰撞中Actor列表</actor></actor>
步骤4:
碰撞效果。举例:主角攻击敌人,敌人掉血。 public void BBCollideHitCallBack (Actor other) {  if (other.Name.StartsWith ("BBCollider_EnemyATK"))  {  EnemyState state = Logic.EnemyMgr.Instance.EnemyState(other.Parent.Name);  bool judget = Logic.EnemyMgr.Instance.GetEnemyJudge(other.Parent.Name);   if (state == EnemyState.Attack && judget && !Logic.LogicMgr.Instance.CurPlayer.CheckDefenseState() && !Logic.LogicMgr.Instance.CurPlayer.CheckDieState())   {    int playerHP = Logic.PlayerDateMgr.Instance.HP;    playerHP --;    Logic.PlayerDateMgr.Instance.SetHP(playerHP);    Logic.LogicMgr.Instance.CurPlayer.State = Logic.CharacterState.Hurt;   }  } }

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

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

官方千人大群:59113309   135439306

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

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

 

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

  1. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程:简介及目录》(附上完整工程文件)

    介绍:讲述如何使用Genesis-3D来制作一个横版格斗游戏,涉及如何制作连招系统,如何使用包围盒实现碰撞检测,软键盘的制作,场景切换,技能读表,简单怪物AI等等,并为您提供这个框架的全套资源,源码以 ...

  2. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程04:技能的输入与检测》

    4.技能的输入与检测 概述: 技能系统的用户体验,制约着玩家对整个游戏的体验.游戏角色的技能华丽度,连招的顺利过渡,以及逼真的打击感,都作为一款游戏的卖点吸引着玩家的注意.开发者在开发游戏初期,会根据 ...

  3. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程01: 资源导入》

    1. 资源导入 概述: 制作一款游戏需要用到很多资源,比如:模型.纹理.声音和脚本等.通常都是用其它相关制作资源软件,完成前期资源的收集工作.比如通常用的三维美术资源,会在Max.MAYA等相应软件中 ...

  4. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程08:虚拟键盘实现》--本系列完结

    8.虚拟键盘实现 概述: 硬键盘就是物理键盘,平时敲的那种.软键盘是虚拟的键盘,不是在键盘上,而是在"屏幕"上.虚拟按键就是虚拟键盘的一部分,根据功能需求,提供部分按键效果的UI可 ...

  5. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程07:UI》

    概述: UI即User Interface(用户界面)的简称.UI设计是指对软件的燃机交互.操作逻辑.界面美观的整体设计.好的UI设计不仅可以让游戏变得更有品位,更吸引玩家,还能充分体现开发者对游戏整 ...

  6. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程06:技能播放的逻辑关系》

    6.技能播放的逻辑关系 技能播放概述: 当完成对技能输入与检测之后,程序就该对输入在缓存器中的按键操作与程序读取的技能表信息进行匹配,根据匹配结果播放相应的连招技能. 技能播放原理: 按键缓存器中内容 ...

  7. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程05:技能读表》

    5.技能读表 技能读表概述: 技能读表,作为实现技能系统更为快捷的一种方式,被广泛应用到游戏开发中.技能配表,作为桥梁连接着游戏策划者和开发者在技能实现上的关系.在游戏技能开发中,开发者只需要根据策划 ...

  8. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程02:关键帧动画导入与切割》

    2. 关键帧动画导入与切割 动画的分割与导入概述: 在游戏当中,游戏角色在不同状态下会有不同的动作,这些动作在引擎里相当于一段段的动画片段.当导入模型资源的时候,连同模型动画都会一并导入到引擎中.开发 ...

  9. Beat &amp;#39;Em Up Game Starter Kit (横版格斗游戏) cocos2d-x游戏源代码

    浓缩精华.专注战斗! 游戏的本质是什么?界面?养成?NoNo!    游戏来源于对实战和比赛的模拟,所以它的本源就是对抗.就是战斗! 是挥洒热血的一种方式! 一个游戏最复杂最难做的是什么?UI?商城? ...

随机推荐

  1. html 关于块级元素和行内元素

    常用的行内元素要记住:a.span.img.input.lable.select.strong.textarea 常用的块级元素要记住:div.h1~h6.dl.ul.ol 例如在一个title中,有 ...

  2. 安装好Windows 8后必做的几件事情,让你的Win8跑的更快更流畅。

    1.关闭家庭组,因为这功能会导致硬盘和CPU处于高负荷状态. 关闭方法:Win+C-设置-更改电脑设置-家庭组-离开 如果用不到家庭组可以直接把家庭组服务也给关闭了:控制面板-管理工具-服务-Home ...

  3. .net对文件的操作之对文件目录的操作

    .NET 提供一个静态File类用于文件的操作,下面列出它的主要操作方法. 返回值类型 方法名称 说明 bool Exists(string path) 用于检查指定文件是否存在 void Copy( ...

  4. Navicat_Preminum

    一. 安装 参考http://blog.csdn.net/longyuhome/article/details/79206041. 软件准备• [OYKSOFT.COM]navicat11.0.8_p ...

  5. Vim复制文件全部内容到系统剪贴板

    参考:http://vim.wikia.com/wiki/%22copy_all_to_clipboard%22_howto vim中有两个buffer为系统的剪贴板,它们为: * (primary ...

  6. linux 添加自定义环境变量

    1. vi /etc/profile ,在文件末尾加上要定义的环境变量,语法如下: export 变量名=变量值

  7. &quot;urllib&quot;库的学习

    在习题—41遇到这个模块/库, 有兴趣的参考下面这个网址: http://blog.sina.com.cn/s/blog_b369b20d0101kb7m.html # coding: utf-8 i ...

  8. win7上Android环境搭建以及调试

    工欲善其事必先利其器,好记性不如烂笔头.要学习一门新的语言,首先必须得先搭环境,否则没法实践.如果之前按照网上的提示,搭建过环境,而且环境比较复杂的话,我相信隔很长一段时间后,就会忘记,到真正用的时候 ...

  9. Nodejs http-proxy代理实战应用

    var https = require('https'); var express = require('express'); var app = express() var http = requi ...

  10. ubuntu18.04安装openresty

    ubuntu18.04使用openresty官方APT源安装openresty 添加openresty的 APT 仓库,这样就可以便于未来安装或更新软件包(通过 apt-get update 命令). ...