《Genesis-3D开源游戏引擎--横版格斗游戏制作教程04:技能的输入与检测》
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:技能的输入与检测》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- Erlang 开发者的福音:IntelliJ IDEA 的 Erlang 插件
IntelliJ IDEA 的 Erlang 插件,主要特性: 智能编辑器: Erlang 代码补全.语法和错误高亮.代码检查 代码导航:项目和文件结构视图.在文件.模型.函数和用例之间快速跳转 工 ...
- PL/SQL — 集合及常用方法
PL/SQL中提供了常用的三种集合联合数组.嵌套表.变长数组,而对于这几个集合类型中元素的操作,PL/SQL提供了相应的函数或过程来操纵数组中的元素或下标.这些函数或过程称为集合方法.一个集合方法就是 ...
- 【toplink】 位居第一的Java对象关系可持续性体系结构
TopLink,是位居第一的Java对象关系可持续性体系结构,原署WebGain公司的产品,后被Oracle收购,并重新包装为Oracle AS TopLink.TOPLink为在关系数据库表中存储 ...
- SIAlertView
SIAlertView是AlertView的替代产品 的效果比较多 . 使用实例: SIAlertView *alertView = [[SIAlertView alloc] initWithTitl ...
- 遍历DOM的所有节点,输出宽度高度都大于50的元素节点名称
需要注意的问题有几点: 1.遍历所有元素节点的方式是:document.getElementsByTagName("*"),同时为了兼容性好可以再一句:document.all 2 ...
- 简单的网页布局效果html5+CSS3
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- location.hash && location.href
hash:设置或获取 href 属性中在井号“#”后面的分段. href:设置或获取整个URL为字符串. 通过下面的测试你会发现区别,将代码放到你的HTML中,然后用浏览器打开,测试步骤: 点击“超链 ...
- 用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 ...
- mysql 监控工具monyog使用总结
1. 下载安装 2. 登录之后,查看 locked queries 2. 慢查询
- 严重: The web application [] registered the JDBC driver 错误
近日发现启动tomcat的时候报如下警告: -- :: org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc 严重: The ...