??xml version="1.0" encoding="utf-8" standalone="yes"?>色婷婷综合久久久中文字幕,久久99国产精一区二区三区,2021精品国产综合久久http://www.shnenglu.com/helloqinglan/category/11786.htmlw披半g长工衣,怀揣一颗地dzh-cnSun, 04 Apr 2010 02:08:57 GMTSun, 04 Apr 2010 02:08:57 GMT60游戏到底有多赚钱http://www.shnenglu.com/helloqinglan/archive/2010/04/04/111554.html白云?/dc:creator>白云?/author>Sat, 03 Apr 2010 17:18:00 GMThttp://www.shnenglu.com/helloqinglan/archive/2010/04/04/111554.htmlhttp://www.shnenglu.com/helloqinglan/comments/111554.htmlhttp://www.shnenglu.com/helloqinglan/archive/2010/04/04/111554.html#Feedback0http://www.shnenglu.com/helloqinglan/comments/commentRss/111554.htmlhttp://www.shnenglu.com/helloqinglan/services/trackbacks/111554.html  游戏有多赚钱Q看一下上市游戏公司的财报q道了?a target="_blank">http://tech.163.com/caibaoQ这里有国内互联|公司胦报汇总,摘录09q第四季度几家公司的游戏业务赢利情况Q见下表Q?/font>

公司 游戏营收(万元) 毛利?万元) 毛利?/td>
盛大 133600 80200 60%
完美 54000 52600 86.60%
畅游 48250 28800 92%
巨h 27300 23200 83.90%

 

  当然Q这是占据了国内游戏行业收入一大半的几家大公司Q不q就是公司,只要能成功让产品上线Q利润率也是一L(fng)?/font>

 

  从上市公司的财报里可以看刎ͼ一般MMORPG的每z跃付费用户q_每月贡献收入大致?0元左叻I有些游戏?x)高很多Q有些稍低一些。也是_只要?万活跃付费用P?5%的利润率来计,扣除q营成本后的月利润就能达?00万?/font>

 

  不过Q目前游戏的cd基本上都是道h费,q样不是每个玩游戏的人都?x)掏钱。按照畅游胦报中披露的信息,非付费用户向付费用户的{化比例ؓ(f)18%Q其他游戏的q个比例应该也不?x)相差太多? * 18%Q月收入100万就需要有11万的z跃用户?/font>

 

  z跃用户的统计方法一般是如果该̎号在一天内累计在线旉过2时Q刚该玩家的z跃天数加1Q如果在U时间在半小时到2时之间Q则z跃天数?.5Q在U时间小于半时的不活跃天数。当Ӟq是每日z跃用户数的l计Ҏ(gu)?/font>

 

  我们?时为单位,只要在每个时间单位内?1 / 12万用户在U,则就辑ֈ?0万活跃用戗也是_q_在线只要不到一万hpC月入100万的目标?/font>

 

  q个数字基本上是可信的。可以再看一看完的财报Q完Q4财报昄Q^均同时在U(ACUQؓ(f)115.7万hQ网游收入ؓ(f)5.4亿元Q^均每月ؓ(f)1.8亿,q样?万^均在UA(ch)献的收入?18000 / 115.7 = 155万,q个数字比前面计的不到一万同时在UA(ch)献收?00万还要高Q这是因为完的ARPU值比畅游高,为每?4元?/font>

 

  所以,每当跟别Zl我是做游戏Ӟ别h都会(x)感叹一下,游戏啊,qQ我也笑W,实是挺赚钱的。可是,如此赚钱的品,开发h员的回报又有多少呢?

 

  再来看一下上市公司的财报。依然是畅游的,“非美国通用?x)计准则产品开发费用ؓ(f)510万美元,环比增长5%Q同比减?2%。环比增长主要是׃聘用了更多的游戏研发人员而导致员工薪酬与利费用的增加。同比减主要是׃公司理层奖金方案的调整——之前授予的股权Ȁ励在IPO后h(hun)值提高,因而公司减其现金奖励?#8221;

  从这句话上可以看出来Q这个研发费用不仅仅只是开发h员的工资Q还包括了由于员工的相关利Q也包含了ؓ(f)员工所~纳的保险,公积金等费用。另外也q包括了奖金Q以及股权奖q{。就q?20万,也只占到了营收的7%?/font>

  在公司管理层解读财报的时候有另外一句话Q?#8220;截止?009q?2?1日,共有520位工E师。地面推q团队中正式员工?0人,另外q有临时雇员大约q有600人?#8221;不知道这510万的研发费用是否包括了上面提到的地面推广人员和(f)旉员,暂时认ؓ(f)其不包含吧,假定q些钱都花在?20位开发h员n上?/font>

  另外也不知道q?10万是否包含研发相差的办公室租金等费用Q这个估计应该包含吧?/font>

  公司为员工缴U的保险Q公U金跟我们交的一P?x)占工资?0%多,办公开支不大好,另外利也不好说Q比如聚,l织出去玩等Q这些不好统计,q不排除有一些无法统计到的灰色内宏V简单一点,qq?10万有50%最后以money的Ş式发C开发h员手上吧Q包括每月固定工资与奖金。这Pq_每h每月?600元?/font>

  因ؓ(f)大部分公司的奖金都是以多发一个或者几个月的工资Ş式来发放的,据说畅游每年相当于能?6个月工资Q?600 * 12 / 16 = 1200元。^?000元的月薪Q可能大部分Z(x)感觉到自己ƈ没有q么多。当Ӟ因ؓ(f)有一部分h有股权的奖励Q他们的收入q超q了8000 * 16Q所?0%的精p得了80%的利?:) 其实也是差不多的?/font>

 

  如此高利润率的游戏品,到头来生产者们的回报却也还是一栗所以,再听Ch说游戏很赚钱Ӟ有必要好好对其解释一?:) 游戏实是赚钱,可钱q不在我们这些h的口袋里?/font>

 

  再来看近期网易的大话二团队集体离职,大明龙权开发团队集体蟩槽完,q有华义成都差不多整个公司蟩到腾讯,金山的团队到|易d发大唐,盛大的英雄年代团队出走征途等{,q不能说是员工不够忠诚,实在是利益分配的不合理。新的老板只要肯多拿出一个甚臛_个百分点Q分到开发h员的手中是沉甸甸的诱惑了?/font>

 

  而且q有另外一条很重要的因素,游戏的成功与否很大程度上来自于那几个开发h员。纵观国内游戏厂商,基本上都是只靠着开发团队做的一ƾ游戏就撑v了整个公司,让公司挤q二Uѝ一U游戏厂商行列,甚至靠着q一ƾ游戏去赚美国股民的钱。当然这U成功也有很大的偶然性?/font>

  像一个正在创业\上的朋友所_游戏是能让你q速从杨白力_成黄世仁的最好选择。当前,前提是你不是在ؓ(f)别h打工?/font>



]]>
FXComposer中的Annotations与Semanticshttp://www.shnenglu.com/helloqinglan/archive/2009/09/28/97415.html白云?/dc:creator>白云?/author>Sun, 27 Sep 2009 16:02:00 GMThttp://www.shnenglu.com/helloqinglan/archive/2009/09/28/97415.htmlhttp://www.shnenglu.com/helloqinglan/comments/97415.htmlhttp://www.shnenglu.com/helloqinglan/archive/2009/09/28/97415.html#Feedback3http://www.shnenglu.com/helloqinglan/comments/commentRss/97415.htmlhttp://www.shnenglu.com/helloqinglan/services/trackbacks/97415.htmlDXSAS : DirectX Standard Annotations and SemanticsQDirectX引入的一在Shader代码与应用程序之间进行数据绑定的规范Q当出到0.8时被q泛用于各种应用E序中,后来从MS的品线中神U消失,有关DXSAS的规范文档被从MSDN中移除,只留下几引用说明。。?/font>

 

单来_当我们在DX中用Shader的时候,我们?x)用一个常量表来设|各U参数|其中最重要的当属世界变换矩阵了。这在用DX写游戏程序时没有问题Q但是在其他一些Shader~辑工具中问题就出来了,如何讄q些变量Q当Ӟ每种工具可以提供自己的方法,比如现在MaxQMaya都提供了自己的方法在Shader中绑定世界变换矩阵,但问题是每种工具提供的方法都不一Pq样写出来的Shader文g麻烦了。。?/font>

 

于是QMSq时站出来,提出了一个标准:(x)DXSAS。这是目前还能找到的DXSAS的一D|qͼ(x)

Standard annotations and semantics (DXSAS) provide a method of using shaders in a standard way that enables shaders to be used with tools, applications, and game engines. DXSAS defines a set of semantics and annotations that are attached to host application values and effect parameters for the purpose of sharing effects.

地址Q?a target="_blank">http://msdn.microsoft.com/en-us/library/bb173004(VS.85).aspx

 

有标准是好事Q而且我们也能看到Q大量的Shader工具及游戏引擎也使用CSASQ比如FXComposerQ比如RenderMonkeyQ比如CryEngine。。。当Ӟ各工具可能对SAS都会(x)有自q扩展Q但大部分还都是按照标准来的?/font>

 

可是Qؓ(f)什么MSH然将q标准移除了。。。而且Q没有Q何理q。。。以至于FXComposer1.8版本以前的文档中附带的SAS描述章节也跟着一q删除,我在FXComposer2.5上找遍了整个手册也没扑ֈq个 WorldViewProjection 从哪里来Q翻遍了MSDN上HLSL有关的内容也没有看到q几个关键字。无奈Google之,原来受此困惑的hq真不少?/font>

 

好在QNvidia推出了一份新的文档,描述SAS的用方法,或许Nvidia也很困惑Q?#8220;which came from DirectX 9, and are sometimes hard to find”。。。但是新的FXComposer手册中对q些只字未提却是我仍然很困惑的,对于像我q样的一个新手来_完全不可能知道这些东西是如何来的Q如何去找这些Semantics的定义?/font>

 

Nvidia|站上的SAS说明文档Q?a target="_blank">http://developer.nvidia.com/object/using_sas.html

 

以及FXComposor官方论坛上置的关于SAS文档的说明脓(chung)Q当时我竟然没看到这个置脓(chung) :(  http://developer.nvidia.com/forums/index.php?showtopic=1358

 

其他人提出的一些相关疑问:(x)

http://developer.nvidia.com/forums/index.php?showtopic=750

http://developer.nvidia.com/forums/index.php?showtopic=31

http://developer.nvidia.com/forums/index.php?showtopic=1061

http://developer.nvidia.com/forums/index.php?showtopic=1347

http://developer.nvidia.com/forums/index.php?showtopic=1394

 

留下q些记录Q也许有跟我一L(fng)初哥们,点困惑 :)



]]>
Structuring the Main Loophttp://www.shnenglu.com/helloqinglan/archive/2009/09/14/Structuring_the_Main_Loop.html白云?/dc:creator>白云?/author>Mon, 14 Sep 2009 12:29:00 GMThttp://www.shnenglu.com/helloqinglan/archive/2009/09/14/Structuring_the_Main_Loop.htmlhttp://www.shnenglu.com/helloqinglan/comments/96154.htmlhttp://www.shnenglu.com/helloqinglan/archive/2009/09/14/Structuring_the_Main_Loop.html#Feedback2http://www.shnenglu.com/helloqinglan/comments/commentRss/96154.htmlhttp://www.shnenglu.com/helloqinglan/services/trackbacks/96154.html    看到CppBlog上翻译的一?a href="http://www.shnenglu.com/Charlib/services/trackbacks/94403.aspx" target="_blank">游戏d@?/a>Q想起之前也看到q一类似的文章Q因为笔记本上第一记录就是这个主循环的简短翻译,Ҏ(gu)了一下,发现q篇文章对实现细节的描述更多一些,也发上来与大家共享?/font>

    q篇文章最早是出现在flipcode的论坛上Q?a target="_blank">地址在这?/a>Q后来有人整理了一下,q添加了更多的描qͼ也就是下面的内容?a target="_blank">原脓(chung)地址在这?/a>?/font>

    文章中关于网l的描述是指局域网环境下的情况Q另外这个主循环也没有考虑到windows环境下与Windows Message Loop的结合,如果是应用在windows环境下,可以?a target="_blank">参考下q里Q把两者结合基本上差不多了?/font>

    译q未严格늅原文Qؓ(f)了读h畅Q很多句子都是按照我个h的理解来描述?/font>

 

This article is about a way of structuring a game's main loop. It includes techniques for handling view drawing with interpolation for smooth animation matched to the frame-rate with fixed-step game logic updating for deterministic game logic. A lot of this is still pretty much a work-in-progress as I muddle my way through, learning better ways of doing things or new tricks to add to my bag, so please bear with me.

q篇文章描述的是如何l织游戏d@环的一U方法。内容包括了如何处理qx的动ȝӞq且能够Ҏ(gu)当前帧率做正的动画插|另外q要保证固定的游戏逻辑更新帧率Q以保游戏逻辑的计结果是定的?/font>

q些内容的实现有很多都还在进行中Q我也在不断地学?fn)更好的?gu)Q以及将一些新的技巧添加进来,所以,希望能够l我一些耐心与宽宏V?/font>

The heart of a game, any game, is the game loop. This is where the action takes place, where the guns fire and the fireball spells fly. In some games, the concept of the game loop may be diffused among different components or game states, which implement their own version of the game loop to be exectued at the proper time, but the idea is still there.

M游戏的核心都是游戏主循环。游戏的动作执行、子弹的击以及火球法的飞行等{都是在q里实现?/font>

在一些游戏中Q你可能?x)找不到一个唯一的游戏主循环Q取而代之的是,你会(x)在一些组件及状态机中找到各个不同版本的d@环?/font>

其实q个原理也是一L(fng)Q只不过是把原来的一个主循环拆分成了多个Q这样可以控制游戏在不同的时间及状态下执行不同的@环过E?/font>

 

The game loop is just that: a loop. It is a repeating sequence of steps or actions which are executed in a timely and (hopefully) efficient manner, parceling out CPU time to all of the myriad tasks the game engine is required to perform: logic, physics, animation, rendering, handling of input. It must be constructed in a deterministic, predictable fashion so as to give expected behavior on a wide array of hardware configurations. Classic failures in this regard include old pre-Pentium DOS-based games that were synchronized to run well on old hardware, but which did not have the controls in place to control the speed on newer hardware, and consequently ran so rapidly that they became unplayable on new hardware. With such a broad diversity of hardware as now exists, there must be tighter controls on the game loop to keep it running at a consistent speed, while still taking advantage of more powerful hardware to render smoother animation at higher framerates.

单来_游戏d@环就是一个@环过E?/font>

在这个不断重复执行的q程中,我们需要把CPU旉按照一定的规则分配C同的d上,q些d包括Q逻辑、物理、动甅R渲染、输入处理等{?/font>

游戏的主循环必须保证是以一U确定的、可预测的方式来执行Q这h能在大量的不同硬仉|环境下都得到我们所期望的相同行为?/font>

以前的DOS游戏曄出现q这L(fng)问题Q它们在旧的g上运行的很好Q但是放到新的硬件上以后失L制了Q游戏的q行速度变的如此之快Q以至于Ҏ(gu)无法ȝ它?/font>

现在市场上存在这么多的硬件种c,所以就必须要紧紧地控制住游戏的d@环,保证他们以一个固定的速度q行Q但同时又能获得q些强大的硬件所带来的好处:(x)以尽可能高的帧率来渲染出更^滑的动画?/font>

 

Older games frequently tied the rendering of the view very closely to the game loop, drawing the view exactly once per logic update and waiting for a signal from the display system indicating a vertical retrace period, when the electron gun in the CRT monitor was resetting after drawing the screen. This synchronized loops to a predictable rate based on the refresh rate of the monitor, but with the advent of customizable refresh settings this leads again to unpredictable loop behavior. Retrace synchronization is still useful, especially to avoid visual artifacts when rendering the view, but is less useful as a means for synchronizing the game logic updating, which may require finer control.

以前的游戏经常将渲染q程与游戏@环紧密地l在一P首先执行一ơ逻辑更新Q然后绘制画面,接着{待昄pȝ触发一个垂直同步信P之后是下一轮@环周期:(x)逻辑更新、渲染、等?#8230;…周而复始?/font>

q种同步的@环方法在昄器的h率可预测的情况下是有效的Q但是当可以自定义刷新率以后Q这U行为又变得不可预测了?/font>

垂直同步仍然是有用的Q尤其是在避免画面的渲染出现撕裂的情况下Q但是用来同步游戏的逻辑更新没多大用了Q这时可能需要更好的控制Ҏ(gu)?/font>

 

The trick, then, is to separate game logic from rendering, and perform them in two separate sub-systems only marginally tied to each other. The game logic updates at it's own pace, and the rendering code draws the screen as fast as it possibly with the most accurate, up-to-date data the logic component can provide.

q种Ҏ(gu)是游戏逻辑更新与屏q渲染过E分dQ将他们攑ֈ两个分离的子pȝ中去处理Q只是在需要的时候才与另一个打交道?/font>

游戏的逻辑更新严格按照计划来执行,但是屏幕渲染则以它所能达到的最大速率来进行?/font>

 

The system I am accustomed to using is based on a Tip of the Day ( http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-MainLoopTimeSteps&forum=totd&id=-1 ) posted to http://www.flipcode.com by Javier Arevalo. It implements a loop wherein the game logic is set to update a fixed number of times per second, while the rendering code is allowed to draw as rapidly as possible, using interpolation to smooth the transition from one visual frame to the next.

q里描述的方法基于Javier Arevalo发表?/font>flipcode Tip of the Day 上的代码来实现?/font>

在这个游戏主循环里,游戏逻辑更新被设|ؓ(f)每秒执行固定ơ数Q但同时渲染代码被允许执行尽可能多次Qƈ且还使用了插值来使得两个渲染帧之间的动画变化可能的qx?/font>

 

Briefly, here is the code. I will then attempt in my own crude fashion to explain the workings, though I suggest you check out the original tip at the above link to read Javier's explanation, as well as the forum posts accompanying it which offer up insights and suggestions on how the performance of the loop may be improved.

闲话说Q下面首先是代码Q然后我?x)简单的按我的方式描qC下代码的工作原理Q同时我你阅M下上面链接地址所l出的内容,其中有Javier的解释,q且论坛上的回脓(chung)也有一些不错的内容Q包括别人的评论和一些关于如何提高效率的?/font>

(注:(x)flipcode论坛早就已经关闭Q上面的链接地址已经失效Qflipcode上只保留有一些优U内容?a >archivesQ?a target="_blank">在这里能扑ֈq篇原文Q其中包括Javier的解?

 

time0 = getTickCount();
do
{
  time1 = getTickCount();
  frameTime = 0;
  int numLoops = 0;

  while ((time1 - time0) > TICK_TIME && numLoops < MAX_LOOPS)
  {
    GameTickRun();
    time0 += TICK_TIME;
    frameTime += TICK_TIME;
    numLoops++;
  }
  IndependentTickRun(frameTime);

  // If playing solo and game logic takes way too long, discard pending time.
  if (!bNetworkGame && (time1 - time0) > TICK_TIME)
    time0 = time1 - TICK_TIME;

  if (canRender)
  {
    // Account for numLoops overflow causing percent > 1.
    float percentWithinTick = Min(1.f, float(time1 - time0)/TICK_TIME);
    GameDrawWithInterpolation(percentWithinTick);
  }
}
while (!bGameDone);
 

Structurally, the loop is very simple. The above snippet of code can encapsulate the entire workings of your game.

从结构上来说Q这个主循环非常单。上面的代码片段基本上能够囊括你的游戏的整个工作q程?/font>

 

First of all, the main loop portion is embodied as the do{} while(!bGameDone); block. This causes the loop to run endlessly, until some game condition indicates that it is finished and it is time to exit the program, at which point the loop ends and the game can be properly shut down. Each time through the loop, we perform game logic updates, input updating and handling, and rendering. Now, for a breakdown of the sections of the loop.

首先Q主循环的执行过E被包在do…while循环块中Q这使得游戏d@环将怸l束地运行,直到游戏明确地被告知需要结束ƈ且退出程序时为止?/font>

在每ơ进入@环的时候,我们?x)执行游戏逻辑的更斎ͼ输入更新与处理,q有渲染。接下来Q把循环分ؓ(f)几个片段来描q?/font>

 

time1 = getTickCount();
frameTime = 0;
int numLoops = 0;

while ((time1 - time0) > TICK_TIME && numLoops < MAX_LOOPS)
{
    GameTickRun();
    time0 += TICK_TIME;
    frameTime += TICK_TIME;
    numLoops++;
}
 

This portion is the game logic update sequence that forces the game logic (physics updates, object motion, animation cycling, etc...) to update a set number of times per second. This rate is controlled by the TICK_TIME constant, which specifies the number of milliseconds the logic update is supposed to represent in real time. It probably won't take that long to perform, in which case the update won't be performed again until enough time has passed. For example, with TICK_TIME=40, each logic represents 40 milliseconds, thus forcing the code to update game objects at a rate of 25 times per second.

q部分代码处理游戏逻辑的更斎ͼq且强制要求游戏逻辑每秒执行固定ơ数?/font>

游戏的逻辑处理包括物理更新、对象行为、动d@环等{。更新速率通过TICK_TIME帔R指定Q其含义Zơ逻辑更新的时间间隔,即经qTICK_TIME后应该再ơ进行更斎ͼ而不是说一ơ逻辑更新要持l这么长旉?/font>

例如QTICK_TIME = 40Q其含义为每ơ游戏逻辑更新后表?0毫秒Q这得每U游戏对象会(x)被更?5ơ?/font>

 

The logic is encapsulated in it's own while loop. It is possible during a given frame that game logic will take too long. If a logic update cycle goes overtime, we can delay rendering for a bit to give ourselves a little extra time to catch up. The while loop will continue to process game logic updates until we are no longer overtime, at which point we can go ahead and continue on with drawing the view. This is good for handling the occasional burp in logic updating, smoothing out the updates and keeping them consistent and deterministic; but in the case that the logic repeatedly goes overtime, it is possible to accumulate more time-debt than the loop can handle. Thus, the MAX_LOOPS constant is in place to dictate a maximum number of times the loop can repeat to try to catch up. It will force the loop to dump out periodically to handle other tasks such as input handling and rendering. A loop that is constantly running at the MAX_LOOPS limit runs like hell and is about as responsive as a tractor with four flat tires, but at least it keeps the loop operating, allowing the user to pass input to terminate the program. Without the MAX_LOOPS failsafe, it would be entirely possible for a slow computer to lock up with no way to exit as it chokes on the loop, trying to catch up but getting further and further behind.

逻辑更新的代码被包在他自qwhile循环中?/font>

可能在某一帧里游戏逻辑的处理时间会(x)非常长,甚至?x)超Ӟq时我们可以E稍暂停一下屏q的渲染Q得游戏逻辑更新能够在这D|间里赶上来?/font>

q个while循环是用来让游戏逻辑l箋更新Q直到我们不再超Ӟ之后我们l箋游戏的主循环q且q行屏幕渲染?/font>q可以很好地处理H发的逻辑更新时Q得我们的更新更加qxQƈ保证逻辑的一致性和可预性?/font>

但是如果游戏逻辑处理持箋地超Ӟ甚至使得我们的主循环无法处理q来Q这时MAX_LOOPS会(x)起到作用Q他游戏控制权从逻辑更新中蟩出来Q去执行如输入处理和屏幕渲染{其他Q务?/font>

MAX_LOOP帔R限制了这里的while循环用来q赶逻辑处理旉时最多能重复的次数?/font>q样当游戏真的出现完全无法处理完逻辑更新的时候,用户也有Z(x)l束E序?/font>

如果没有MAX_LOOP的检,很有可能?x)出C台很慢的?sh)脑试图q上逻辑处理旉Q但是却追远Q而又没有Z(x)退个过E,最后陷在了q个d@环中……

 

IndependentTickRun(frameTime);
 

This section is where input is gathered, events are pumped from the event queue, interface elements such as life bars are updated, and so forth. Javier allows for passing how much time the logic updates took, which can be used for updating on-screen clock or timer displays and the like if necessary. I've never found occasion to use it, but I regularly pass it anyway on the off-chance I'll need it someday. frameTime basically gives the amount of time that was spent in the logic loop performing updates.

q部分代码用来处理用戯入的捕获Q事件会(x)从事仉列中被取出来处理Q界面元素,如血条等Q会(x)在这里被更新Q还有其他类似的处理?/font>

Javier在这里留了一个frameTime参数Q用来指明逻辑更新所q旉。可以用q个值来更新游戏屏幕上的旉或定时器{类g息?/font>

虽然我目前还没有扑ֈZ(x)用它Q但我还是习(fn)惯性地把它带上了,也许某天我会(x)需要?/font>

 

In order for the game loop to run predictably, you should not modify anything in this step that will affect the game logic. This portion of the loop does not run at a predictable rate, so changes made here can throw off the timing. Only things that are not time-critical should be updated here.

Z使游戏@环的q行是可预测的,你不应该在这里修改Q何可能媄响游戏逻辑的东西,因ؓ(f)此部分在游戏d@环中的执行次数是不可预测的,所以在q里只能做一些时间无关的更新?/font>

 

// If playing solo and game logic takes way too long, discard pending time.
if (!bNetworkGame && (time1 - time0) > TICK_TIME) time0 = time1 - TICK_TIME;
 

This is where we can shave off our time debt if MAX_LOOPS causes us to dump out of the logic loop, and get things square again--as long as we are not running in a network game. If it is a single-player game, the occasional error in the timing of the game is not that big of a deal, so sometimes it might be simpler when the game logic overruns it's alloted time to just discard the extra time debt and start fresh. Technically, this makes the game "fall behind" where it should be in real time, but in a single player game this has no real effect. In a network game, however, all computers must be kept in synchronization, so we can't just cavalierly discard the pending time. Instead, it sticks around until the next time we enter the logic update loop, where the loop has to repeat itself that many more times to try to catch up. If the time burp is an isolated instance, this is no big deal, as with one or two cycle overruns the loop can catch up. But, again, if the logic is consistently running overtime, the performance of the game will be poor and will lag farther and farther behind. In a networked game, you might want to check for repeated bad performance and logic loop overruns here, to pinpoint slow computers that may be bogging the game down and possibly kick them from the game.

当由于满了MAX_LOOP条g而蟩出逻辑循环Ӟ可以在这里减掉多加的上TICK_TIME旉Qƈ且只在单机游戏时才这样做?/font>

如果是在单机游戏中,偶尔出现旉上的错误是不?x)有什么大问题的,所以当游戏逻辑执行时后也没有多大关系Q我们简单的把多q旉减掉Q然后重新开始。从技术上来说Q这?x)得游戏有一点点旉上的落后Q但在单机游戏里q不?x)有什么实际的影响?/font>

但是在网l游戏中q样做却不行Q所有连|的?sh)脑都必要保持旉上的同步?/font>

在网l游戏中Q如果某台电(sh)脑落后了Q他应该保持其落后的状态,然后在下一ơ进入逻辑更新循环Ӟ自己让自己多重复几次Q以便追赶上来?/font>

如果旉延迟只是个孤立事Ӟq将不会(x)有多大问题,l过一两次速就?x)追赶上来,但是如果游戏逻辑更新L时Q游戏的表现会(x)非常p糕Qƈ且最l将?x)越来越滞后?/font>

在网l游戏中Q你可能需要检查出q些持箋时Q表现L很差的电(sh)脑,q将q些可能拖慢整个游戏环境的电(sh)脑踢出去?/font>

 

// Account for numLoops overflow causing percent > 1.
float percentWithinTick = Min(1.f, float(time1 - time0)/TICK_TIME);
GameDrawWithInterpolation(percentWithinTick);
 

This is where the real magic happens, in my opinion. This section performs the rendering of the view. In the case of a loop where TICK_TIME=40, the logic is updating at 25 FPS. However, most video cards today are capable of far greater framerates, so it makes no sense to cripple the visual framerate by locking it to 25 FPS. Instead, we can structure our code so that we can smoothly interpolate from one logic state to the next. percentWithinTick is calculated as a floating point value in the range of [0,1], representing how far conceptually we are into the next game logic tick.

在这里我们将q行屏幕l制?/font>

当TICK_TIME = 40Ӟ逻辑更新帧率?5FPSQ但是现在大多数昑֍都能支持更高的渲染率,所以我们没必要反而锁定渲染率ؓ(f)25FPS?/font>

我们可以l织我们的代码,让我们能够^滑的从一个逻辑状态到下一个状态做插倹{?/font>percentWithinTickZ??之间的QҎ(gu)Q表C我们应该向下一个逻辑帧走多远?/font>

 

Every object in the game has certain state regarding LastTick and NextTick. Each object that can move will have a LastPosition and a NextPosition. When the logic section updates the object, then the objects LastPosition is set to it's currentNextPostion and a new NextPosition is calculated based on how far it can move in one logic frame. Then, when the rendering portion executes, percentWithinTick is used to interpolate between these Last and Next positions:

每个可移动的对象都有LastPosition和NextPosition。逻辑更新部分的代码在执行时会(x)对象的LastPosition讄为当前的NextPositionQ再Ҏ(gu)它每一帧所能移动的距离来计出NextPosition?/font>

然后Q在渲染对象的时候,可以再用percentWithTick来在Last和Next位置之间q行插倹{?/font>

译注Q?/font>

time0为最后一个逻辑帧所在的旉点,time1为当前实际时_(time1 – time0) / TICK_TIME表示当前旉比最后一个逻辑帧所在时间超Z多少癑ֈ比,用这个百分比来向下一逻辑帧做插倹{?/font>

如果机器比较快,在两个逻辑更新旉点之间执行了多次屏幕渲染Q这h值就有效了。此时time0不变Qtime1一直在增长Q可以根据增长的癑ֈ比来计算动画应该从最后一ơ执行逻辑更新的位|向下一ơ逻辑更新所在的位置走多q?/font>

也就是上文所说的Q在Last和Next位置之间q行插倹{插值后的实际位|,即DrawPosition的计方法如下:(x)

动画播放的插g是类伹{?/font>

 

DrawPosition = LastPosition + percentWithinTick * (NextPosition - LastPosition);
 

The main loop executes over and over as fast as the computer is able to run it, and for a lot of the time we will not be performing logic updates. During these loop cycles when no logic is performed, we can still draw, and as the loop progresses closer to the time of our next logic update, percentWithinTick will increase toward 1. The closer percentWithinTick gets to 1, the closer the a ctual DrawPosition of the object will get to NextPosition. The effect is that the object smoothly moves from Last to Next on the screen, the animation as smooth as the hardware framerate will allow. Without this smooth interpolation, the object would move in a jerk from LastPosition to NextPosition, each time the logic updates at 25FPS. So a lot of drawing cycles would be wasted repeatedly drawing the same exact image over and over, and the animation would be locked to a 25FPS rate that would look bad.

游戏的主循环以电(sh)脑所能够辑ֈ的最大速度不停地运行,在大多数旉里,我们不需要执行逻辑更新?/font>

但是在这些不执行逻辑更新的周期里Q我们仍然可以执行屏q渲染。当循环的进E越接近我们的下一ơ逻辑更新旉QpercentWithinTick接q?QpercentWithinTick接q?QDrawPosition的位|就接qNextPosition?/font>

最后的效果是游戏对象在屏q上慢慢的、^滑地从Last位置Ud到Next位置Q动作将以硬件率所能允许的E度可能的qx?/font>

如果没有q个qx插DE,对象位置会(x)从上一帧所在的LastPosition直接跛_下一帧所在的位置NextPosition。大量的渲染周期都被费在把对象反复渲染到相同的位置上,q且动画也只能被锁定?5FPSQ得看h效果非常差?/font>

 

With this technique, logic and drawing are separated. It is possible to perform updates as infrequently as 14 or 15 times per second, far below the threshold necessary for smooth, decent looking visual framerate, yet still maintain the smooth framerate due to interpolation. Low logic update rates such as this are common in games such as real-time strategy games, where logic can eat up a lot of time in pathfinding and AI calculations that would choke a higher rate. Yet, the game will still animate smoothly from logic state to logic state, without the annoying visual hitches of a 15FPS visual framerate. Pretty danged nifty, I must say.

使用了这Ҏ(gu)术之后,逻辑更新与屏q渲染被分离开了?/font>

q将允许我们把逻辑更新帧率降低?4?5FPSQ这q远低于qx的动L染所需要的帧率Q但是在使用动画插g后却仍然能维持^滑的渲染帧率?/font>

在实时策略类游戏中可能会(x)使用q样低的逻辑更新帧率Q这里逻辑更新?x)因寻\和AI计算而占用大量的旉Q在q种情况下用高的逻辑更新帧率昄不行?/font>

但是Q游戏却仍然能够在不同的逻辑状态之间做qx的动画过渡,不会(x)因ؓ(f)只有15FPS的渲染率而出现那些o人生厌的动画跌现象?/font>

非常的漂亮,我不得不说?/font>

 

I've created a simple program in C to demonstrate this loop structure. It requires SDL ( http://www.libsdl.org ) and OpenGL. It's a basic bouncy ball program. The controls are simple: Press q to exit the program or press SPACE to toggle interpolation on and off. With interpolation on, the loop executes exactly as described to smooth out the movement from one logic update to the next. With interpolation off, the interpolation factor percentWithinTick is always set to 1 to simulate drawing without interpolation, in essence locking the visual framerate to the 25FPS of the logic update section. In both cases, the ball moves at exactly the same speed (16 units per update, 25 updates per second), but with interpolation the motion is much smoother and easier on the eyes. Compile and link with SDL and OpenGL to see it in action: http://legion.gibbering.net/golem/files/interp_demo.c



]]>
˳ɵӰվþ| þAV뾫Ʒɫҹ鶹| ޾ƷþëƬ| þþѹ۳ӰԺ| þۺɫݺ| þþþþþþþ| þۺϳDž| Ļþҹ| þѾƷһ| ľƷ99þù | 99þù¶Ʒ| AVݺɫۺϾþ| 9999Ʒŷþþþþ| þù޾ƷӰԺ| þþۺϾɫۺϾ| ޹ŷۺ997þ| þùҹƵ| Ʒþþþþ| Ʒþþþþ| ݺɫþþۺ| 91þþƷһ| Ҫþðѹۿ| þݺҹҹ96׽ | Ů˸߳þþýˮ| 99þ99þ| þþƷ| ?VþþƷ | ھƷžžþþƷ| 뾫Ʒþþþ| þþþþƵ| ˾þ777777| Ʒþþþþҹ| ƷþþĻ| þþþ?V| 99þۺϺݺۺϾþֹ| þþƷAVþþ| þݺҹҹ2020| þ޹Ʒ| þþƷƷƾ | þþƷëƬѹۿ| ھƷþ|