InputManager Update Frequency

2024-01-19 00:18

本文主要是介绍InputManager Update Frequency,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

InputManager Update Frequency 

 仅供个人学习使用,请勿转载,勿用于任何商业用途。

 

    很高兴上一篇文章引起了很多争论,主要是关于以什么频率更新InputManager。大概是上一篇文章说的不够清楚,所以我想再说的详细一点。

    首先,为什么需要IM。Xna只提供了最基本的输入检测方式:只能主动查询某个按键是否被按下,没有事件支持,没有常用的keyJustDown和keyJustUp。其次,我希望在一个地方处理键盘事件,然后转换为响应的系统消息传递给上层组件,这样便于管理,可以非常方便的让用户自定义按键,并且避免冲突。直接让基本的IsKeyDown这样的函数遍布在代码的各处,会很难修改代码,你甚至无法知道哪个对象在捕获输入,捕获了哪些输入。对于同时捕获了相同输入的对象(比如两个textbox),会出现一连串副作用,当然,我们可以让每个对象判断自己当前是否获得了焦点,不过这样会导致大量重复代码,并且更难维护。最后,我希望通过IM,提供类似winForm或者WPF的输入处理方式。
 
    接下来,为什么要以固定频率更新IM。为了方便讨论,这里仅仅以xna的Game框架为例:
 
     以上是基本框架的简化,只要游戏运行以后,就将不停的顺序调用Update和Draw,当然,当xna中的isRunningSlow标志被设置时,会暂时忽略Draw,不过这里我们只假设Update和Draw是一一对应的。

     前面所指的“以固定频率更新IM”表示以某个确定的值更新IM,而不是每次Update都更新。这里指的更新是:判断是否需要触发某个事件(keyboradAction,mouseAction),以及按键的状态是否为Pressing。下图是IM的接口:

     InputState将作为输入事件的参数传递给事件订阅者。其中,有2个事件是非常特别的pressed, moving,因为这两个事件是持续性的,而程序更新的时间是离散,很显然的问题就是以什么频率触发这2个事件。当然,最简单的方式就是每次update只要检测到这两个状态就触发事件。但这样并不是最高效的方法。如果游戏每秒调用数百次Update,就意味着数百次事件触发。有人觉得这样的调用是微不足道的,那么先设想一下你可能如何编写代码:
 

 相信任何人都编写过以上代码。稍微分析以下这段代码可能引起的操作,角色位置改变,意味着坐标变换,矩阵乘法。如果他在sceneGraph中有子node,那么将是一系列矩阵乘法。此外,你需要碰撞检测,检查是否可以移动。动态物体的位置改变,还有可能导致重建sceneGraph,接下来周围所有对象要对你进行AI反馈,等等。想想,每秒数百次,你还觉得代价微不足道吗?在textbox中,按下了A键1秒,就显示出上百个相同的字符,你不觉得bug吗?当然,可以让高层逻辑检查满足一定的条件在作出相应,但这就意味着检查代码会遍布所有对象,所有对象都需要对每一次相应作检查,所有使用IM的人都必需要知道可能发生的潜在问题。为什么不在底层就解决这个问题呢?更何况根本就不需要那么精确的输入精度,即使对于实时交互式程序来说,每秒30~60次更新就足以满足绝大部分需求。

     因此,在我的设计中,只会每隔固定的一段时间,检查是否需要触发某个事件,而不是随Update的速率而改变,保证无论update的频率如何,我的输入更新频率总是一定。当然,这里的IM的刷新频率只能小于等于Update的频率。

     希望以上的解释足够清楚。此外,我在之前的文章中也说过,如果你一开始就考虑程序以固定每秒30或者60次的速度更新,那么就可以完全不用考虑这个问题。最后,在我的实现中,这些而外的输入控制代码只用了几个简单的判断语句而已,我实在没有理由不这么做:

 

以下是我对一些问题的回答:

“不理解按键事件是否这么必要另外你保留了 IsKeyDown的方法这方法和你的事件一起使用不容易乱么”
在上一篇的第二点我说过所有输入都应该通过事件获得。之所以保留了IsxxxPressing这样的函数,因为这是某个框架中的一部分,我希望让使用者获得尽可能多的控制权,同时,这2个函数并不会引起任何逻辑上的错误。

“键盘打字速度的世界记录是大约每分钟800次,也就是每秒13次。很遗憾 据我所知 高桥名人的记录是1秒16次 30次的刷新小小不够“
800次是我google到的结果,可能不一定正确吧:) 之所以提供这个值,是让大家在设计自己的程序时作为一个参考。合理的IM采样间隔就是在不遗漏任何输入情况下的某个最小值。有人觉得推敲用户的输入速度没有必要,假设不知道输入速度,由如何能找出合理的采样间隔呢? 其实我觉得不论13次也好,16次也好,每秒30次的刷新已经足够,如果感兴趣的话,可以自己做个测试看看。13次或者16次,只是非常非常罕见的瞬时状态,这时就算丢失1,2次输入也并不是什么问题,更何况没有游戏需要那么快的输入频率,就像wow每个技能都有冷却时间,冷却时间之内,按的再快也没用。

“效率看起来微乎其微 和一个会放上万Sprite的游戏比起来 优化放在更核心的地方比较好效率“
上面已经讨论过,过高的刷新率会引起一连串的连锁反映,看似微不足道,实际却会被放大上百倍。如果用户知道某个事件将以什么频率触发,那么他编写起程序来也更容易,不是吗?系统的效率取决于系统中的短板,对于游戏更是如此,我希望让每个部份都尽可能的高效。

“那样做出来的东西就是 理论刷新率上百 而地图1秒实际的移动次数只有IM的30 那反而是浪费了上百的刷新率“
理论上,60fps以上人眼就看不出区别了,这也就是为什么很多游戏锁在60fps。不过有人就是喜欢炫耀自己的fps,那就让他浪费好了, 但我们要保证在速度不同的两台机器上,程序行为是一样的。我们是在做游戏而不是精确的物理仿真程序,30~60的更新已经足以:)

 

 

 

这篇关于InputManager Update Frequency的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/620719

相关文章

Chapter 10 Stability and Frequency Compensation

Chapter 10 Stability and Frequency Compensation Chapter 8介绍了负反馈, 这一章介绍稳定性, 如果设计不好, 负反馈系统是要发生震荡的. 首先我们学习理解稳定判断标准和条件, 然后学习频率补偿, 介绍适用于不同运放的补偿方式, 同时介绍不同补偿对两级运放slew rate的影响, 最后介绍Nyquist’s判断标准 10.1 Gener

apt-get update更新源时,出现“Hash Sum mismatch”问题

转载自:apt-get update更新源时,出现“Hash Sum mismatch”问题 当使用apt-get update更新源时,出现下面“Hash Sum mismatch”的报错,具体如下: root@localhost:~# apt-get update ...... ...... W: Failed to fetch http://us.archive.ubuntu.com/ub

ON_COMMAND_RANGE 和 ON_UPDATE_COMMAND_UI_RANGE

 ON_COMMAND_RANGE 和 ON_UPDATE_COMMAND_UI_RANGE 可以影射ID连续的Toolbar/Menu ID。 ON_COMMAND_RANGE影射的消息响应函数需要一个参数UINT表明是哪一个消息, afx_msg void OnZoom(UINT nID); 而ON_UPDATE_COMMAND_UI_RANGE的消息响应函数则无此ID,与ON

update 返回更新的行的 id

应用软件开发过程中, 经常碰到 用 SQL 语句 更新表后, 希望 获取 更新的行 的 id ,  可以通过 以下方法 获取   update [user] set userPwd = '123' output inserted.id , inserted.userName where userName like 'mk%' 更新到多行时,这个方法仍然可用

Update Azure OpenAI npm Package to 2023-12-01-preview Version

题意:将 Azure OpenAI npm 包更新到 2023-12-01-preview 版本 问题背景: I am currently using the azure-openai npm package in my project with version 2023-03-15-preview. As per the latest updates, version 2023-12

myeclipse中没有software update选项

方法一:你在myeclipse中点Windows-->Preferences 在弹出的对话框的左侧栏,点General-->点Capabilities,然后把Classic Update前的框选上,OK了。 方法二:也可以通过Help-->MyEclipse Configuration Center-->Software-->Add Site的方式进行插件安装。。

mongoose 查询,删除,update等

1.首先,引入mongoose(前提,你已经有了model,里面有数据) var mongoose = require('mongoose'); 2.连接mongondb, 连接数据库 var url = config.mongoUrl;//连接mongodbmongoose.connect(url);var db = mongoose.connection;// 连接失败d

C# 窗体中Control以及Invalidate,Update,Refresh三种重绘方法的区别

在 C# 中,Control 类是 Windows Forms 应用程序中所有控件的基类。它提供了控件的基本功能和属性,这些功能和属性被所有继承自 Control 类的子类所共享。这意味着 Control 类是构建 Windows Forms 应用程序中用户界面元素的基础。 以下是 Control 类的一些关键特性和方法: 属性: Size:获取或设置控件的宽度和高度。Location:获

Datax 支持增量 oracle writeMode update

Datax 支持增量 oracle update datax介绍支持增量 oracle update修改 OracleWriter.java修改WriterUtil.java修改CommonRdbmsWriter.java效果源码 datax介绍 DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgr

Datax 支持增量 postgresql writeMode update

Datax 支持 postgresql update datax介绍支持增量 postgresql update修改 PostgresqlWriter.java修改WriterUtil.java效果源码 datax介绍 DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、AD