第二章 第五节 统一输入接口

电脑硬件:电脑主板上的接口介绍,看完你就懂了 它们主要用于连接老式的键盘和鼠标,虽然速度和兼容性不如USB接口,但在某些特定场合依然发挥着重要作用。PCIe接口是主板上的扩展能力象征,可以连接各种扩展卡,如显卡、声卡、网卡等。电脑主板作为电脑硬件组成关键的部分,今天给大家分享一下电脑主板上有哪些接口,具体每一个接口的特点、使用场景,有需要的朋友可以来了解一下!它们不仅能连接鼠标、键盘、U盘、打印机,还能连接各种外设,如移动硬盘、游戏手柄等。:虽然现在用得越来越少,但在一些特定场合,如工业控制、老旧设备上,仍然需要使用PS/2接口。 阅读详情

统一输入接口

目前我们已经会怎样和输入硬件通信的基本方法(Now that we have the basics down on how to communicate with the input hardware),是时候把这些信息整合进游戏引擎了。游戏引擎只有一个类,封装了三种输入设备,并为游戏提供了一个统一的接口。这个类,我们把它叫做GameInput,从IDisposable接口继承而来。此接口定义了一个Dispose方法,提供清除函数,在C++里一般是析构函数。此类的构造函数会创建所有的输入设备,并只接受一个参数,即前面提到过的应用程序的窗口句柄。

 

虽然我们可以强加让游戏在游戏循环里查询GameInput来取得击键,但是有更好的方式:我们可以使用action映射。Action映射把一个键盘的键或者鼠标的按钮与一个指定的函数相关联。在每帧里有键或者按钮被按下(或者按下的状态被改变)则调用特定的函数。这让输入系统基于事件而不是基于查询,这会提供效率。DirectInput有内建的action映射功能。我们这个游戏引擎实现了分离的action映射系统,目的是示范action映射究竟是如何工作的。一旦你理解了其中的思想,只要你喜欢你可以直接使用微软内置的版本。

 

Action映射里的每一个实体包含mapping结构或者axis mapping结构的实例,如列表2-2所示:

列表:Mapping结构

struct Mapping

{

   public int key;

   public ButtonAction action;

   public bool bOnTransition;

}

struct AxisMapping

{

   public int key;

   public AxisAction action;

}

结构中的key是索引,是键盘状态数据或者鼠标按钮数据,指示了控制action映射到什么上。开头的256个值表示键盘实体,接下来的8个是表示鼠标按钮,最后的32个是表示操纵杆按钮。ButtonAction委托(delegate)表示一个不需要参数也没有返回值的函数。此函数通常用来在游戏中执行一些动作,例如移动主角,开火或者游戏开发者想做的其他动作。AxisAction委托(delegate)使用这个数据为此轴每一帧都被调用。两个委托的定义如下:

public delegate void ButtonAction();

public delegate void AxisAction(int nCount);

类GameInput的公开方法如列表2-3所示。我将在随后的几页里为这些方法提供简短的说明。如果你对实现的细节有兴趣,请参考GameInput.cs 源文件(源代码的一部分,可以从Apress Web网站下载 http://www.apress.com)

列表2.3:GameInput方法列表

GameInput(System.Windows.Forms.Form form)

void Poll()

bool IsMouseButtonDown( int nButton )

bool IsKeyPressed()

bool IsKeyPressed(Key key)

void MapKeyboardAction( Key key, ButtonAction proc, bool bTransition )

void MapMouseButtonAction( int nButton, ButtonAction proc, bool bTransition )

void MapJoystickButtonAction( int nButton, ButtonAction proc, bool bTransition )

void MapMouseAxisAction( int nAxis, AxisAction proc )

void MapJoystickAxisAction( int nAxis, AxisAction proc )

void UnMapKeyboardAction( Key key )

void UnMapMouseButtonAction( int nButton )

void UnMapJoystickButtonAction( int nButton )

void UnMapMouseAxisAction( int nAxis )

void UnMapJoystickAxisAction( int nAxis )

void ClearActionMaps()

Point GetMousePoint()

int GetMouseX()

int GetMouseY()

int GetMouseZ()

int GetJoystickX( )

int GetJoystickY( )

int GetJoystickNormalX( )

int GetJoystickNormalY( )

int GetJoystickZ( )

bool GetJoystickButton( int nIndex )

int GetJoystickSlider( int nIndex )

void Dispose()

 

Poll方法被游戏应用每一帧调用一次。此方法测试每一个硬件设备来取得输入,然后它检查action映射里的每个实体,看是否有被映射的函数需要被调用。如果是,则调用函数来响应玩家的动作。对于一个特殊的轴action的情况呢,函数则使用轴的当前值调用自己(In the case of the actions for a particular axis, the functions are called every time with the current value for that axis)。列表2-4中的这段代码位于Poll方法中,用来处理action映射。

列表2.4:action映射处理

foreach ( AxisMapping map in m_AxisActionMap )

{

   switch ( map.key )

   {

      case 0:

         map.action(m_mousedata.X);

         break;

      case 1:

         map.action(m_mousedata.Y);

         break;

      case 2:

         map.action(m_mousedata.Z) ;

         break;

      case 3:

         map.action(m_joystick.X);

         break;

      case 4:

         map.action(m_joystick.X);

         break;

      case 5:

         map.action(m_joystick.X);

         break;

   }

}

// Only process the action map if the console is not visible.

if ( !Game Engine.Console.IsVisible )

{

   foreach ( Mapping map in m_ActionMap )

   {

      // If this mapping is against the keyboard

      if ( map.key < 256 )

      {

          // take the action if the key is down or transitioning.

         if ( m_keydata[(Key)map.key] )

        {

            if ( !map.bOnTransition | | oldkeydata[(Key)map.key] )

            {

               map.action();

            }

        }

      }

      else if ( map. key < 264 ) // Space for 8 mouse buttons

      {

         if ( (m_mousedata.GetMouseButtons()[map.key-256] & 0×80) != 0 )

         {

            if ( !map.bOnTransition | |

               (oldmousedata. GetMouseButtons() [map.key-256] & 0×80) == 0 )

            {

               map.action();

            }

         }

      }

      else // joystick buttons

      {

         if ( (m_joystick.GetButtons()[map.key-264] & 0×80) != 0 )

         {

            if ( !map.bOnTransition | |

               (oldjoystickdata.Buttons[map.key-264] & 0×80) == 0 )

            {

               map.action();

            }

         }

      }

   }

}

 

这些Is和Get方法提供了访问输入数据的低层方式。如果因为某种原因,游戏需要显式的检查一个输入而不是使用映射的动作,这些方法就可以被使用。

 

QT自制TCP服务器 TCP服务器 网络调试助手 阅读详情

相关推荐

基于MicroPython的ESP32与微信小程序MQTT通信实战

本文详细介绍了基于MicroPython的ESP32与微信小程序通过MQTT协议实现远程控制的完整实战方案。项目利用巴法云作为免费MQTT服务器,提供了从设备端编程、小程序开发到通信调试的全流程指南,帮助开发者快速构建低成本、易上手的物联网应用,如智能开关、传感器监控等。

week9的博客 633

教训:时间一定要用统一输入接口

        程序web端部署在web服务器,数据库部署在数据库服务器;当发起一个添加请求时,用的是数据库服务器当前时间添加,而在用户立刻对这个添加后的进行操作,采用的是web端当前时间,这样导致一个问题就是:用户操作的时间有可能就比添加的时间要早。因为数据库服务器时间和web端服务器时间存在一定的偏差。        教训:使用当前时间要么都用web端时间,要么就都用数据库端时间!!!

赤道与北极 819

FPGA调试利器:VIO与ILA在Vivado中的实战应用指南

本文详细介绍了Vivado中FPGA调试工具VIO与ILA的实战应用技巧。VIO作为虚拟输入/输出工具,可实时调整参数;ILA作为集成逻辑分析仪,能高效捕获内部信号。文章通过具体案例展示了如何配置ILA采样深度、触发条件,以及VIO的动态参数调整功能,帮助开发者提升上板调试效率,解决常见通信失败、数据不同步等问题。

weixin_42553471的博客 424

《人性的弱点》第二章 获取喜爱的十二大技巧:读后感

永远避免正面的冲突,那才是对的。 一个真正成功的推销员,他决不会跟顾客争辩,即使轻微的争辩,也加以避免。人类的思想,不是那么容易改变的 当我们有错误的时候,或许我们会对自己承认。如果对方能给我们承认的机会,我们会非常地感激,不用对方说,极自然地我们就承认了。如果有人硬把不合胃口的事实,往我们的喉咙塞下去,我们是无法接受下来的。 我很细心地查看,发现我们并没有错误。我知道这是他和他的朋友们,

zhudaPengzz的博客 7887

DDR内存设计必看:DFI接口协议详解与实战避坑指南(附时序图解析)

本文深入解析了DDR内存设计中连接内存控制器与物理层的DFI接口协议,聚焦于DDR4/DDR5设计的实际痛点。文章详细阐述了协议版本兼容性、时钟架构(匹配频率与频率比系统)、PCB信号完整性设计以及上电初始化与调试等关键环节,为硬件工程师提供了一套从理论到实战的完整避坑指南,并附有时序图解析以助理解。

weixin_29256771的博客 329

保姆级教程:用GPU-Burn给你的NVIDIA Tesla服务器做个“压力体检”(附温度功耗监控脚本)

本文提供了一份详细的GPU服务器压力测试指南,重点介绍如何使用GPU-Burn工具对NVIDIA Tesla服务器进行全面的性能测试和温度功耗监控。从环境部署、多GPU测试策略到专业级监控指标解析,帮助运维人员构建标准化的GPU健康评估体系,确保AI训练和科学计算等关键业务的稳定性。

weixin_30619101的博客 395

《人性的弱点》第二章:故事总结

司华伯管理下的一家工厂,那位负责的厂长,无法使他管理的工人达到标准化的生产量。 司华伯问那个厂长:这到底是怎么回事?像你这样一个能干的人,竟不能使那些工人达到工厂预计的生产量? 厂长回答说:我也弄不清楚是怎么回事。我用温和的话鼓励他们,有时不得已去斥责他们,甚至用降职、撤职来恐吓他们,可是那些工人就是不肯辛勤工作。 他们谈话的时候,是日班快结束,夜班要开始之时。 司华伯向那厂长说:你给我一

zhudaPengzz的博客 5979

Qt+PCL实战:如何用QVTKOpenGLNativeWidget高效渲染3D点云(附完整代码)

本文深入解析了Qt与PCL结合使用QVTKOpenGLNativeWidget进行高效3D点云渲染的实战技术。通过对比传统QVTKWidget,详细介绍了QVTKOpenGLNativeWidget在渲染效率、内存占用和兼容性方面的显著优势,并提供了完整的代码示例和性能优化策略,助力开发者在工业检测、自动驾驶等领域实现更高效的点云可视化。

keras9composer的博客 686

什么是静态路由,Windows,Linux服务器如何配置静态路由实现连通多网段(附案例)

默认路由的作用:默认路由的作用是在路由表中没有匹配的路由条目时,确保数据包能够被转发到某个已知的路由器。静态路由(Static Routing)‌是一种由网络管理员手工配置的路由信息,这些路由信息在缺省情况下是私有的,不会传递给其他的路由器。‌默认路由(Default route)‌是指当路由器在路由表中找不到到达目的网络的路由时所选择的路由。1、服务器需要连接两个网段,但是只能配置一个网关(如配置两个网关,则最后配置的网关会生效,前一个则失效),需要配置静态路由实现网络互通。是目标网络的IP地址,

qq_40680147的博客 2841

【OpenClaw从入门到精通】第19篇:OpenClaw电商实战:从零搭建比价+库存监控+自动调价全自动化系统(2026实测附完整代码)

2026年OpenClaw成为全球最火开源项目,电商行业因其场景高频、数据标准化成为其核心落地领域。本文针对电商从业者面临的比价繁琐、库存混乱、调价滞后三大痛点,基于OpenClaw的“接入层-执行层-决策层”三层架构,从零拆解智能比价、多平台库存监控、动态自动调价三大核心场景的实现逻辑。文中包含完整的环境配置、技能安装、代码实现(含Python脚本与YAML配置)、执行结果验证,同时补充关键算法原理与避坑指南,兼顾新手入门与进阶提升。读者可直接参考本文实操流程,快速搭建属于自己的电商自动化系统,实现7×2

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 2237

ZYNQ PS裸机开发RS485

RS485 是一种通用的通信标准,广泛用于数据采集和控制应用中。它的主要优点之一是它允许将多个 RS485 设备放在同一条总线上,这使得多个节点可以相互连接。RS-485是美国电子工业协会(EIA)在1983年批准了一个新的平衡传输标准(balanced transmission standard),EIA一开始将RS(Recommended Standard)做为标准的前缀,不过后来为了便于识别标准的来源,已将RS改为EIA/TIA。

baidu_34971492的博客 830

linux静态转windows,linux、windows路由配置(静态)

路由配置(静态)1、windows下的配置a、在本地连接中配置ip地址及子网掩码,勿配置网关;b、运行cmd,输入 route print 命令,查看本机的路由情况;c、配置动态路由,输入 route add -p 192.168.0.0 mask 255.255.0.0 192.168.30.129 metric 256 回车d、ping 卫生厅提供的ip 192.168.30.97 ,如果可以...

weixin_42297727的博客 167

claude code desktop中出现Doesn‘t look like an Anthropic model - expected a gateway model route 解决方案

本文主要介绍了claude code desktop中出现Doesn’t look like an Anthropic model - expected a gateway model route referencing an Anthropic model和Server is busy. Retrying的解决方案,希望能对使用claude code desktop的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 9万+

linux、windows路由配置(静态)

  路由配置(静态) 1、windows下的配置a、在本地连接中配置ip地址及子网掩码,勿配置网关;b、运行cmd,输入 route print 命令,查看本机的路由情况;c、配置动态路由,输入 route add -p 192.168.0.0 mask 255.255.0.0 192.168.30.129 metric 256 回车d、ping 卫生厅提供的ip 192.168.30.97...

iteye_4979的博客 182

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

linux和windows配置IPV4/IPV6地址、静态路由、查看路由、ping命令

linux配置IPV4/IPV6地址、静态路由、查看路由命令以及ipv4和ipv6 ping命令

LJ511100的博客 8796

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

校园网双网卡路由冲突解决:Windows与Linux静态路由配置指南

在多网卡环境中,操作系统通过路由表决定数据包从哪块网卡发出,默认路由的单一性常导致校园网与公网访问冲突。静态路由通过为特定网段指定网关和接口,实现流量分流,是解决双网卡路由冲突的核心技术。在校园网场景下,合理配置静态路由可让校内资源走校园网、公网流量走宽带,兼顾访问速度与资源可达性。Windows下使用route add -p添加永久路由,Linux下通过netplan或NetworkManager实现持久化配置,配合跃点数调整和验证清单,可有效避免路由冲突和重启丢失问题。

weixin_30225755的博客 247

VB摄像头监控

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

静态路由配置与排障详解:从eNSP实验到Windows/Linux实战

在计算机网络中,路由表决定了数据包的转发路径,而静态路由作为最基础的路由方式,依靠管理员手动指定下一跳和出接口,具有稳定、可控、不依赖协议交互的特点。与OSPF等动态路由协议相比,静态路由无需计算开销,适合网络规模稳定、拓扑结构清晰的场景,如企业出口、多网段互联以及服务器多网卡环境。掌握静态路由的核心在于理解路由逐跳转发与回程路由的对称性,同时熟悉命令行下的配置与验证方法。本文从网络工程师的视角出发,结合eNSP模拟器实验,展示路由器之间的静态路由配置流程,并延伸至Windows系统下的route add命

weixin_29290379的博客 65

静态路由从ensp到Linux/Windows:配置、排错与实验全解析

路由转发是网络通信的基石,路由器依据路由表决定每个数据包的去向。静态路由作为最朴素的人工指路方式,通过目标网段、掩码与下一跳的定义,让设备在无动态协议时也能准确送达数据。其配置简单、可控性强,广泛用于小型组网、分支互联与默认出口场景。然而实际工程中,ensp模拟器里的回程路由缺失、Linux下ip route add报错RTNETLINK answers: File exists、Windows上route命令持久化失败等问题常常困扰学习者。理解路由表核心字段与转发方向,才能灵活应对多系统环境。本文以综合实

weixin_31766003的博客 330

静态路由从原理到实战:华为、Linux与Windows配置排错全解析

路由设置是网络互联的基础,静态路由作为最基础的路由方式,决定了数据包如何跨网段转发。理解路由表、下一跳与回程路由的关系,是网络工程师和运维人员的核心基本功。在华为设备中,通过路由表的flags字段可快速识别静态路由与直连路由,而路由优先级则控制着路径选择的逻辑。在Linux系统中,添加静态路由时需要处理RTNETLINK answers: File exists的冲突报错,掌握ip route add、replace等命令可有效规避。Windows环境下,使用route add配合-p参数可实现持久化静态路

weixin_29597551的博客 290

静态路由综合实验:从ensp到Linux/Windows的配置与排错

静态路由是网络工程师必须掌握的基础技术之一,它通过手动指定目的网段与下一跳,让数据包按预期路径转发。在实际组网中,路由方向性、逐跳转发以及回程路由的设计,往往比命令本身更考验工程思维。掌握静态路由的配置与排错,不仅适用于华为ensp模拟器,也同样适用于Linux和Windows等主机环境。当在Linux系统中执行ip route add时,常会遇到“RTNETLINK answers: File exists”的报错,这背后是内核路由表的冲突保护机制;而Windows下route add忘加-p参数则会导致

weixin_31423955的博客 311

静态路由配置全解析:华为、Linux、Windows实战与排障

静态路由是网络基础架构中不可或缺的转发机制,它通过人工指定的下一跳地址,让设备在非直连网段间建立通信通路。理解路由表的结构与最长匹配原则,是掌握静态路由原理的关键。在实际工程中,静态路由具备不占用带宽、行为可控等优势,适合小型网络、分支互联及备份链路等场景。本文从华为设备、Linux系统到Windows平台,系统梳理了静态路由配置的具体命令与常见故障排查方法,帮助网络工程师快速构建清晰的排障思路。

weixin_29227425的博客 133

静态路由配置实战:华为Linux Windows跨网段互通与排障

静态路由是网络运维中最基础的技能之一,它通过手动指定目标网段与下一跳,在路由表中建立精确的转发路径,无需动态协议交互,天然具备稳定、可控、省资源的优势。理解路由表的最长匹配原则、路由优先级以及直连路由与静态路由的差异,是掌握网络通信的核心。静态路由广泛应用于小型网络、多网段互联、双网卡选路等场景,同时也常因回程路由缺失、防火墙拦截或Linux下ip route add报“File exists”等问题引发排障需求。本文从网络拓扑规划出发,完整演示华为设备ip route-static命令、Linux的ip

weixin_31364787的博客 323

linux系统rc路由配置_windows系统配置静态路由

同网段内有234和254两个网关,计划访问10.0.1.0网段走网关234,其它网段走默认路由254,实现基于用户终端的手动分流。操作需要以管理员身份使用route命令实现。如无说明,掩码都是/24。操作方法:1,开始,输入cmd,右击cmd.exe,选择以管理员身份运行。2,配置静态路由,命令格式如下route add目标网段mask点分十进制掩码 下一跳route add 10...

weixin_42303112的博客 168

linux添加路由的方式,linux和windows路由条目添加方法。

在windows添加一条静态路由1、添加一条路由表route add 60.232.142.25 mask 255.255.255.248 192.168.100.250 metric 3 if 2添加一条路由记录,所有到60.232.142.25/29网段的数据包,都通过2号网络接口卡走192.168.100.250的网关,优先级为3。route add –p 60.232.142.25 mas...

weixin_34540432的博客 758

linux添加静态路由(附windows添加静态路由)

添加静态路由:

weixin_44850446的博客 2468

linux和windows手动添加路由条目命令

如何 在windows添加一条静态路由1、添加一条路由表Route add 60.232.142.40 mask 255.255.255.248 192.168.100.250 metric 3 if 2添加一条路由记录,所有到60.232.142.40/29网段的数据包,都通过2号接口卡(网卡)走192.168.100.250的网关,优先级为3。(结果会怎样?)Route add –p 60.2...

weixin_34293246的博客 1992
上一篇: 第二章 第四节 获得操纵杆的输入
下一篇: 第二章 第六节 绘制Splash Screens
刮风
博客等级 码龄19年 30粉丝 5原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值