가장 좋아하는 게임 별 코딩 보석은 무엇입니까? [닫은]


24

Quake III 의 John Carmack 's Fast Inverse Square Root 부터 시작하겠습니다 .

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
그것은 실제로 질문이 아닙니다. 최소한이 페이지를 커뮤니티 위키 페이지로 선언 할 수도 있습니다.
Rachel Blum

커뮤니티에서 완료했습니다.
gak

3
망쳐! 위대한 JC가 만든 모든 코드와 함께하십시오!
Adam Naylor

3
0x5f375a86 (: 그건 그렇고,보다 정확한 "매직 넘버"제곱근 함수를 역 고속에서 사용하기가 있다는 것을주의 할 en.wikipedia.org/wiki/... )
Ricket

8
또한 John Carmack이 아닙니다.
Kaj

답변:


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와 같은 엔진 전체에서 사용됩니다.
Nick Bedford

1
참된. 그것이 보석 인 이유입니다. ;)
MrValdez

4
흥미로운 변형은 상대 거리 에만 관심이있는 경우 입니다. 그런 다음 잠재적으로 비싼 sqrt호출을 건너 뛰고 간단히 계산할 수 distance2 = x^2 + y^2있습니다.
mmyers

@mmyers-또 다른 멋진 점 : x ^ 2 공간에서 작업하는 경우 거리는 상대적이 아닙니다.
Steven Evers

상대 거리 비트를 언급 해 주셔서 감사합니다. 사람들이 덜 정확한 것을 사용해야 할 때 A *를 사용하는 것처럼 불필요한 제곱근 연산이 너무 많이 보였습니다.
Ricket

13

나에게서 가장 큰 것은 Scott Bilas의 GameObject 시스템에 관한 내용을 읽고 있었다 . 필자는 데이터베이스 시스템을 사용하지 않더라도 6 단계 상속 트리를 만드는 것을 중단하고 훨씬 더 관리하기 쉽고 재사용 가능한 구성 요소 시스템을 만들었습니다.


10

Duff 's Device 와 함께 가야 합니다. 문자 그대로 턱을 떨어 뜨린 것은 첫 번째 코드 블록이었습니다. "당신은 할 수 있습니까?!?"


세상에 고글! 그들은 아무것도하지 않습니다!
Raoul

"스위치 케이스"안에 중첩 된 "do-while"은 항상 깜박입니다. 20 년이 지난 후에도
Andreas

1
-1. 나는 이것을 좋아하지 않는다. 오늘날에는 그다지 유용하지 않습니다 ( memcpy다른 사람들이 코드를 읽을 수있게 하려면 대신 사용 하십시오)
bobobobo

1
@JoeWreschnig 왜 안되죠? Memcpy는 항상 더 읽기 쉽고 휴대 가능하며 최적화되어있을 것입니다.
kaoD

1
@kaoD : memcpy는 Duff의 장치와 동일하지 않기 때문에 "읽을 수 있고 휴대 가능하며 아마도 더 최적화 된"방법이 중요하지 않습니다. 현대 CPU 파이프 라인은 아마도 때문에 분기 예측 및 명령어 캐시의 그것보다 더프의 장치없이 잘 할 것입니다,하지만이없는 것도 함께 할 수있는가 memcpy.

7

몇 년 전에 글을 쓰는 데 도움이 된 게임의 작은 C / C ++ 스 니펫 :

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

첫 번째 게임 ( this )에서 1Mb 이상의 RAM에 액세스해야했고 인터넷이 시작되기 전에 DOS 응용 프로그램이 추가 RAM에 액세스하는 데 사용한 XMS 및 EMS에 대한 설명서가 없었습니다.

그래서 나는 세그먼트 레지스터와 관련하여 386에 등장한 작은 '백도어'를 사용했습니다. 일반적으로 실제 모드에서는 주소가 seg*16+off1Mb로 제한되어 계산되었습니다 .

그러나 보호 모드로 전환하고 4Mb 주소로 세그먼트를 설정 한 후 다시 전환하고 세그먼트 레지스터에 기록하지 않은 경우 (DOS는 8086 세그먼트 레지스터 만 사용했기 때문에 OK) 전체에 액세스 할 수 있습니다. 플랫 주소 공간으로 4Mb. DOS 서비스를 사용하려면 실제 모드로 전환해야합니다.

사용 가능한 DPMI 익스텐더가 많지 않았습니다.


C #에서 거의 작동합니다 (대리자 유형을 선언하고 하나 이상의 캐스트를 삽입해야 함)
finnw

실제 모드에서 32 비트 주소 지정 모드를 의미합니까? (즉, 주소 크기 접두사가 필요합니다). 세그먼트 디스크립터를 설정해야했고 실제로 세그먼트 레지스터를 일반 16 * FS +로 사용하지 않았습니까? 세그먼트가 16 비트 모드, 기본 주소 (16 * 값)에 한계가 있다고 생각하지 않았으므로 16 비트 모드에서 FS를 무언가로 설정할 수 없으며 사용 [fs:esi]하거나 무엇이든 액세스 할 수 없습니다. 원했습니까?
Peter Cordes

나는 이것을 시도하지 않았거나 16 비트 모드, 32 및 64 비트 asm에 대한 실제 코드를 작성했지만 이상한 소리가납니다. 흠, 그럴듯한. 최신 CPU는 세그먼트 내부를 확실히 캐시하고 세그먼트 등록에 쓸 때만 캐시를 다시로드하므로 보호 모드 base + limit을 유지하는 방법 일 수 있습니다 (실제로 발생한 일이며 실제로 사용하지 않은 경우) 16 * FS에서 시작하는 4MB).
Peter Cordes

5

개인적으로 저는 Mersenne Twister의 팬으로, 난수를 예측할 수 있습니다. 특히 다른 시드의 여러 인스턴스를 만들어야하는 경우

http://en.wikipedia.org/wiki/Mersenne_twister


Mersenne Twister는 좋은 난수 생성기라는 점에서 훌륭하지만 특히 우아하거나 시원하지는 않습니다 (또는 빠르거나 구현하기 쉽지 않음). 이를 위해 en.wikipedia.org/wiki/Rule_30을 참조하십시오 .

1
음 .. 더 나은 MT에 비해 대부분의 용도에 일반적으로 en.wikipedia.org/wiki/Well_equidistributed_long-period_linear
야리 Komppa

5

다음은 Chris Crawford (Atari가 분명히 사용)가 언급 한 'A Graphics Trick'입니다.

LDA FIRST
EOR SECOND
AND CONTROL
EOR SECOND
STA OUTPUT

설명을 보려면 전체 기사 를 읽으십시오 .


1
그 링크는 이제 끊어 졌으므로 여기에 설명이 도움이 될 것입니다.
finnw

감사. 그는 사라져 다시 웹 사이트를 변경했습니다. 링크를 업데이트했습니다.
Anthony

4

어떤 이유로 사람들은 종종 게임에서 디자인 패턴의 힘을 과소 평가합니다. 게임에 성공한 거의 모든 단일 GoF 패턴을 보았습니다.


1
게임 프로그래밍에서 내가 좋아하는 것 중 하나는 표준 GoF 방식의 "정확성"에서 벗어나 순수한 사랑스러운 속도에 집중하는 것입니다! 즉, 좋은 것보다 더 해로운 게임에서 MVC의 많은 나쁜 구현을 보았습니다.
Iain

디자인 패턴이 그 자리에 있다고 생각합니다. 그러나 게임에서는 그리 많지 않습니다.
blissfreak

@blissfreak : 게임 프로그래밍에 특별한 패턴은 없지만 패턴이 일반적이지 않은 와일드 웨스트로 만듭니다. 그것들은 엄청나게 일반적이며 여기 에 몇 가지 예가 있습니다.
Steven Evers

4

Math.atan2 ()는 모든 trig와 함께 매우 유용합니다.


으악! 나는 많은 3D를 해왔고 실제로는 필요하지 않았습니다.
Skizz

+1, x + y 벡터 컴포넌트에서 라디안 방향으로가는 유일한 방법입니다.
RCIX

1
@RCIX : 내 요점은 변환이 필요하지 않다는 것입니다. 즉 (x, y)-> 각도, 각도 문제에 대한 벡터 솔루션이 있습니다.
Skizz

6
나는 실제로 표준 라이브러리 함수를 "gem"이라고 부르지 않을 것이다.

1
@ 스키즈 : 아마도 3d에 대한 것이지만 정규화 된 벡터를 가져 와서 라디안 방향 값을 추출하는 다른 방법은 없습니다. 2D 게임에서 큰 가치가 있습니다.
RCIX

3

위 ... 피타고라스의 보석에 추가하려면
항상 사람들에게 3D 프로그래밍을위한 그들 만 알 필요가 없다는 것을 :
- ^ 2 + B ^ 2 = C ^ 2
- soscastoa (죄 = 반대면 / 경 사진면, COS = 부착면을 / 경사면, tan = 대향면 / 부착면)-a
. b = | a | * | b | * cos alpha
-a * b = | a | * | b | * sin alpha * 단위 벡터
게임 개발에서 발생하는 거의 모든 3D (또는 2D) 문제를 해결할 수 있습니다 (4 가지 규칙).
물론, 더 좋은 방법이 있지만, 이것으로 모든 것을 해결할 수 있습니다-나는 알아야 할 것은, 나는 경력에 기초한 핵입니다.


5
re : soscastoa 나는 대부분의 사람들이 sohcahtoa ( '경사면이 더 명확하지 않은 경우,'히포 텐스 (hypotenuse) ')로 더 구체적으로'경사면 '을 대체한다고 알고 있다고 생각합니다. 혀에서 더 쉽게 흘러 나와 기억하기 쉽다고 생각합니다.
Asmor

1
나는 중등 학교 (고등학생 연령)가 내 두뇌에 각인되어 있기 때문에 항상 '그의 낙타와 울부 짖는 늙은 아랍 앉아'를 선호합니다.
George Duckett

도있다 " S 오메 O LD H ippy C 화염 차 H 광고 T는 찢어 O N A는 CID"
blissfreak

3

내가 가장 좋아하는 것 중 하나는 Michael Abrash " The Zen of Code Optimization" 에서 'Life'의 어셈블리 언어 버전과이를 최적화하는 전체 설명입니다 .

나는 보석을 코딩하는 사람에게 그의 책을 추천합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.