A Simple Input Manager for XNA

XNA教程(一) 作者:Mike Fleishauer & clayman本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。Blog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn  special thanks to Mike Fleishauer ^_^ 阅读详情

A Simple Input Manager for XNA

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

(update on 4.28 09: 这篇文章的设计是有bug的,详细更新可以看这里)

           Why we need input manager? 在PC平台上,KeyboardState和MouseState提供了基本的用户输入信息,但是对实际编写游戏来说,还缺少了几个关键功能。首先,这两个类只能“拉”出数据,而不能主动“推”数据,也就是说,需要客户端显式查询某个键的状态,而不能当键状态发生改变时通知客户。其次,IsKeyDown和IsKeyUp返回的值并不是我们所预期的。对于普通的KeyDown事件来说,只在按键第一次被按下的时候触发,比如我们在t1时刻按下按键,触发keydown事件,到t2时刻,即使按键仍然处于按下的状态,也不应该触发keydown事件。而对于IsKeyDown来说,不论何时,只要按键处于按下状态就一直返回true,IsKeyUp也具有同样的行为。我习惯把XNA的IsKeyDown成为pressing,而把只在按键第一次状态变化时触发的事件成为keydown或者keyup。最后,查询某个键被按下了多久,也是很常见的操作。

           基于以上讨论,input manager其实只是一个简单的类,只需要具有以下功能:
1. 同时支持推和拉模型
2. 支持以下事件:KeyDown, KeyUp, KeyPressing, MouseDown, MouseUp, MousePressing, MouseMove, MouseWheel。大部分事件接受一个void GenericEventHandle<T>(T t); 类型的委托
3. 支持查询某个按键被按下的时间

 我们可以马上写出Input Manger的接口:

           实现起来也非常简单,保存当前和上一次更新时的键盘,鼠标状态。游戏主循环调用Update,每次更新时次迭代所有键,检查状态是否有改变,触发相应的事件。为了支持时间查询,用一个Dirctionay来记录每个按键被按下的时间。

          这里有两点需要注意的地方:首先,迭代更新按键状态不要用foreach + Enum.GetValues(typeof(Keys))的方法来实现。GetValues基于反射,相对来说是比较慢的操作。可以尝试把所有枚举值保存到普通数组里,迭代数组来遍历所有按键要快的多。另外,记录每个按键时间的Dirctionay不要用Enum做key。使用Enum类型做key,需要进行装箱。把Enum转换成int再做为Dirctionay的键值来使用,就能得到很大的性能提升。

          当然这里还有一个潜在的问题,应该以多快的频率来更新输入状态呢? 前面提到过,在游戏主循环中调用update(),这意味着对于IsFixedTimeStep为true的XNA游戏来说,将每秒更新60次;而对IsFixedTimeStep为false的游戏来说,根据实际情况,每秒更新几十次或者几百次都是有可能的。问题是我们需要每秒更新那么多次吗?目前键盘打字速度的世界记录是大约每分钟800次,也就是每秒13次,我没有找到鼠标点击速度的世界记录,不过自己测试了以下,每秒6~8次点击已经是极限速度。根据奈奎斯特(Nyquist)采样定理,只要采样频率大于信号中最高频率的2倍时,就能完整保留原始信号中的信息,也就是说,即使你是世界冠军,每秒30次更新就足以捕获你的所有输入。从上面的类图中可以看到,我们允许用户分别设置键盘,鼠标击键的更新频率和鼠标移动事件的触发频率,因此,update中的代码可能看起来是这样的:

  1. public void Update(GameTime gameTime)
  2. {
  3.     float elapsedTime = (float)(gameTime.ElapsedGameTime.TotalSeconds);
  4.     keyboardUpdateCount += elapsedTime;
  5.     mouseButtonUpdateCount += elapsedTime;
  6.     mouseMoveUpdateCount += elapsedTime;
  7.     if (keyboardUpdateCount >= keyboardUpdateInterval)
  8.     {
  9.         //Update keyboard state,fire keyboard event
  10.         keyboardUpdateCount = 0;
  11.     }
  12.     if (mouseButtonUpdateCount >= mouseButtonUpdateInterval)
  13.     {
  14.         //update mouse state,fire mouse event
  15.         mouseButtonUpdateCount = 0;
  16.     }
  17.     if (mouseMoveUpdateCount >= mouseMoveUpdateInterval)
  18.     {
  19.         //update mouse position,fire mouse move event if needed
  20.         mouseMoveUpdateCount = 0;
  21.     }
  22. }

           你可以注意到Input Manager还有一个active属性。原因是当XNA游戏失去焦点时,KeyboardState和MouseState仍然能捕获到用户输入,对大多数游戏来数,这显然是不必要的,所以当游戏失去焦点时,我们将把Input Manager的active属性设置为false,停止更新输入。

接下来的工作
         

 

 最后要说的是,KeyboardState返回的所有键盘消息,都是Keys枚举的一个值,如果你想编写文本框,允许用户输入,必须把各个枚举值转换为相应的字符。详细的实现也许非常复杂,你要考虑shift按下或者Caps Lock是否开启; 又或者你希望把每个键盘消息映射为游戏内的某个消息,等等。那么也许就需要在input manage之上,再建立一个InputMessageTranslator之类的东西了。

Windows下通过Ollama安装使用DeepSeek本地大模型 本地安装运行Deepseek大模型 阅读详情

相关推荐

DoubletFinder实战:如何优化参数提升scRNA-seq双细胞识别准确率?

本文深入探讨了如何通过优化DoubletFinder参数提升scRNA-seq双细胞识别准确率。详细解析了pK和nExp参数的影响机制,提供了系统化的参数优化流程和多样本整合策略,并结合真实数据集演示了验证方法与高级应用场景,帮助研究人员获得更可靠的分析结果。

weixin_28523493的博客 340

搬家了,新地址http://www.cnblogs.com/clayman/

   终于决定搬家,难用都还可以勉强忍受,可是最近居然开始乱封blog了,怕怕。可惜那么多文章带不走,手动把部份我觉得比较有价值的文章搬过去了。呵呵,欢迎大家有空过去看看:)。 此blog将不再更新...........

Clayman的专栏 18万+

AutoDock Vina 对接计算(大批量)

AutoDock Vina是一种用于计算生物分子之间相互作用的计算工具,主要用于蛋白质和小分子(通常是潜在药物分子)之间的对接研究。它可以用于虚拟筛选、药物设计和生物分子结合位点的预测等多个应用领域。

MurphyStar的博客 1万+

Scene Management --- scene graph

Scene Management -- scene graph仅供个人学习使用,请勿转载,勿用于任何商业用途。              下面是一个简化的游戏引擎数据流,每一帧,scene data作为数据源,输入到物理/碰撞检测和AI子系统,子系统更新所有物体的状态(包括位置,光照信息等等),之后数据流入渲染系统,最终显式在屏幕上。         显然,后面两部分的效率都依

Clayman的专栏 7737

cst使用局部网格加密,手动加密,special设置等方法合理网格布局加速仿真速度

在CST中,计算复杂模型或者阵列的时候往往需要耗费大量仿真时间,除了使用更高性能的电脑或工作站进行仿真,合理对CST的仿真网格进行适当设置也是必不可少的一步。CST中网格设置影响模拟的精度和速度,因此花时间理解网格过程是很重要的。

OVEN_b612的博客 1万+

分享Charles抓包 显示<unknown> 解决方案 !

首先电脑上需要安装charles,然后需要设置手机上的WiFi设置,修改配置中的代理设置,把服务器的主机名设置成你电脑当前的ip地址(需要注意的是,你的代理服务器主机名的ip地址要和你当前连的ip地址的网段需要一致)。像 Charles 这样的工具,虽然功能强大,但仍然需要用户具备一定的配置和排障能力,以应对各种复杂的网络环境。通过将 Charles 的 SSL 证书正确安装到移动设备中,并在设置中启用“允许不安全的内容”选项,最终成功解决了这一问题,并准确抓取到所有请求数据。Charles 显示。

朱雀随云记的博客 8105

一些关于引擎设计,Scene Management的文章

    这几天逛GameDev,几乎把所有和Scene Management相关的文章和帖子都翻遍了,看到各种牛人的讨论,受益匪浅啊,对研究引擎设计非常有用,把部分特别有意思的帖子列出来,希望对你也有帮助:)  (以下顺序不分前后) (update on 4.23.09)The Technology of a 3D Engine  part 1, part 2, part 3S

Clayman的专栏 6802

畅游Diffusion数字人(20):FLAME代码解读与实现

​ 之前的博客《畅游Diffusion数字人(17):更强大的人脸和表情表达方法 FLAME:Learning a model of facial shape and expression》讲解了FLAME的原理,这篇博客主要讲解一下FLAME的代码实现。

沉迷单车的追风少年 1133

InputManager Update Frequency

InputManager Update Frequency  仅供个人学习使用,请勿转载,勿用于任何商业用途。     很高兴上一篇文章引起了很多争论,主要是关于以什么频率更新InputManager。大概是上一篇文章说的不够清楚,所以我想再说的详细一点。    首先,为什么需要IM。Xna只提供了最基本的输入检测方式:只能主动查询某个按键是否被按下,没有事件支持,没有常用的keyJu

Clayman的专栏 4470

微信小程序云开发 - 实现商家转账到零钱(微信企业付款到零钱) V3功能流程及完整实例代码,过微信云开发的云函数实现企业付款到零钱(提供详细示例源码纯云函数实现,证书、密钥、签名等各种常见问题解决方案

企业付款到零钱(微信小程序提现功能,提现到零钱)微信小程序-云函数实现微信企业付款到零钱功能,实现微信商户号中的企业付款到零钱的功能,微信小程序+云开发+商家转账至零钱+微信小程序用户提现,使用云开发环境的云函数实现微信小程序的支付功能,微信小程序实现微信企业付款到零钱功能的流程,V3 V2基于微信云开发的商家转账至零钱,小程序云函数企业付款到零钱功能实现,云开发实现微信商户支付企业付款到零钱功能,不用服务器纯云函数实现,详细示例代码demo教程,API证书错误,转账不到账怎么办,密钥生成有误,转账失败,有

🏆 前端领域优质创作者 1万+

【YOLO系列】YOLOv4详解:模型结构、损失函数、训练方法及代码实现

摘要:YOLOv4在目标检测领域实现了精度与速度的平衡,通过CSPDarknet53骨干网络、SPP+PANet特征融合及CIoU损失函数等创新,在MS COCO数据集达到65.7% AP50,V100显卡实现62FPS实时检测。核心优化包括Mosaic数据增强、自对抗训练和解耦头结构,显著提升小目标检测和遮挡场景鲁棒性。代码实现采用CSP模块和SPP多尺度池化,兼顾计算效率与检测性能,为工业落地提供高效解决方案。(149字)

一碗白开水一 1358

Scene Management --- Collision Detection

Scene Management --- Collision Detection 仅供个人学习使用,请勿转载,勿用于任何商业用途。     没有碰撞检测的引擎是不完整的。碰撞检测是引擎的基础服务之一,需要为渲染,物理仿真,AI和游戏逻辑都等众多子系统提供服务。由于碰撞检测本身设计到大量数学运算,以及各个子系统对碰撞检测需求的不同,使得它成了最难实现的部分。    碰撞检测需要解决的

Clayman的专栏 4011

跨境电商产品信息抓取:使用Python爬虫进行市场分析

跨境电商平台是指为不同国家和地区的买卖双方提供在线交易服务的电子商务平台。亚马逊(Amazon):全球最大的电商平台之一,提供丰富的商品种类和全球配送服务。eBay:全球知名的在线拍卖和购物网站,支持个人和企业卖家。速卖通(AliExpress):阿里巴巴旗下的跨境电商平台,主要面向全球消费者提供中国制造的商品。Wish:以移动端为主的跨境电商平台,主打低价商品和个性化推荐。这些平台上的商品数据包括商品名称、价格、销量、用户评价、库存等信息,对于市场分析具有重要价值。

2201_76125261的博客 1233

The Design of Model (part 1)

The Design of Model (part 1)仅供个人学习使用,请勿转载,勿用于任何商业用途。              过去一段时间都做引擎设计,小有成果,过几天陆续整理出来,今天先发个引子吧. ^_^           第一步当然是定义模型数据,有了模型,才方便做后续开发。通俗一点说,就是要创建model类。也许你会说XNA或者说DirectX已

Clayman的专栏 3931

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Make Your Game Input Robust

Make Your Game Input Robust 仅供个人学习使用,请勿转载,勿用于任何商业用途。    如果你读过 之前 那篇关于InputManager的文章,那么非常抱歉,最近发现那样的设计是有缺陷的。我又一次被隐藏的复杂性打败了-_-#。    问题一,以什么频率进行输入更新。对于XNA framework来说,每次程序主循环调用Update时,都会刷新KeyboardSta

Clayman的专栏 3892

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

More on Scene Management

 More on Scene Management仅供个人学习使用,请勿转载,勿用于任何商业用途。      相信很多人都看过Tom Forsyth那篇著名的文章>。我第一次看时,只觉得是Tom开的一个小玩笑。不过最近,随着对scene management研究的深入,感觉对于大多数游戏来说,scene graph确实不是那么必须。      由于scene graph实在是一个被严重

Clayman的专栏 3774

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Scene Management --- Culling

Scene Management --- Culling仅供个人学习使用,请勿转载,勿用于任何商业用途。     上次说到场景很大,物体很多时,每帧都把所有物体传递给渲染系统是不可能的。考虑到所见区域只是场景中的一小部分,因此,剔除视野之外的物体,就显得尤为重要,也就是常说的裁剪。本质上,裁剪算是碰撞检测的一部分,通过碰撞检测判断物体是否在视锥之内,但他和游戏里一般的碰撞检测还是有很大

Clayman的专栏 3568

The Design of Model (part 2)

The Design of Model (part 2)仅供个人学习使用,请勿转载,勿用于任何商业用途。    继续上次的讨论,所有渲染器支持的对象都必须支持接口Draw,那么Draw应该实现哪些职责呢?由于已经把材质作为单独的对象来管理,所以Draw只需要完成2个任务:设置几何数据,绘图。下面是一个可能的Draw方法实现:Draw(){    graphicsDevice.V

Clayman的专栏 3303

【Unity知识速递】第7期 Unity 6.6 深度解析:WebGPU 正式版与 WebAssembly64,Web 游戏的内存革命

如何启用 Wasm64?需要注意的是,Wasm64 需要浏览器支持 Memory64 提案,目前主流浏览器的最新版本都已支持。一句话总结: Unity 6.6 用 WebGPU 转正、Wasm64 16GB 内存和渐进式加载三连击,将 Web 游戏的体验天花板又往上推了一大截——Web 平台不再是"妥协版",正在成为真正的一等公民。Unity 6.6 新增了 WebAssembly64(Wasm64) 构建选项,这可能是本次更新中对 Web 游戏开发者影响最大的一项升级。

crystal_WJT的博客 433

设计模式(unity游戏研发版)

当你使用图形用户界面类时通常会遇到一个问题。比如,你创建了自定义按钮类并允许客户端在按钮中注入自定义代码,这样当用户按下按钮时就会触发这些代码。观察者模式允许任何实现了订阅者接口的对象订阅发布者对象的事件通知。你可在按钮中添加订阅机制,允许客户端通过自定义订阅类注入自定义代码。在Unity中,这就像UnityEvent在Inspector中绑定多个回调。

m0_63330263的博客 104

Claude Fable 5.2 登顶:65 分、单发做游戏,和一份 $26.54 一单的账单

Anthropic 发布 Claude Fable 5.2:AA 智能指数 65 分登顶历史第一,但性能 #71、成本 #73、冗余度 #72——最强能力、最贵成本、最慢速度的矛盾体。同底层 Mythos 5.2 无护栏反而更强。文章拆解:65 分构成、官方实战验收、基准提升真伪、一条提示词一晚做出街机游戏的完整流水线(自写机器人跑完 12 关自检)、$26.54 账单与 98% 缓存折扣下的真实成本重估。

johnsong2009的博客 258

10分钟完成第一个Python小游戏

第一个项目不用找复杂的,‌直接选「猜数字小游戏」对应的教程‌就好——几乎所有入门教程都会讲这个项目,资料最多、遇到问题随便搜就能找到解决方法,不会卡壳,30分钟肯定能做完,非常容易建立信心。‌教程链接‌:直接搜标题👉 ‌《Python零基础入门项目:30分钟写完猜数字游戏》‌(优先选黑马程序员、鱼C-小甲鱼这两个UP主的版本,播放量都是百万级,口碑稳定)‌教程地址‌:打开菜鸟教程官网→找到「Python 实例」板块,直接在线写代码运行。全程不跳步,30分钟就能做完,做完能直接运行玩,成就感拉满。

mF44Job8l的博客 62

Unity 数据存储指南:本地存储、个性化设置、缓存与 Resources/StreamingAssets 的区别

在 Unity 开发中,“数据存到哪里”、“缓存能不能清”、“打包后资源有什么区别” 是新手最容易混淆、老手也经常踩坑的问题。Unity 本地存储机制(包括 Unity 放在 C 盘的内容);Unity 个性化设置(编辑器首选项 Editor Preferences);Unity 缓存的打开、关闭与清理;打包后 Resources 与 StreamingAssets 的区别;其他可自定义存储的内容汇总。为方便理解,本文配有一个可直接运行的演示工程,所有代码见文末"配套工程说明"。

zhchyun 223

Claude Code做Unity项目移植(三): 使用SKILL进行自动化Git提交

本文介绍基于ClaudeCodeSkill的Unity自动化Git提交助手——unity-git-commit,通过四大模块实现提交前的智能检查与安全修复:1)校验Git仓库状态;2)验证Unity项目文件(如排除Library/Temp,确保.meta文件完整);3)依据可配置的C#命名规范自动识别并安全修复命名问题(避免序列化、反射等高危场景误改);4)生成精准提交注释,但强制人工确认。全程仅本地commit,不自动推送或破坏性操作,保障安全。核心思想为“机械化工作交AI,关键决策留人工”,显著提升提交

Aman1984的博客 647

用 AI 在 Unity 里做一款 RTS:最难的不是生成代码,而是证明它真的能玩

git@github.com:zoucdr/unity-skilled-mcp.git

邹杭特的博客 245

HarmonyOS 游戏与图形渲染入门:Canvas、渲染管线与掉帧排查

本文详解鸿蒙图形渲染选型与优化,指出多数“游戏感”需求仅需Canvas+requestAnimationFrame即可实现。通过deltaTime保证跨设备流畅性,优先使用animateTo声明式动画,避免逐帧绘制开销。强调性能优化应从主线程长任务、过度绘制、对象分配入手,结合Profiler排查掉帧。XComponent适用于高负载场景,但需权衡开发成本。最后提醒引擎迁移三要点:性能模型差异、打包流程匹配、版本兼容。核心结论:先用简单方案验证,再决定是否上引擎。

信息安全领域优质创作者|操作系统领域专家 428
上一篇: Beware of GPU memory bandwidth!!
下一篇: 接下来写什么?
soilwork
博客等级 码龄23年 290粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值