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. Erlang 开发者的福音:IntelliJ IDEA 的 Erlang 插件

    IntelliJ IDEA 的 Erlang 插件,主要特性: 智能编辑器:  Erlang 代码补全.语法和错误高亮.代码检查 代码导航:项目和文件结构视图.在文件.模型.函数和用例之间快速跳转 工 ...

  2. PL/SQL — 集合及常用方法

    PL/SQL中提供了常用的三种集合联合数组.嵌套表.变长数组,而对于这几个集合类型中元素的操作,PL/SQL提供了相应的函数或过程来操纵数组中的元素或下标.这些函数或过程称为集合方法.一个集合方法就是 ...

  3. 【toplink】 位居第一的Java对象关系可持续性体系结构

    TopLink,是位居第一的Java对象关系可持续性体系结构,原署WebGain公司的产品,后被Oracle收购,并重新包装为Oracle AS TopLink.TOPLink为在关系数据库表中存储 ...

  4. SIAlertView

    SIAlertView是AlertView的替代产品 的效果比较多 . 使用实例: SIAlertView *alertView = [[SIAlertView alloc] initWithTitl ...

  5. 遍历DOM的所有节点,输出宽度高度都大于50的元素节点名称

    需要注意的问题有几点: 1.遍历所有元素节点的方式是:document.getElementsByTagName("*"),同时为了兼容性好可以再一句:document.all 2 ...

  6. 简单的网页布局效果html5+CSS3

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. location.hash && location.href

    hash:设置或获取 href 属性中在井号“#”后面的分段. href:设置或获取整个URL为字符串. 通过下面的测试你会发现区别,将代码放到你的HTML中,然后用浏览器打开,测试步骤: 点击“超链 ...

  8. 用CURL来实现file_get_contents函数:curl_file_get_contents

    <?php $url='http://www.bamuyu.com/news/zixun/list_7_2.html'; $content=curl_file_get_contents($url ...

  9. mysql 监控工具monyog使用总结

    1. 下载安装 2. 登录之后,查看 locked queries 2. 慢查询

  10. 严重: The web application [] registered the JDBC driver 错误

    近日发现启动tomcat的时候报如下警告: -- :: org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc 严重: The ...