首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在C游戏引擎中实现输入处理?

如何在C游戏引擎中实现输入处理?
EN

Game Development用户
提问于 2013-09-22 13:40:30
回答 1查看 4.1K关注 0票数 3

我开始学习C编程,尽管我有很多使用高级语言的经验。我想用C和OpenGL编写一个游戏引擎。我想我理解图形渲染部分,但现在我很好奇如何接收和处理键盘、鼠标和控制器输入。如何在C中实现这类事情?

EN

回答 1

Game Development用户

发布于 2013-09-23 09:06:28

虽然您当然可以选择跨平台库,但如果您想自己编写输入函数,则需要创建一些通用代码接口规则或C++对象,这些规则或对象将涵盖所有平台,以做到这一点。然后,您将创建特定于平台的实现,只有在为该平台构建库时才进行编译。

至少那块我能帮上忙。下面的链接展示了如何使用预处理器指令来检测Windows,并且在大多数情况下它应该可以工作,尽管32位版本可能有一些警告。您仍然需要找到特定于平台的API来管理每个目标平台的输入收集,也许还需要管理编译器/ IDE的项目设置,以创建多个构建目标,每个目标环境都是不同的。总之,这是一个复杂的方法.

https://stackoverflow.com/questions/3213037/determine-if-linux-or-windows-in-c

如果你想使用过剩,这里有一个教程,可以让你走上正确的道路。我不认为这包括创建Windows,但我听说过剩也包括.

http://www.lighthouse3d.com/tutorials/glut-tutorial/keyboard/

如果你还有其他问题的话,我可以看看能做些什么来回答。

-编辑

由于它的要求,我可以提供一个高层次的想法,如何收集输入,和一些更多的方向,我可以给一些更具体的东西,虽然我从来没有使用过剩个人。

收集输入的方法有两种:轮询和基于事件的方法。轮询是游戏的首选,因为您希望能够在更新循环中一次获得在一个帧中发生的所有输入。然而,在现实中,这一切都发生在基于事件的模型中,即使您深入到操作系统内核中的中断处理程序,与最低层次的电路交互。我不会对这部分发牢骚,因为别人可能更有资格回答这个问题。

在基于事件的模型中,每次按下键时都会触发一些回调函数。这是异步发生的,因此涉及到某种形式的多任务处理,例如线程处理或中断,在较低的级别。在这个模型中,您向输入引擎传递一个函数,这个函数在每次事件发生时都会调用,在本例中,是按下键或鼠标移动。假设它看起来像这样,对于一个虚构的InputObject API.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void gatherInput(InputObject input)
{
 if(input.isKey())
 {
      doKeyPress(input.getKeyCode());
 }
 else if(input.isMouse())
 {
      doMouseMovement(input.getMousePosition());
 }
}

显然,您可能需要更多的功能,例如获得修饰符键,或鼠标按下按钮和位置,但您得到了想法。

不过,对于电子游戏来说,最好的方法是创建一个轮询环境,如果你还没有做到这一点。在这种环境中,轮询机制基本上是一个队列或其他一些结构,我们的虚拟InputObject条目将被记录到其中。然后,我们会同时在输入投票中调用一些方法,这将允许我们将InputObjects排出队列,并对它们进行响应,每次一个。这有一个明显的优点,即自从您上次在游戏循环中运行update之后,所有输入都同时被收集和响应,这样游戏逻辑就不会在与输入收集不同的时间步骤上更新。

输入轮询方法可能如下所示..。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void update(Time time)
{
    while(this.inputQueue.hasNext())
    {
     InputObject i = this.inputQueue.dequeue();

     if(i.isKey())
     {
         doKeyPress(i.getKeyCode());
     }
     else if(i.isMouse())
     {
         doMouseMovement(i.getMousePosition());
     }
     // etc...
    }

    simulate(time);
    animate(time);
    draw(time);
    //etc...
}

对于某些输入库,您可能必须将事件转换为您自己设计的轮询队列。在本例中,事件只是将包含输入的对象排队到某个输入队列中,然后在每次更新时一次得到它们。如前所述,这是首选的方法。

希望,这是明确的泥浆,但如果它是如此稍微清楚,请随时提供要点:)

票数 2
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/62572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文