Đá quý mã hóa trò chơi cụ thể yêu thích của bạn là gì? [đóng cửa]


24

Tôi sẽ bắt đầu với Rễ vuông nghịch đảo nhanh của John Carmack trong Quake III:

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
Đó thực sự không phải là một câu hỏi - ít nhất, bạn có thể tuyên bố đây là trang wiki cộng đồng ...
Rachel Blum

Xong, cộng đồng đóng băng.
gak

3
Kệ đời nó! chỉ cần đi với bất kỳ và tất cả các mã được tạo ra bởi JC tuyệt vời!
Adam Naylor

3
Nhân tiện, xin lưu ý rằng có một "số ma thuật" chính xác hơn để sử dụng trong hàm căn bậc hai nghịch đảo nhanh: 0x5f375a86 ( en.wikipedia.org/wiki/ Lỗi )
Ricket

8
Cũng lưu ý rằng đó không phải là John Carmack.
Kaj

Câu trả lời:


25

Hàm 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;
}

Nó nhận một giá trị, chuyển đổi nó thành một tỷ lệ trong một phạm vi và sau đó chia tỷ lệ tương đối với một phạm vi khác. Giống như một lerp đôi.

Bạn có thể sử dụng nó để bình thường hóa công cụ:

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

Hoặc bạn có thể chuyển đổi từ phạm vi này sang phạm vi khác:

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

Lưu ý trong ví dụ thứ hai rằng phạm vi ngoài là một thứ tự khác với phạm vi.

Nó trông không giống lắm, nhưng tôi sử dụng fella nhỏ này ở khắp mọi nơi.


14

Tôi vẫn không thể tin được bao nhiêu lần tôi đã sử dụng Định lý Pythagore trong mã trò chơi của mình. Đối với tôi, công thức đơn giản này là một viên ngọc quý trong phát triển trò chơi.

a ^ 2 + b ^ 2 = c ^ 2
(nguồn: mathurl.com )

hoặc là

văn bản thay thế
(nguồn: mathurl.com )

và khi chỉ có vấn đề khoảng cách tương đối, nó có thể được sử dụng mà không cần hoạt động căn bậc hai đắt tiền

văn bản thay thế
(nguồn: mathurl.com )


Thành thật mà nói, toán học Pythagore được sử dụng TẤT CẢ trên mã trò chơi, đặc biệt là các công cụ, như mã vật lý, mã kết xuất, AI.
Nick Bedford

1
Thật. Đó là lý do tại sao nó là một viên đá quý. ;)
MrValdez

4
Một biến thể thú vị là khi bạn chỉ quan tâm đến khoảng cách tương đối . Sau đó, bạn có thể bỏ qua sqrtcuộc gọi đắt tiền và chỉ cần tính toán distance2 = x^2 + y^2.
mmyer

@mmyer - Một điều tuyệt vời khác: nếu bạn đang làm việc trong không gian x ^ 2, khoảng cách không chỉ là tương đối.
Steven Evers

Cảm ơn bạn đã đề cập đến bit khoảng cách tương đối. Tôi đã thấy quá nhiều thao tác căn bậc hai không cần thiết, giống như mọi người sử dụng A * khi họ nên sử dụng một cái gì đó ít chính xác hơn.
Ricket

13

Cuốn lớn nhất từ ​​tôi là đọc về hệ thống GameObject của Scott Bilas. Mặc dù tôi không sử dụng hệ thống cơ sở dữ liệu như anh ta, nhưng nó đã ngăn tôi tạo cây thừa kế cấp 6 và khiến tôi tạo ra một hệ thống thành phần dễ quản lý và tái sử dụng hơn nhiều.


10

Tôi phải đi với thiết bị của Duff . Đó là khối mã đầu tiên thực sự khiến hàm của tôi giảm xuống. "Bạn có thể làm điều đó?!?"


Chúa ơi. Các kính bảo hộ! Họ không làm gì cả!
Raoul

"Do-while" lồng nhau bên trong "hộp công tắc" luôn khiến tôi chớp mắt. Thậm chí 20 năm sau ...
Andreas

1
-1. Tôi không thích cái này. Hôm nay nó không hữu dụng lắm (bạn sẽ sử dụng memcpythay vào đó, nếu bạn muốn người khác có thể đọc mã của bạn)
bobobobo

1
@JoeWreschnig tại sao không? Memcpy sẽ luôn dễ đọc hơn, dễ mang theo hơn và có thể được tối ưu hóa hơn.
kaoD

1
@kaoD: Bởi vì memcpy không tương đương với thiết bị của Duff - không quan trọng là "có thể đọc, di động và có thể được tối ưu hóa hơn" như thế nào nếu nó không làm điều tương tự! Đường ống CPU hiện đại có thể sẽ làm tốt hơn mà không cần thiết bị của Duff hơn với nó vì dự đoán rẽ nhánh và hướng dẫn bộ nhớ đệm, nhưng điều đó có để làm với memcpy.

7

Một đoạn C / C ++ nhỏ từ một trò chơi tôi đã giúp viết lại nhiều năm trước:

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

Trong trò chơi đầu tiên của tôi ( cái này ) tôi cần truy cập hơn 1Mb RAM, và, trước khi internet tắt, tôi không có tài liệu nào cho XMS và EMS mà các ứng dụng DOS sử dụng để truy cập thêm RAM.

Vì vậy, tôi đã kết thúc bằng cách sử dụng một 'cửa hậu' nhỏ đặc trưng trong 386 liên quan đến các thanh ghi phân khúc. Thông thường, ở chế độ thực, địa chỉ được tính theo seg*16+offgiới hạn của bạn là 1Mb.

Tuy nhiên, bạn có thể chuyển sang chế độ được bảo vệ, thiết lập phân đoạn để giải quyết 4Mb, chuyển lại và miễn là bạn không ghi vào thanh ghi phân đoạn (điều này ổn vì DOS chỉ sử dụng các thanh ghi phân đoạn 8086), bạn có thể truy cập toàn bộ 4Mb như một không gian địa chỉ phẳng. Việc quay trở lại chế độ thực là cần thiết nếu bạn muốn sử dụng các dịch vụ DOS.

Không có nhiều bộ mở rộng DPMI có sẵn.


Hầu hết các công trình trong C # (bạn cần phải khai báo một loại đại biểu và chèn ít nhất một diễn viên)
finnw

Ý bạn là với chế độ địa chỉ 32 bit ở chế độ thực? (tức là yêu cầu tiền tố kích thước địa chỉ). Bạn có chắc chắn cần phải thiết lập một bộ mô tả phân khúc và nó thực sự không sử dụng đăng ký phân đoạn như 16 * FS + bình thường không? Tôi không nghĩ các phân đoạn thậm chí có giới hạn ở chế độ 16 bit, chỉ là địa chỉ cơ sở (giá trị 16 * của chúng), vì vậy bạn không thể đặt FS ở chế độ 16 bit và sử dụng [fs:esi]hoặc bất cứ điều gì để truy cập bất cứ điều gì bạn truy nã?
Peter Cordes

Tôi đã không thử điều này hoặc viết bất kỳ mã thực nào cho chế độ 16 bit, chỉ là 32 và 64 bit asm, nhưng nghe có vẻ lạ. Hmm, hợp lý mặc dù. Các CPU hiện đại chắc chắn lưu trữ nội bộ phân đoạn nội bộ và chỉ tải lại các bộ đệm đó khi bạn ghi vào regs phân đoạn, vì vậy có thể đó là cách nó giữ cơ sở + chế độ được bảo vệ (nếu đó thực sự là những gì đã xảy ra và bạn không sử dụng 4MB bắt đầu từ 16 * FS).
Peter Cordes

5

Cá nhân tôi là một fan hâm mộ lớn của Mersenne Twister cho các số ngẫu nhiên có thể dự đoán được, đặc biệt nếu bạn cần tạo một vài trường hợp khác nhau của Rand

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


Mersenne Twister là tốt theo nghĩa nó là một trình tạo số ngẫu nhiên tốt, nhưng nó không đặc biệt thanh lịch hoặc mát mẻ (hoặc nhanh hoặc dễ thực hiện). Đối với điều đó, bạn có thể muốn xem en.wikipedia.org/wiki/Rule_30 .

1
WELL thường tốt hơn MT cho hầu hết các mục đích sử dụng .. vi.wikipedia.org/wiki/Well_equidistribution_long- period_linear
Jari Komppa

5

Đây là một đề cập của Chris Crawford (và dường như được sử dụng bởi Atari) mà anh gọi là 'Thủ thuật đồ họa':

LDA FIRST
EOR SECOND
AND CONTROL
EOR SECOND
STA OUTPUT

Đọc toàn bộ bài viết để được giải thích.


1
Liên kết đó hiện đã bị hỏng, vì vậy nó sẽ giúp có một lời giải thích ở đây.
vây

Cảm ơn. Anh ấy đi và thay đổi trang web của mình một lần nữa. Tôi đã cập nhật các liên kết.
Anthony

4

Vì một số lý do, mọi người thường đánh giá thấp sức mạnh của các mẫu thiết kế trong các trò chơi. Tôi đã thấy gần như mọi mô hình GoF duy nhất được áp dụng thành công cho các trò chơi.


1
Một trong những điều tôi thích về lập trình trò chơi là thoát khỏi cách "chính xác" của GoF và chỉ tập trung vào tốc độ đáng yêu thuần túy! Điều đó nói rằng, tôi đã thấy rất nhiều triển khai xấu của MVC trong các trò chơi gây hại nhiều hơn là tốt.
Iain

Tôi nghĩ rằng các mẫu thiết kế có vị trí của họ. Không quá nhiều trong các trò chơi, mặc dù.
blissfreak

@blissfreak: Không có gì đặc biệt về lập trình trò chơi khiến nó trở thành một loại miền tây hoang dã nơi các mô hình không phổ biến. Chúng rất phổ biến và đây là một số ví dụ.
Steven Evers

4

Math.atan2 () cực kỳ hữu ích (cùng với tất cả các trig).


Nó là, trời ạ! Tôi đã thực hiện rất nhiều 3D và không bao giờ thực sự cần nó.
Skizz

+1, đó là cách duy nhất để đi từ các thành phần vectơ x + y sang hướng radian.
RCIX

1
@RCIX: Quan điểm của tôi là sự biến đổi đó là không cần thiết, tức là (x, y) -> góc, có một giải pháp vectơ cho bất kỳ vấn đề góc nào.
Skizz

6
Tôi thực sự sẽ không gọi một chức năng thư viện tiêu chuẩn trần là "đá quý".

1
@Skizz: Có thể cho 3d, nhưng tôi không biết cách nào khác để lấy một vectơ chuẩn hóa và trích xuất giá trị hướng radian. Đó là một giá trị tốt trong các trò chơi 2D.
RCIX

3

Để thêm vào đá quý pythagore ở trên ...
Tôi luôn nói với mọi người rằng để lập trình 3d họ chỉ cần biết:
- a ^ 2 + b ^ 2 = c ^ 2
- soscastoa (sin = phía đối diện / bên dốc, cos = bên gắn liền / bên dốc, tan = bên đối diện / bên gắn liền)
- a. b = | a | * | b | * cos alpha
- a * b = | a | * | b | * sin alpha * vector đơn vị
Nó có thể giải quyết khá nhiều bất kỳ vấn đề 3d (hoặc 2d) nào bạn gặp phải trong quá trình phát triển trò chơi - 4 quy tắc.
Chắc chắn, có những cách đẹp hơn, nhưng điều này có thể giải quyết tất cả - tôi nên biết, tôi là một hack dựa trên sự nghiệp của họ.


5
re: soscastoa Tôi nghĩ rằng hầu hết mọi người đều biết rằng như vậy sohcahtoa (thay thế 'bên dốc' bằng cách cụ thể hơn, nếu thừa nhận là tối nghĩa hơn, 'hypotenuse'). Chảy lưỡi dễ dàng hơn, và tôi nghĩ do đó dễ nhớ hơn.
Asmor

1
Tôi sẽ luôn thích 'Sat Arab cũ trên lạc đà và hú', từ khi học cấp hai (tuổi trung học), nó đã in sâu vào não tôi.
George Duckett

Ngoài ra còn có " S ome O ld H ippy C ame A nd H ad T ripped O n A cid"
blissfreak

3

Một trong những mục yêu thích của tôi là phiên bản ngôn ngữ lắp ráp của 'Cuộc sống' và toàn bộ mô tả về tối ưu hóa nó, trong " Thiền tối ưu hóa mã" của Michael Abrash.

Tôi muốn giới thiệu bất kỳ cuốn sách nào của anh ấy cho bất cứ ai tìm kiếm đá quý mã hóa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.