2009年11月2日 星期一

九型人格

今天测了我属于九型人格中的哪一个


第五型:智慧型,思想型(Thinker/Observer)观察者
  *【欲望特质】:追求知识
  〖基本困思〗:我若没有知识,就没有人会爱我。
  〖主要特征〗:冷眼看世界,抽离情感,喜欢思考分析,要知很多,但缺乏行动,对物质生活要求不 高,喜欢精神生活,不善表达内心感受 ;想藉由获取更多的知识,来了解环境,面对周遭的事物。他们想找出事情的脉络与原理,做为行动的准则。有了知识,他们才敢行动,也才会有安全感。
  〖主要特质〗:温文儒雅 、有学问 、条理分明 、表达含蓄 、拙於词令 、沉默内向 、冷漠疏离 、欠缺活力 、反应缓慢
  〖生活风格〗:爱观察、批评,把自己抽离,每天有看不完的书。
  〖人际关系〗:
  理智型(Thinker)你是个很冷静的人,总想跟身边的人和事保持一段距离,也不会让情绪。 很多时,你都会先做旁观者,后才可投入参与。另外,你也需要充分的私人空间和高度的私隐,否则你会觉得很焦虑,不安定!你也很有机会成为专家,例如电脑 啦,漫画啦,时装啦,因为你对知识是非常热爱的!
  〖好辨、抽离〗
  思想型的人常常观察身边的事,却很少参与,所以感情投入也很少。还有,他们好辨,很执着,却少有「辨输」的空间和量度。对知识的执着固然重要,但经验生活中所得的体会也非常可贵,希望你们取得平衡,得到最多!
  〖基本恐惧〗:无能,无知
  〖基本欲望〗:能干,知识丰富

2009年10月19日 星期一

Foo x(Bar())

Foo x(Bar())

似乎很有趣得声明, 这个声明定义了一个x function, 这个function 返回 Foo 类型object.

而x function的参数是一个函数,这个函数没有参数,并且返回一个Bar类型变量.

所以上面的定义和 Foo x = Foo(Bar()); 是不完全相同的.

2009年9月24日 星期四

fmode c++

fmod function

double fmod ( double numerator, double denominator );
float fmod ( float numerator, float denominator );
long double fmod ( long double numerator, long double denominator );





Compute remainder of division

Returns the floating-point remainder of numerator/denominator.

The remainder of a division operation is the result of subtracting the integral quotient multiplied by the denominator from the numerator:

remainder = numerator - quotient * denominator

Parameters

numerator
Floating point value with the division numerator.
denominator
Floating point value with the division denominator.



Return Value
The remainder of dividing the arguments.

Portability
In C, only the double version of this function exists with this name.

Example

/* fmod example */
#include
#include

int main ()
{
printf ("fmod of 5.3 / 2 is %lf\n", fmod (5.3,2) );
printf ("fmod of 18.5 / 4.2 is %lf\n", fmod (18.5,4.2) );
return 0;
}



Output:


fmod of 5.3 / 2 is 1.300000
fmod of 18.5 / 4.2 is 1.700000

in reference to:

"fmod
function
double fmod ( double numerator, double denominator );
float fmod ( float numerator, float denominator );
long double fmod ( long double numerator, long double denominator );
<cmath>
Compute remainder of division

Returns the floating-point remainder of numerator/denominator.The remainder of a division operation is the result of subtracting the integral quotient multiplied by the denominator from the numerator:remainder = numerator - quotient * denominatorParameters

numerator
Floating point value with the division numerator.
denominator
Floating point value with the division denominator.
Return Value
The remainder of dividing the arguments.Portability
In C, only the double version of this function exists with this name.Example
/* fmod example */
#include <stdio.h>
#include <math.h>

int main ()
{
printf ("fmod of 5.3 / 2 is %lf\n", fmod (5.3,2) );
printf ("fmod of 18.5 / 4.2 is %lf\n", fmod (18.5,4.2) );
return 0;
}Output:
fmod of 5.3 / 2 is 1.300000fmod of 18.5 / 4.2 is 1.700000"
- fmod - C++ Reference (view on Google Sidewiki)

2009年9月22日 星期二

瑞典克朗回来了

2009年9月21日 星期一

桃李不言,下自成蹊

使用频率

  较少使用


发 音

  táo lǐ bù yán,xià zì chéng xī


释 义

  蹊:小路。原意是桃树不招引人,但因它有花和果实,人们在它下面走来走去,走成了一条小路。比喻人只要真诚、忠实,就能感动别人。


出 处

  《史记·李将军列传》:“《史记》卷一零九《李将军传》太史公曰:“李将悛悛如鄙人,口不能道辞。及死之日,天下知与不知,皆为尽哀。彼其忠实心诚信於士大夫也?谚曰:桃李不言,下自成蹊。此言虽小,可以谕大也。”亦作“桃李不言,下自成行;桃李无言,下自成蹊。”


例句

  “桃李不言,下自成蹊”,弘一法师无愧于此誉,他重视言传身教,并毕生一以贯之。桃子李子虽不会说话但是他的果实甜美
  同样惹人喜爱 人们都来吃 树下自然就成了一条小路


原文

  太史公曰:传曰:“其身正,不令而行;其身不正,虽令不从。”其李将军之谓也。余睹李将军,悛悛如鄙人,口不能道辞。及死之日,天下知与不知,皆为尽哀。彼其忠实心诚信于士大夫也。谚曰:“桃李不言,下自成蹊。”此言虽小,可以谕大也。


译文

   太史公说:《论语》说,“本身行为正,不下命令,人们也奉行;本身不正,即使下命令,人们也不奉行。”这是说的李将军啊。我见到李将军,朴朴实实象个乡 下人,口不善于言辞。他死的时候天下无论认识他的或不认识他的,都为他十分哀痛。他那忠实诚恳的心地实在使士大夫崇敬,谚语说:“桃李不能言语,可树下踩 出小路来。”这话虽小,却可以使人明白大道理啊!


字词解释

  蹊:小路
  正:行得正
  悛悛:小心谦恭的样子
  能:擅长
  彼:代词,代李将军
  心:品德,思想
  信:信任
  士大夫:此处指将士
  虽:即使
  谕:告诉,这里是“说明”的意思


近义词

  桃李不言,下自成行


故 事

  西汉名将李广英勇善战,历经汉文帝、景帝、武帝,立下赫赫战功,匈奴单于都很敬佩他,对部下也很谦虚和蔼。西汉政府并没重用李广,60多岁被迫自杀,许多部下及不相识的人都自动为他痛哭,司马迁称赞他是“桃李不言,下自成蹊”


用 法

  复句式;作分句;含褒义;指实至名归。


其他说法

  “桃李不言,下自成蹊”表现了这样一个道理:酒香不怕巷子深,只要是真正的桃李,不必为自己多做宣传,人们自然会登门求贤。这一方面是对桃李沉默谦逊精神的肯定,另一方面也是对求贤者们的判断力的肯定。但是我们也应该看到,有时候桃李如果为自己说话,效果会更好。
  韩愈在《马说》里告诉我们:“千里马常有而伯乐不常有”,于是有了无数千里马辱没于奴隶人之 手,骈死于槽枥之间,同时求马者又总感叹世上无千里马。万马齐喑,是人才的悲哀,也是社会的悲哀。一个伯乐无法相尽天下良马,我们还需要良马们把自己打扮 得神采奕奕,奔腾跳跃,嘶鸣不已。同样,桃李的芬芳也难以尽传遍天下,也就难保一定“下自成蹊”,如果总恪守沉默是金的道理,恐怕许多桃李会在无人问津中 孤芳自赏直至腐烂。
  另外,求贤者的判断力也实在有限,如果桃李们都等着别人上门,而人们又只能“循蹊”而行,“循 蹊”便容易导致盲从地随波逐流。这样的路,尽头可能是桃李,也可能是臭鱼烂虾。冯小刚的电影《大腕》里有句话:“广告做得好,假的也成真的了”就是在嘲讽 着这种盲从与俗众的力量。错用了伪劣产品可以吃一堑长一智地换用另一种,而错用了纸上谈兵的赵括导致了赵国几十万兵丁被坑杀,赵王再也没有改过的机会了, 唯有向秦称臣。
  所以“桃李不言”有时难以保证“下自成蹊”的皆大欢喜,反而可能导致这样一种两败俱伤的局面: 一边是桃李们昂着头孤芳自赏心里感叹着世人无识才之慧眼,空任满腹才学成粪土;另一边是求贤若渴的人们没头苍蝇般地苦苦求索,有人没找到很失望,有人找错 了很受伤。沟通这两边的桥梁就在于“言”,只有桃李懂得为自己而言,才能更广为人知,人们也才能有更多更好的选择余地。因此天下的桃李们在想要保持自己高 洁的同时也应该明白这样一个道理:“桃李不言,下自成蹊”诚然可贵,然而打开天窗说亮话也许于人于己价更高。谦逊应有度,自信亦有理,毕竟我是桃李我怕 谁?

英汉对照   西汉时候,有一位勇猛善战的将军,名叫李广,一生跟匈奴打过七十多次仗,战功卓著,深受官兵和百姓的爱戴。李广虽然身居高位,统领千军万马,而且是保卫 国家的功臣,但他一点也不居功自傲。他不仅待人和气,还能和士兵同甘共苦。每次朝廷给他的赏赐,他首先想到的是他的部下,就把那些赏赐统统分给官兵们;行 军打仗时,遇到粮食或水供应不上的情况,他自己也同士兵们一样忍饥挨饿;打起仗来,他身先士卒,英勇顽强,只要他一声令下,大家个个奋勇杀敌,不怕牺牲。 这是一位多么让人崇敬的大将军啊!
  后来,当李广将军去世的噩耗传到军营时,全军将士无不痛哭流涕,连许多与大将军平时并不熟悉的百姓也纷纷悼念他。在人们心目中,李广将军就是他们崇拜的大英雄。
  汉朝伟大的史学家司马迁在为李广立传时称赞道:“桃李不言,下自成蹊。”意思是说,桃李有着芬芳的花朵,甜美的果实,虽然它们不会说话,但仍然会吸引人们到树下赏花尝果,以至树下都走出一条小路,李广将军就是以他的真诚和高尚的品质赢得了人们的崇敬。
  “桃李不言,下自成蹊”这则成语出自《史记·李将军列传》,比喻为人真诚,严于律已,自然会感动别人,自然会受到人们的敬仰。
  Peaches and Plums Do Not Have to Talk, Yet the World Beats a Path to Them--Natural Attraction
  During the Western Han Dynasty(206 B.C.- A.D.24)Period, there was a very famous general whose name was Li Guang. He was very brave and skillful in battle, and had fought more than seventy battles with the Huns, an ancient nationality in China.Having made brilliant achievements in war, he was deeply loved and esteemed by the officers and men as well as the common people. However,he did not claim credit for himself and become arrogant,although he held a high post,commanding a big army,and had rendered outstanding service in defending the county. He was not only polite and amiable, but also shared weal and woe with the soldiers. He always had the troops under his commandant heart,and whenever gifts were bestowed upon him by the imperial government,he distributed the gifts to his officers and men. When marching, he endured the torments of hunger and thirst as the soldiers did when food and water were in short supply. When fighting, he charged at the head of his men,and ,when he gave the order,every soldier advanced bravely to engage in fighting,not fearing death.
  When the sad news of the death of General Li Guang reached the militaty camp,the officers and men of the whole army wept bitterly.


在教育学中德育方法的表现

  “桃李不言,下自成蹊”体现了德育方法中的榜样示范法
  榜样示范法,用榜样人物的优秀品德来影响学生的思想、情感和行为的方法。由于榜样能把社会真实 的思想、政治和法纪、道德关系表现得更直接、更亲切、更典型,因而能给人以极大的影响、感染和鼓励,教育、带动和鼓舞人们前进;运用榜样示范法符合青少年 学生爱好学习,善于模仿,崇拜英雄,追求上进的年龄特点,也符合人的认识有生动直接到抽象的发展规律。

2009年9月11日 星期五

Leave Color

2009年9月9日 星期三

Invert Chrominance Phase

I saw there is a effect from Premiere Pro which is called Invert Chrominance Phase.
And I guess it probably exchange the UV in YUV color space. And the result color from my testing code looks almost same as the result in Premiere.
Following is the HLSL code for that. Formulat is from Wiki.

float y, u, v;
y = dot(thePixel.rgb, float3(0.299, 0.587, 0.114));
u = dot(thePixel.rgb, float3(-0.14713, -0.28886, 0.436));
v = dot(thePixel.rgb, float3( 0.615, -0.51499, -0.10001));

thePixel.r = y + 1.13983 * u ;
thePixel.g = y - 0.39465 * v - 0.58060 * u ;
thePixel.b = y + 2.03211 * v ;

2009年8月26日 星期三

游戏主循环


引言

游戏主循环是每个游戏的心跳,输送着整个游戏需要的养分。不幸的是没有任何一篇好的文章来指导一个菜鸟游戏程序员如何为自己的程序供养。不过不用担心,因为你刚好不小心看到了这篇,也是唯一一篇给予这个话题足够重视的文章。

由于我身为游戏程序员,我见过许许多多的手机小游戏的代码。这些代码给我展 示了五彩缤纷的游戏主循环实现方法。你可能要问:“这么简单的一个小玩意还能做到千奇百怪?” 事实就是这样,我就会在此文中讨论一些主流实现的优缺点,并且给你介绍在我看来最好的输送养分的解决方案。


游戏主循环


每一个游戏都是由获得用户输入,更新游戏状态,处理AI,播放音乐 和音效,还有画面显示这些行为组成。游戏主循环就是用来处理这个行为序列。如我在引言中所说,游戏主循环是每一个游戏的心跳。在此文中我不会深入讲解上面 提到的任何一个行为,而只详细介绍游戏主循环。所以我把这些行为简化为了两个函数:

update_game(); //更新游戏状态 (后文可能翻译为逻辑帧)
display_game(); //更新显示 (显示帧)

下面是最简单的游戏主循环:

bool game_is_running = true;

while( game_is_running ) {
update_game();
display_game();
}

这 个简单循环的主要问题是它忽略了时间,游戏会尽情的飞奔。在小霸王机器上运行会使玩家有极强的挫败感,在牛逼的机器上运行则会要求玩家有超人的判断力和 APM(原意为慢的机器上运行慢,快的机器上运行快……)。在远古时代,硬件的速度已知的情况下,这不算什么,但是目前有如此多的硬件平台使得我们不得不 去处理时间这个重要因素。对于时间的处理有很多的方法,接下来我会一一奉上。

首先我会解释两个贯穿全文的术语:

每秒帧数(后简称FPS)

FPS是Frames Per Second的缩写。在此文的上下文中它意味着display_game()每秒被调用的次数。

游戏速度

游戏速度是每秒更新游戏状态的速度,换言之,即update_game()每秒被调用的次数。

FPS依赖于恒定的游戏速度

实现

一个让游戏每秒稳定运行在25帧的解决方案如下:

const int FRAMES_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;

DWORD next_game_tick = GetTickCount();
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started

int sleep_time = 0;

bool game_is_running = true;

while( game_is_running ) {
update_game();
display_game();

next_game_tick += SKIP_TICKS;
sleep_time = next_game_tick - GetTickCount();
if( sleep_time >= 0 ) {
Sleep( sleep_time );
}
else {
// Shit, we are running behind!
}
}

这 个方案有一个非常大的优点:简单!因为你知道update_game()每秒被调用25次,那么你的游戏的逻辑部分代码编写将非常直白。比如说在这种主循 环实现的游戏中实现一个 重放 函数将非常简单(译者注:因为每帧的间隔时间已知,只需要记录每一帧游戏的状态,回放时按照恒定的速度播放即可。就像电影胶片一样)。如果在游戏中没有受 到随机值的影响,只需要记录玩家的输入就可以实现重放。

在你实现这个循环的硬件上你可以按需要调整FRAMES_PER_SECOND到一个理想的值,但是这个游戏主循环实现会在各种硬件上表现得怎么样呢?

小霸王机

如果硬件可以应付指定的FPS,那么不会有什么事情发生。但是小霸王通常是应付不了的,游戏就会卡。在极端情况下就会卡得掉渣,或者一步十卡、一卡十步(原意为某些情况下游戏速度很慢,有一些情况下又比较正常)。这样的问题会毁掉你的游戏,使得玩家及其挫败。

牛逼的机器

在牛逼的机器上似乎不会有任何问题,但是这样的游戏主循环浪费大量的时钟循 环!牛逼的机器运行这个游戏可以轻松的跑到300帧,却每秒只运行了25或者30帧~ 那么这个主循环实现会让拥有牛逼硬件的玩家无法尽情发挥其硬件效果产生极大的挫败感(原意为这样的实现会让你的视觉效果受到影响,尤其是高速移动物体)。

从另外一个角度来说,在移动设备上,这一点可能会是一个优点。游戏持续的高速运行会很快地消耗电池……

结论

基于恒定游戏速度的FPS的主循环实现方案简单易学。但是存在一些问题,比如定义的FPS太高会使得老爷机不堪重负,定义的FPS太低则会使得高端硬件损失太多视觉效果。

基于可变FPS的游戏速度

实现

另外一种游戏实现可以让游戏尽可能的飞奔,并且让依据FPS来决定游戏速度。游戏状态会根据每一显示帧消耗的时间来进行更新。

DWORD prev_frame_tick;
DWORD curr_frame_tick = GetTickCount();

bool game_is_running = true;
while( game_is_running ) {
prev_frame_tick = curr_frame_tick;
curr_frame_tick = GetTickCount();

update_game( curr_frame_tick - prev_frame_tick );
display_game();
}

这个游戏主循环的代码比起之前稍微复杂一些,因为我们必须去考虑两次update_game()调用之间的时间差。不过,好在这并不算复杂。
初窥这个实现的代码好像是一个理想的实现方案。我已经见过许多聪明的游戏程序员用这种方式来书写游戏主循环。但是我会给你展示这个实现方案在小霸王和牛逼的机器上的严重问题!是的,包括非常职业非常娴熟非常牛逼的玩家的机器。

小霸王

小霸王会在某些运算复杂的地方出现卡的情况,尤其在3D游戏中的复杂场景更 是如此。帧率的降低会影响游戏输入的响应,同时降低玩家的反应速度。游戏状态更新也会因此突然受到影响。这样的情况会使得玩家和AI的反应速度减慢,造成 玩家挫败感加剧。比如一个在正常帧率下可以轻松越过的障碍会在低帧率下无法逾越。更严重的问题是在小霸王上会经常发生一些违反物理规律的怪事,如果这些运 算涉及到物理模拟的话。

牛逼的机器

你可能会好奇,为什么刚才的游戏循环在飞快的机器上会出现问题。不幸的是,这个方案的确如此,首先,让我给你介绍一些计算机数学知识。

浮点数类型占用内存大小是有限的,那么有一些数值就无法被呈现。比如0.1就不能用2进制表示,所以会被近似的存储在一个浮点数中。我用python给你们展示一下。

>>> 0.1
0.10000000000000001

这个问题本身并不怎么具有戏剧性,但是这样的后果却截然相反。比方说你的赛车的速度是0.001个单元每微秒。那么正确的结果是在10秒后你的赛车会移动10个单位,那么我们这样来实现一下:

>>> def get_distance( fps ):
... skip_ticks = 1000 / fps
... total_ticks = 0
... distance = 0.0
... speed_per_tick = 0.001
... while total_ticks < 10000:
... distance += speed_per_tick * skip_ticks
... total_ticks += skip_ticks
... return distance


现在我们来得到40帧每秒时运行10秒后的结果
>>> get_distance( 40 )
10.000000000000075

等等~怎么不是10呢?发生了什么?嗯,400次加法后的误差就有这么大,每秒运行100次加法后又会是怎么一个样子呢?

>>> get_distance( 100 )
9.9999999999998312

误差越来越大了!那么,40帧每秒的结果和100帧每秒之间误差差距是多大呢?

>>> get_distance( 40 ) - get_distance( 100 )
2.4336088699783431e-13

你可能会想这样的误差可以忽略。但是真正的问题出现在你使用这些错误的值去 进行更多的运算。小的误差会被扩大为致命的错误!然后这些错误会在游戏飞奔的同时毁掉它!这些问题发生的几率绝对大到足够引起你的注意。我有见过因为这个 原因在高帧率出现问题得游戏。之后那个游戏程序员发现这些问题出现在游戏的核心部分,只有重写大部分代码才能修复它。

结论

这样的游戏主循环看上起不错,但是并不怎么样。不管运行它的硬件怎样,都可能出现严重的问题。另外,游戏实现的代码相对于固定游戏速度的主循环而言更加复杂,那你还有什么使用它的理由呢?

最大FPS和恒定游戏速度

实现

我们的第一个实现中,FPS依赖于恒定的游戏速度,在低端的机器上会出现问题。游戏速度和游戏显示都会出现掉帧。一个可行的解决方案是牺牲显示帧率的来保持恒定的游戏速度。下面就实现了这种方案:


const int TICKS_PER_SECOND = 50;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 10;

DWORD next_game_tick = GetTickCount();
int loops;

bool game_is_running = true;
while( game_is_running ) {

loops = 0;
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
update_game();

next_game_tick += SKIP_TICKS;
loops++;
}

display_game();
}

游戏会以稳定的50(逻辑)帧每秒的速度更新,渲染速度也尽可能的快。需要 注意的是,如果渲染速度超过了50帧每秒的话,有一些帧的画面将会是完全相同的。所以显示帧率实际上也等同于最快每秒50帧。在小霸王上运行的话,显示帧 率会在更新游戏状态循环达到MAX_FRAMESKIP时下降。从上面这个例子来说就是当渲染帧率下降到5(FRAMES_PER_SECOND / MAX_FRAMESKIP)以下时,游戏速度会变慢。

小霸王

在小霸王上运行这样的游戏循环会出现掉帧,但是游戏速度不受到影响。如果硬件还是没有办法处理这样的循环,那么游戏速度和游戏帧率都会受到影响。

牛逼的机器

在牛逼的机器上这个游戏循环不会出现问题,但是如同第一个解决方案一样,还是浪费了太多的时钟周期。找到一个快速更新并且依然能够在小霸王上运行游戏的平衡点是至关重要的!

结论

使用上面的这个方案可以使游戏的实现代码比较简单。但是仍然有一些问题:如果定义了一个过高的FPS会让小霸王吃不消,如果过低则会让牛逼的机器难以发挥性能。


独立的可变显示帧率和恒定的游戏速度

实现

有没有可能对之前的那种方案进行优化使得它在各种平台上都有足够好的表现 呢?当然是有的!游戏状态本身并不需要每秒更新60次。玩家输入,AI信息等都不需要如此高的帧率来进行更新,大约每秒25次就足够了。所以,我们可以试 着让update_game()每秒不多不少的被调用25次。渲染则放任不管,让其飞奔。但是不能让小霸王的低渲染帧率影响到游戏状态更新的速度。下面就 是这个方案的实现:

const int TICKS_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 5;

DWORD next_game_tick = GetTickCount();
int loops;
float interpolation;

bool game_is_running = true;
while( game_is_running ) {

loops = 0;
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
update_game();

next_game_tick += SKIP_TICKS;
loops++;
}

interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
/ float( SKIP_TICKS );
display_game( interpolation );
}

使用这种方案的update_game()实现会比较简单,相对而 言,display_game()则会变得稍许复杂。你需要实现一个接收插值参数的预言函数,这并不是什么难事,只是需要做一些额外的工作。我会接着解释 这个预言函数是如何工作的,不过首先让我告诉你为什么需要这样的一个函数。

游戏状态每秒被更新25次,如果你渲染的时候不使用插值计算,渲染帧率就会 被限定在25帧。需要注意的是,25帧并没有人们想象中的糟糕,电影画面在每秒24帧的情况下依然流畅。所以25帧可以很好的展示游戏画面,不过对于高速 移动的物体,更高的帧率会带来更好的效果。所以我们要做的是,在显示帧之间让高速移动的物体平滑过度。这就是我们需要一个插值和预言函数的原因。

插值和预言函数

如我之前所说,游戏状态更新在一个恒定的帧率下运行着,当你渲染画面的时 刻,很有可能就在两个逻辑帧之间。假设你已经第10次更新了你的游戏状态,现在你需要渲染你的场景。这次渲染就会出现在第10次和第11次逻辑帧之间。很 有可能出现在第10.3帧的位置。那么插值的值就是0.3。举个例子说,我的一辆赛车以下面的方式计算位置。

position = position + speed;

如果第10次逻辑帧后赛车的位置是500,速度是100,那么第11帧的位置就会是600. 那么在10.3帧的时候你会在什么位置渲染你的赛车呢?显而易见,应该像下面这样:

view_position = position + (speed * interpolation)

现在,赛车将会被正确地渲染在530这个位置。

基本上,插值的值就是渲染发生在前一帧和后一帧中的位置。你需要做的就是写 出预言函数来预计你的赛车/摄像机或者其他物件在渲染时刻的正确位置。你可以根据物件的速度来计算预计的位置。这些并不复杂。对于某些预计后的帧中出现的 错误现象,如某个物体被渲染到了某个物体之中的情况的确会出现。由于游戏速度恒定在每秒更新25次状态,那么这种错误停留在画面上的时间极短,难以发现, 并无大碍。

小霸王

大多数情况下,update_game()执行需要的时间比display_game()少得多。实际上,我们可以假设在小霸王上update_game()每秒还是能运行25次。所以游戏的逻辑状态不会受到太大的影响,即使FPS非常低。

牛逼的机器

在牛逼的硬件上,游戏速度会保持每秒25次,屏幕更新却可以非常快。插值的方案可以让游戏在高帧率中有更好的画面表现。但实质上游戏的状态每秒只更新了25次。

结论

使游戏状态的更新独立于FPS的解决方案似乎是最好的游戏主循环实现。不过,你必须实现一个插值计算函数。

整体总结

游戏主循环对游戏的影响远远超乎你的想象。我们讨论了4个可能的实现方法,其中有一个方案是要坚决避免的,那就是可变帧率来决定游戏速度的方案。

一个恒定的帧率对移动设备而言可能是一个很好的实现,如果你想展示你的硬件全部的实力,那么最好使用FPS独立于游戏速度的实现方案。

如果你不想麻烦的实现一个预言函数,那么可以使用最大帧率的实现方案,只是要找到一个帧率大小的平衡点。

现在,你可以着手编写你梦寐以求的游戏了!

Koen Witters

Svenska kurs





Linköpings universitet



Week 35 - 43 2009 Text format | Printer friendly version

Course
THSV04
Nybörjarkurs i svenska för utbytesstudenter
D
Course
THSV03
Nybörjarkurs i svenska för utbytesstudenter
C
Course
THSV03
Nybörjarkurs i svenska för utbytesstudenter
D
Course
THSV04
Nybörjarkurs i svenska för utbytesstudenter
C
Course
THSV04
Nybörjarkurs i svenska för utbytesstudenter
E

Week 37
2009
Monday
Sep 7
Tuesday
Sep 8
Wednesday
Sep 9
Thursday
Sep 10
Friday
Sep 11
08
00
30
09
00
30
10
00
30
11
00
30
12
00
30
13
00
30
14
00
30
15
00
30
16
00
30
17
00 17:00-20:00
THSV04.e
Lesson
Peder Johansson
D34
17:00-20:00
THSV04.c
Lesson
Tori Latkovic
KY31
17:00-20:00
THSV04.d
Lesson
Åsa Tiri
KY31
30
18
00
30
19
00
30
20
00
30


Week 38
2009
Monday
Sep 14
Tuesday
Sep 15
Wednesday
Sep 16
Thursday
Sep 17
Friday
Sep 18
08
00
30
09
00
30
10
00
30
11
00
30
12
00
30
13
00
30
14
00
30
15
00
30
16
00
30
17
00 17:00-20:00
THSV04.e
Lesson
Peder Johansson
D34
17:00-20:00
THSV04.c
Lesson
Tori Latkovic
KY31
17:00-20:00
THSV04.d
Lesson
Åsa Tiri
KY31
30
18
00
30
19
00
30
20
00
30


Week 39
2009
Monday
Sep 21
Tuesday
Sep 22
Wednesday
Sep 23
Thursday
Sep 24
Friday
Sep 25
08
00
30
09
00
30
10
00
30
11
00
30
12
00
30
13
00
30
14
00
30
15
00
30
16
00
30
17
00 17:00-20:00
THSV04.e
Lesson
Peder Johansson
D34
17:00-20:00
THSV04.c
Lesson
Tori Latkovic
KY31
17:00-20:00
THSV04.d
Lesson
Åsa Tiri
KY31
30
18
00
30
19
00
30
20
00
30


Week 40
2009
Monday
Sep 28
Tuesday
Sep 29
Wednesday
Sep 30
Thursday
Oct 1
Friday
Oct 2
08
00
30
09
00
30
10
00
30
11
00
30
12
00
30
13
00
30
14
00
30
15
00
30
16
00
30
17
00 17:00-20:00
THSV04.e
Lesson
Peder Johansson
D34
17:00-20:00
THSV04.c
Lesson
Tori Latkovic
KY31
17:00-20:00
THSV04.d
Lesson
Åsa Tiri
KY31
30
18
00
30
19
00
30
20
00
30


Week 41
2009
Monday
Oct 5
Tuesday
Oct 6
Wednesday
Oct 7
Thursday
Oct 8
Friday
Oct 9
08
00
30
09
00
30
10
00
30
11
00
30
12
00
30
13
00
30
14
00
30
15
00
30
16
00
30
17
00 17:00-20:00
THSV04.e
Lesson
Peder Johansson
D34
17:00-20:00
THSV04.c
Lesson
Tori Latkovic
KY31
17:00-20:00
THSV04.d
Lesson
Åsa Tiri
KY31
30
18
00
30
19
00
30
20
00
30


Week 42
2009
Monday
Oct 12
Tuesday
Oct 13
Wednesday
Oct 14
Thursday
Oct 15
Friday
Oct 16
08
00
30
09
00
30
10
00
30
11
00
30
12
00
30
13
00
30
14
00
30
15
00
30
16
00
30
17
00 17:00-20:00
THSV04.e
Lesson
Peder Johansson
D34
17:00-20:00
THSV04.c
Lesson
Tori Latkovic
KY31
17:00-20:00
THSV04.d
Lesson
Åsa Tiri
KY31
30
18
00
30
19
00
30
20
00
30


Week 43
2009
Monday
Oct 19
Tuesday
Oct 20
Wednesday
Oct 21
Thursday
Oct 22
Friday
Oct 23
08
00
30
09
00
30
10
00
30
11
00
30
12
00
30
13
00
30
14
00
30
15
00
30
16
00
30
17
00 17:00-20:00
THSV04.e
Lesson
Peder Johansson
D34
17:00-20:00
THSV04.c
Lesson
Tori Latkovic
KY31
17:00-20:00
THSV04.d
Lesson
Åsa Tiri
KY31
30
18
00
30
19
00
30
20
00
30


The reservation has been modified recently

The reservation holds more information (click on the icon to show more information)
Italic style
The reservation is preliminary

[New search]
[Download the reservations in vCal or iCal format]
[Link to page]
TimeEdit 1.4.9 - Copyright © 1992-2009 TimeEdit AB
Valid HTML 4.01

2009年8月25日 星期二

瑞典人投机取巧

Planka.nu - Så plankar du i SL-trafiken from Planka.nu on Vimeo.