您最喜欢的游戏特定编码宝石是什么?[关闭]


24

我将从约翰·卡马克(John Carmack)的《雷神之锤3》中的快速逆平方根开始:

float Q_rsqrt(float number) {

  long i;
  float x2, y;
  const float threehalfs = 1.5F;

  x2 = number * 0.5F;
  y = number;
  i = * ( long * ) &y;
  i = 0x5f3759df - ( i >> 1 );
  y = * ( float * ) &i;
  y = y * ( threehalfs - ( x2 * y * y ) );

  return y;

}

6
这不是一个真正的问题-至少,您可以将其声明为社区Wiki页面...
Rachel Blum

完成,社区化。
gak 2010年

3
拧那个!只需使用出色的JC编写的所有代码!
亚当·内洛

3
顺便说一句,做笔记,有一个更准确的“幻数”在高速逆平方根函数的使用方法:0x5f375a86(en.wikipedia.org/wiki/...
莉吉特

8
另请注意,这不是约翰·卡马克(John Carmack)的。
Kaj 2010年

Answers:


25

mapValue函数:

float mapValue( float inVal, float inFrom, float inTo, float outFrom, float outTo )
{
    float inScale = (inFrom != inTo) 
        ? ( ( inVal - inFrom ) / ( inTo - inFrom ) ) 
        : 0.0f;
    float outVal = outFrom + ( inScale * ( outTo - outFrom ) );
    outVal = (outFrom < outTo ) 
        ? clamp( outVal, outFrom, outTo ) 
        : clamp( outVal, outTo, outFrom );
    return outVal;
}

它采用一个值,将其转换为一个范围内的比例,然后相对于另一个范围缩放比例。像双-。

您可以使用它来规范化内容:

float minDamage = 0.0f; float maxDamage = 300.0f;
float normalisedDamage = mapValue(damange, minDamage, maxDamage, 0.0f, 1.0f);

或者,您可以从一个范围转换为另一范围:

float brakeStrength = mapValue(timeToCollision, 
    0.0f, 10.0f, // seconds
    1.0f, 0.2f // brake values 
    );

请注意,在第二个示例中,超出范围与进入范围的顺序不同。

看起来不多,但是我到处都用这个小家伙。


14

我仍然不敢相信我在游戏代码中使用了勾股定理几次。对我来说,这个简单的公式是游戏开发中的瑰宝。

a ^ 2 + b ^ 2 = c ^ 2
(来源:mathurl.com

要么

替代文字
(来源:mathurl.com

当只有相对距离很重要时,无需昂贵的平方根运算即可使用

替代文字
(来源:mathurl.com


坦白地说,毕达哥拉斯的数学在整个游戏代码中都被广泛使用,尤其是引擎,例如物理代码,渲染代码,AI。
尼克·贝德福德

1
真正。这就是为什么它是一颗宝石。;)
MrValdez

4
一个有趣的变化是,当您只关心相对距离时。然后,您可以跳过潜在的昂贵sqrt通话,而只需进行计算即可distance2 = x^2 + y^2
mmyers

@mmyers-另一个奇妙的事情:如果您在x ^ 2的空间中工作,距离不仅是相对的。
史蒂文·埃弗斯

感谢您提及相对距离位。我已经看到太多不必要的平方根运算,就像人们在使用A *时应该使用不太精确的东西一样。
Ricket


10

我必须选择Duff的设备。从字面上看,这是第一段代码。 “你能做到吗?!?”


我的天啊。护目镜!他们什么都不做!
拉乌尔

“开关盒”内部嵌套的“ do-while”总是让我眨眼。甚至20年后……
Andreas

1
-1。我不喜欢这个 今天它不是很有用(memcpy如果您希望其他人能够阅读您的代码,则可以改用)
bobobobo

1
@JoeWreschnig为什么不呢?Memcpy将始终具有更高的可读性,可移植性并且可能还会进行优化。
kaoD 2012年

1
@kaoD:因为memcpy不等同于Duff的设备-如果它不做同样的事情,那么“可读性,可移植性以及可能更优化”的大小无关紧要!现代CPU管道可能会做的更好,而不达夫设备比,因为分支预测和指令缓存,但是这并没有memcpy

7

多年以来我帮助编写的游戏中的一个C / C ++小片段:

(fill ? FillRect : DrawRect) (x, y, w, h, colour);

在我的第一个游戏(this)中,我需要访问超过1Mb的RAM,并且在Internet起飞之前,我没有DOS应用程序用来访问额外RAM的XMS和EMS文档。

因此,我最后使用了一个小“后门”,该后门在386中与段寄存器有关。通常,在实模式下,计算出的地址seg*16+off将您限制为1Mb。

但是,您可以切换到保护模式,设置一个地址为4Mb的段,然后切换回去,并且只要您不写入段寄存器(因为DOS仅使用8086段寄存器就可以了),就可以访问整个寄存器。 4Mb作为平面地址空间。如果要使用DOS服务,则必须切换回实模式。

也没有很多DPMI扩展器。


几乎可以在C#中工作(您需要声明一个委托类型并插入至少一个
强制

您是说在实模式下使用32位寻址模式?(即需要一个地址大小的前缀)。您确定必须设置一个段描述符,并且实际上没有将段寄存器用作普通的16 * FS +吗?我不认为段甚至在16位模式下也没有限制,仅在基地址(16 *它们的值)上有限制,所以您不能仅将FS设置为16位模式下的[fs:esi]任何东西,并使用或其他方式访问任何内容通缉?
彼得·科德斯

我还没有尝试过,也没有为16位模式(只有32位和64位asm)编写任何实际代码,但这听起来很奇怪。嗯,虽然合理。现代CPU肯定会在内部缓存段内容,并且只有在您写入段reg时才重新加载这些缓存,所以这也许就是它保持保护模式的base + limit的方式(如果这实际上是在发生,并且您不只是在使用从16 * FS开始为4MB)。
彼得·科德斯

5

就个人而言,我是Mersenne Twister的忠实粉丝,因为它具有可预测的随机数,尤其是在您需要创建多个Rand种子的实例时

http://en.wikipedia.org/wiki/梅森_twister


Mersenne Twister很好,因为它是一个很好的随机数生成器,但是它并不是特别优雅或酷炫(或快速或易于实现)。为此,您可能需要查看en.wikipedia.org/wiki/Rule_30

1
在大多数情况下,WELL通常比MT更好。.en.wikipedia.org
wiki/Well_equidistributed_long

5

这是克里斯·克劳福德(Chris Crawford)提到的(显然是Atari使用的),他称之为“图形技巧”:

LDA FIRST
EOR SECOND
AND CONTROL
EOR SECOND
STA OUTPUT

阅读完整的文章作出解释。


1
该链接现在已断开,因此在这里进行解释将很有帮助。
finnw 2011年

谢谢。他走了,再次更改了他的网站。我更新了链接。
安东尼

4

由于某些原因,人们经常低估游戏中设计模式的力量。我已经看到几乎每一个GoF模式都能成功应用于游戏。


1
我喜欢游戏编程的一件事是摆脱标准的GoF方法“正确性”,而只专注于纯可爱的速度!也就是说,我在游戏中看到过许多不良的MVC实现,弊大于利。
伊恩

我认为设计模式应有的地位。不过,在游戏中没有那么多。
blissfreak 2014年

@blissfreak:游戏编程并没有什么特别之处,它使游戏模式变得不常见。它们很荒谬,是一些示例。
史蒂文·埃弗斯

4

Math.atan2()非常有用(以及所有trig)。


是的,天哪!我已经做过很多3D了,但从来没有真正需要它。
Skizz 2010年

+1,这是从x + y向量分量到弧度方向的唯一方法。
RCIX

1
@RCIX:我的观点是,变换是不必要的,即(x,y)->角度,对于任何角度问题都有矢量解。
Skizz 2010年

6
我不会真正将裸标准库函数称为“ gem”。

1
@Skizz:也许适用于3d,但是我不知道采用其他方法来提取标准化向量并提取弧度方向值。在2D游戏中具有很高的价值。
RCIX

3

要添加到上面的勾股宝石中……
我总是告诉人们,对于3D编程,他们只需要知道: -a
^ 2 + b ^ 2 = c ^ 2
-soscastoa(正弦=相对侧/倾斜侧,cos =固定侧/斜面,tan =相对面/附着面)
-a。b = | a | * | b | * cos alpha
-a * b = | a | * | b | * sin alpha *单位向量
它可以解决您在游戏开发中遇到的任何3d(或2d)问题-4条规则。
当然,有更好的方法,但这可以解决所有问题-我应该知道,我是一个基于em的职业的黑客。


5
re:soscastoa我想大多数人都知道sohcahtoa(用“斜边”代替更具体的斜边)。从舌头流出更容易,因此我认为更容易记住。
Asmor

1
我将永远喜欢“老阿拉伯坐在他的骆驼和How叫上”,因为中学(高中时代)已经印在我的大脑上。
乔治·达基特

还有“ š青梅Ø LD ^ h ippy ç诗情一个 ND ^ h广告牛逼撕开Ø ñ 一个 CID”
blissfreak

3

我最喜欢的之一是'Life'的汇编语言版本,以及对其进行优化的完整描述,请参见Michael Abrash撰写的“ The Zen of Code Optimization”

我会把他的任何书籍推荐给任何想要编码宝石的人。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.