4.技能的输入与检测

概述:

技能系统的用户体验,制约着玩家对整个游戏的体验。游戏角色的技能华丽度,连招的顺利过渡,以及逼真的打击感,都作为一款游戏的卖点吸引着玩家的注意。开发者在开发游戏初期,会根据玩家对此类游戏的惯性操作,设定技能控制按键。同时Genesis引擎为开发者提供的众多API接口,包含了按键过程、按键按下和抬起的识别功能。当玩家根据游戏设定的按键操作,输入后。系统会记录按键操作的命令,然后程序通过对玩家当前输入状态,以及输入的过程检测,判定技能输入是否为有效输入。

技能系统的用户体验,制约着玩家对整个游戏的体验。游戏角色的技能华丽度,连招的顺利过渡,以及逼真的打击感,都作为一款游戏的卖点吸引着玩家的注意。开发者在开发游戏初期,会根据玩家对此类游戏的惯性操作,设定技能控制按键。同时Genesis-3D引擎为开发者提供的众多API接口,包含了按键过程、按键按下和抬起的识别功能。当玩家根据游戏设定的按键操作,输入后。系统会记录按键操作的命令,然后程序通过对玩家当前输入状态,以及输入的过程检测,判定技能输入是否为有效输入。

原理:

按键定义->输入->检测输入状态->检测输入过程。


图4-1

技能输入检测的实现:

步骤1:

引擎提供了相应的API接口,供开发者使用,其中就包括三个与按键相关的接口,一个是按键过程中、按键按下、按键抬起。在ScriptRuntime命名里,有个Input类下,为情提供了相应接口。开发者可以直接定义按下当前操控间,所作的操作。以攻击为例,如下所示。

1 if (Input.KeyDown(Code.J))
2 {
3  Attack_N(Code.J);
4 }

步骤2:

检测输入条件,即玩家当前状态的输入权限。

玩家根据开发者对游戏的设定,进行相关按键操作。当玩家按下按键之后,程序记录按键事件。之后按照开发者定义的检测规则,判定玩家输入是否有效。由于按键所属的功能不同,相应筛选机制也是不同的。技能的输入条件检测,可以通过动画区间帧来控制。玩家权限的判定,是否键输有效。攻击键J举例,原理图,如图4-1-1所示。


图4-2-1

横向为动画帧,上面的A、B、C、D、E等代表所在时间轴上响应的帧数。判定玩家连招输入权限,程序逐帧检测当前帧玩家所属状态。在A点输入J攻击键后,程序遍历每帧玩家状态。在A-B动画区间帧内玩家为无权限输入,玩家即使有键入指令,程序也不认为输入状态有效,进而不做后面的检测。只有在B-C动画区间内时,程序判定玩家有输入权限,玩家在该动画区间内获得键入权限。如在该区间内有攻击键J的输入,程序即遍历后面的动画帧,若无有限键入,即停止此次连招技能的输入状态的检测。

步骤3:

private PlayerRight m_eRight = PlayerRight.ReceiveKeyboard; //玩家权限,包含:接收按键操作、对怪物的有效碰撞伤害

步骤4:

动画区间检测输入状态,代码如下所示。

public class SkillAnimation

{

 public SkillAnimation()

 {

  m_vCallback = new Dictionary< UInt32, List<framecallback>>();

 }

  public delegate void FrameCallback(UInt32 iFrame);

  //帧回调函数容器< 帧数,<回调函数list>>

  private Dictionary< UInt32, List<framecallback>> m_vCallback;  

  //注册帧回调函数

  public void RegisterFrameCallback(UInt32 iFrame, FrameCallback callback)

  {

   if (!m_vCallback.ContainsKey(iFrame))

   {

    List<framecallback> vCallback = new List<framecallback>();

    m_vCallback.Add(iFrame, vCallback);

   }

   m_vCallback[iFrame].Add(callback);

  }

  //清空注册的帧回调函数

  public void Clear()

  {

   foreach (KeyValuePair< UInt32, List<framecallback>> pair in m_vCallback)

   {

    pair.Value.Clear();

   }

   m_vCallback.Clear();

  }

  //遍历注册的帧回调函数,根据播放的帧数触发相应的函数

  public void Tick(UInt32 iCurrentFrame)

  {

   List<uint32> vPlayCompleted = new List<uint32>();

   //遍历注册的回调函数,并触发相应的函数

   foreach (KeyValuePair< UInt32, List<framecallback>> pair in m_vCallback)

   {

    if (pair.Key <= iCurrentFrame)

    {

     foreach (FrameCallback callback in pair.Value)

     {

      callback(pair.Key);

     }

      vPlayCompleted.Add(pair.Key);

    }

   }

   //删除已触发的回调函数

   foreach (UInt32 iCompleted in vPlayCompleted)

   {

    m_vCallback[iCompleted].Clear();

    m_vCallback.Remove(iCompleted);

   }

  }

}

public class SkillAnimationMgr

{

 private SkillAnimationMgr()

 {

  m_vSkillAnimation = new Dictionary< string, SkillAnimation>();

 }

 private static SkillAnimationMgr s_Instance;

 private Dictionary< string, SkillAnimation> m_vSkillAnimation;

 public static SkillAnimationMgr Instance

 {

 get

 {

  if (null == s_Instance)

  {

   s_Instance = new SkillAnimationMgr();

  }

  return s_Instance;

 }

}

public void Init() { }

//添加动画帧回调组件功能

public void AddSkillAnimation(string sAnimationName, SkillAnimation skillAnimation)

{

 if (!m_vSkillAnimation.ContainsKey(sAnimationName))

 {

  m_vSkillAnimation.Add(sAnimationName, skillAnimation);

 }

}

//删除动画帧回调组件功能

public void RemoveSkillAnimation(string sAnimationName)

{

 if (m_vSkillAnimation.ContainsKey(sAnimationName))

 {

  m_vSkillAnimation[sAnimationName].Clear();

  m_vSkillAnimation.Remove(sAnimationName);

 }

}

//Tick管理器中注册的全部帧回调组件

public void Tick(float fElaspeTime)

{

 //未移除当前Tick时不在播放状态的动画SkillAnimation

 foreach (KeyValuePair < string, SkillAnimation > item in m_vSkillAnimation)

 {

  if (ViewMgr.Instance.CurPlayerView.IsSkillAnimationPlaying(item.Key))

  {

   UInt32 iFrame = (UInt32)ViewMgr.Instance.CurPlayerView.GetPlayingAnimationFrame();

   item.Value.Tick(iFrame);

  }

 }

}</framecallback></uint32></uint32></framecallback></framecallback></framecallback></framecallback></framecallback>
步骤5:
对输入过程筛选,输入成功的放入缓存器中,即完成了程序对技能输入的检测,如下所示。 public void Attack_N(Code code)//筛选过程,最后将筛选后的输入,放入缓存器中。 {  //技能输入筛选条件  if (LogicMgr.Instance.CurPlayer.CheckIdleState() || (LogicMgr.Instance.CurPlayer.CheckJumpState() && !LogicMgr.Instance.CurPlayer.CheckAttackIdleState()))  {   LogicMgr.Instance.AddInputKeyboard(code);   LogicMgr.Instance.CurPlayer.Attack_N();  }   else if (LogicMgr.Instance.CurPlayer.CheckAttackState())  {   if (LogicMgr.Instance.CurPlayer.CheckRight(PlayerRight.ReceiveKeyboard))   {    LogicMgr.Instance.AddInputKeyboard(code);   }  } }

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

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

官方千人大群:59113309   135439306

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

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

 

《Genesis-3D开源游戏引擎--横版格斗游戏制作教程04:技能的输入与检测》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. Django操作数据库

    引入models的定义 from app.models import  myclass class  myclass():      aa =  models. CharField (max_leng ...

  2. WebLogic启动时报错

    java.lang.ClassCastException: com.octetstring.vde.backend.BackendRoot cannot be cast to com.octetstr ...

  3. Java学习--Equals与“==”

    在Java规范中,它对equals()方法的使用必须要遵循如下几个规则: equals 方法在非空对象引用上实现相等关系: 1.自反性:对于任何非空引用值 x,x.equals(x) 都应返回 tru ...

  4. 一步步学习ASP.NET MVC3 (8)——EmptyResult,ContentResult,RedirectResult

    请注明转载地址:http://www.cnblogs.com/arhat 上一章,我们阐述了Controller,Action和ActionResult所代表的含义及使用,本章继续研究ActionRe ...

  5. 制作第一个UI图集

    按钮分有两种形式,一种是普通按钮,也就是一张没有文字的按钮图片,在需要用时,就在上面写上不同的.当前所需要的文字.量一种按钮则是图片按钮,这种按钮的特点是整个按钮就是一张图片,它既是按钮也是图片. 在 ...

  6. Objective-c开发中混合使用ARC

    首选“Compile Sources”的位置: 选中工程->TARGETS->相应的target然后选中右侧的“Build Phases”,向下就找到“Compile Sources”了. ...

  7. 如何获得iphone设备的剩余空间

    在手机终端开发的时候,我们需要关注手机剩余空间,因为手机不像电脑一样空间宽裕,当设备空间比较少得时候需要释放空间. 用法:先引入头文件 #include <sys/param.h> #in ...

  8. Java中的数组问题

    java.util.Arrays  This class deals with 'real' arrays in java, in the form of T[]. Thus it doesn't d ...

  9. ireport 在 AIX Linux websphere下的字体安装

    首先,ireport在linux下有些时候是正常的,而有些时候却不正常,只要是汉字就出不来的情况我今天是遇到了. ireport在Linux下不显示中文汉字的解决方法: 将字体文件(后缀名必须是ttf ...

  10. BT5之网络配置

    输入ifconfig命令,可以查看当前IP地址设置情况.查看路由表的命令(用来检查默认网关是否设置正确):netstat -r 一.让BT5自动获取IP地址 自动获取IP地址,使用dhclient命令 ...