开发框架——横版格斗——4.技能的输入与检测

4.技能的输入与检测

概述:

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

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

原理:

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


图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:

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

001 public class SkillAnimation
002 {
003  public SkillAnimation()
004  {
005   m_vCallback = new Dictionary< UInt32, List<framecallback>>();
006  }
007   public delegate void FrameCallback(UInt32 iFrame);
008   //帧回调函数容器< 帧数,<回调函数list>>
009   private Dictionary< UInt32, List<framecallback>> m_vCallback;  
010   //注册帧回调函数
011   public void RegisterFrameCallback(UInt32 iFrame, FrameCallback callback)
012   {
013    if (!m_vCallback.ContainsKey(iFrame))
014    {
015     List<framecallback> vCallback = new List<framecallback>();
016     m_vCallback.Add(iFrame, vCallback);
017    }
018    m_vCallback[iFrame].Add(callback);
019   }
020   //清空注册的帧回调函数
021   public void Clear()
022   {
023    foreach (KeyValuePair< UInt32, List<framecallback>> pair in m_vCallback)
024    {
025     pair.Value.Clear();
026    }
027    m_vCallback.Clear();
028   }
029   //遍历注册的帧回调函数,根据播放的帧数触发相应的函数
030   public void Tick(UInt32 iCurrentFrame)
031   {
032    List<uint32> vPlayCompleted = new List<uint32>();
033    //遍历注册的回调函数,并触发相应的函数
034    foreach (KeyValuePair< UInt32, List<framecallback>> pair in m_vCallback)
035    {
036     if (pair.Key <= iCurrentFrame)
037     {
038      foreach (FrameCallback callback in pair.Value)
039      {
040       callback(pair.Key);
041      }
042       vPlayCompleted.Add(pair.Key);
043     }
044    }
045    //删除已触发的回调函数
046    foreach (UInt32 iCompleted in vPlayCompleted)
047    {
048     m_vCallback[iCompleted].Clear();
049     m_vCallback.Remove(iCompleted);
050    }
051   }
052 }
053 public class SkillAnimationMgr
054 {
055  private SkillAnimationMgr()
056  {
057   m_vSkillAnimation = new Dictionary< string, SkillAnimation>();
058  }
059  private static SkillAnimationMgr s_Instance;
060  private Dictionary< string, SkillAnimation> m_vSkillAnimation;
061  public static SkillAnimationMgr Instance
062  {
063  get
064  {
065   if (null == s_Instance)
066   {
067    s_Instance = new SkillAnimationMgr();
068   }
069   return s_Instance;
070  }
071 }
072 public void Init() { }
073 //添加动画帧回调组件功能
074 public void AddSkillAnimation(string sAnimationName, SkillAnimation skillAnimation)
075 {
076  if (!m_vSkillAnimation.ContainsKey(sAnimationName))
077  {
078   m_vSkillAnimation.Add(sAnimationName, skillAnimation);
079  }
080 }
081 //删除动画帧回调组件功能
082 public void RemoveSkillAnimation(string sAnimationName)
083 {
084  if (m_vSkillAnimation.ContainsKey(sAnimationName))
085  {
086   m_vSkillAnimation[sAnimationName].Clear();
087   m_vSkillAnimation.Remove(sAnimationName);
088  }
089 }
090 //Tick管理器中注册的全部帧回调组件
091 public void Tick(float fElaspeTime)
092 {
093  //未移除当前Tick时不在播放状态的动画SkillAnimation
094  foreach (KeyValuePair < string, SkillAnimation > item in m_vSkillAnimation)
095  {
096   if (ViewMgr.Instance.CurPlayerView.IsSkillAnimationPlaying(item.Key))
097   {
098    UInt32 iFrame = (UInt32)ViewMgr.Instance.CurPlayerView.GetPlayingAnimationFrame();
099    item.Value.Tick(iFrame);
100   }
101  }
102 }</framecallback></uint32></uint32></framecallback></framecallback></framecallback></framecallback></framecallback>

步骤5:

对输入过程筛选,输入成功的放入缓存器中,即完成了程序对技能输入的检测,如下所示。

01 public void Attack_N(Code code)//筛选过程,最后将筛选后的输入,放入缓存器中。
02 {
03  //技能输入筛选条件
04  if (LogicMgr.Instance.CurPlayer.CheckIdleState()
05               || (LogicMgr.Instance.CurPlayer.CheckJumpState() && !LogicMgr.Instance.CurPlayer.CheckAttackIdleState()))
06  {
07   LogicMgr.Instance.AddInputKeyboard(code);
08   LogicMgr.Instance.CurPlayer.Attack_N();
09  }
10   else if (LogicMgr.Instance.CurPlayer.CheckAttackState())
11  {
12   if (LogicMgr.Instance.CurPlayer.CheckRight(PlayerRight.ReceiveKeyboard))
13   {
14    LogicMgr.Instance.AddInputKeyboard(code);
15   }
16  }
17 }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值