我正在使用 Visual C++ 2008 Express 和 Ogre3D SDK 编写游戏。
我的核心游戏逻辑旨在以每秒 100 次的速度运行。为简单起见,我会说这是一个名为“gamelogic()”的方法。它不是基于时间的,这意味着如果我想将游戏时间“提前”1 秒,我必须调用“gamelogic()”100 次。与游戏的屏幕渲染相比,“gamelogic()”是轻量级的。
Ogre 有一个“监听器”逻辑,可以在即将绘制框架和完成绘制框架时通知您的代码。如果我只是在帧渲染之前调用“gamelogic()”,那么游戏玩法将受到屏幕渲染速度的极大影响,屏幕渲染速度可能从 5fps 到 120fps 不等。
想到的简单解决方案是:计算自上次渲染帧以来耗时,并在下一帧之前多次调用“gamelogic()”:100 * timeElapsedInSeconds
但是,我认为“正确”的方法是使用多线程;有一个单独的线程以每秒 100 次的速度运行“gamelogic()”。
问题是,我如何实现这一点以及当两个独立线程之间存在冲突时可以做什么:游戏逻辑更改屏幕内容(3d 对象坐标),同时 Ogre 正在渲染屏幕。
非常感谢。
最佳答案
如果这是您的第一个游戏应用程序,使用多线程来实现您的结果可能比您在第一个游戏中真正应该处理的工作要多。在不同线程中同步游戏循环和渲染循环并不是一个容易解决的问题。
正如您正确指出的那样,渲染时间会极大地影响游戏的“速度”。我建议您不要让您的游戏逻辑依赖于设定的时间片(即 1/100 秒)。使其依赖于当前帧时间(嗯,最后一个帧时间,因为您不知道当前帧需要多长时间才能渲染)。
通常我会写如下内容(我写的是大大简化的):
float Frametime = 1.0f / 30.0f;
while(1) {
game_loop(Frametime); // maniuplate objects, etc.
render_loop(); // render the frame
calculate_new_frametime();
}
其中 Frametime 是当前帧所用的计算帧时间。当您处理游戏循环时,您使用的是前一帧的帧时间(因此将初始值设置为合理的值,例如 1/30 或 1/15 秒)。在前一个帧时间运行它足以让您获得所需的结果。使用该时间范围运行您的游戏循环,然后渲染您的东西。您可能需要更改游戏循环中的逻辑以不假定固定的时间间隔,但通常这些类型的修复非常简单。
异步游戏/渲染循环可能是您最终需要的东西,但这是一个很难解决的问题。它涉及获取对象及其相关数据的快照,将这些快照放入缓冲区,然后将缓冲区传递给渲染引擎。该内存缓冲区必须在关键部分周围正确分区,以避免在渲染循环从中读取时游戏循环写入它。您必须注意确保在传递给渲染循环之前将所有相关数据复制到缓冲区中。此外,您必须编写逻辑来停止游戏或渲染循环,同时等待一个或另一个完成。
这种复杂性是我建议首先以更串行的方式编写它的原因(除非您有经验,而您可能有)。原因是,首先以“简单”的方式进行操作会迫使您了解代码的工作原理、渲染引擎的工作原理、渲染引擎需要什么样的数据等等。在复杂的游戏开发中肯定需要多线程知识这些天,但要知道如何做好它需要深入了解游戏系统如何相互交互。
关于c++ - 游戏逻辑的异步屏幕更新,C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/920829/
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.