Какие ваши любимые игровые жемчужины кодирования? [закрыто]


24

Я начну с « Быстрого обратного квадратного корня» Джона Кармака в 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
На самом деле это не вопрос - по крайней мере, вы можете объявить это вики-страницей сообщества ...
Рэйчел Блум

Готово, сообщество.
Гак

3
Да пошло оно! просто используйте любой код, созданный замечательным JC!
Адам Нейлор

3
Кстати, обратите внимание, что в функции быстрого обратного квадратного корня есть более точное «магическое число»: 0x5f375a86 ( en.wikipedia.org/wiki/… )
Ricket

8
Также обратите внимание, что это не Джона Кармака.
Кай

Ответы:


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

Я до сих пор не могу поверить, сколько раз я использовал теорему Пифагора в своем игровом коде. Для меня эта простая формула является жемчужиной в разработке игр.

а ^ 2 + б ^ 2 = с ^ 2
(источник: mathurl.com )

или

альтернативный текст
(источник: mathurl.com )

и когда имеет значение только относительное расстояние, его можно использовать без дорогостоящей операции с квадратным корнем

альтернативный текст
(источник: mathurl.com )


Ну, если честно, пифагорейская математика используется ВСЕМ над игровым кодом, особенно движками, такими как физический код, код рендеринга, ИИ.
Ник Бедфорд

1
Правда. Вот почему это драгоценный камень. ;)
MrValdez

4
Интересный вариант, когда вы заботитесь только об относительных расстояниях. Тогда вы можете пропустить потенциально дорогой sqrtвызов и просто вычислить distance2 = x^2 + y^2.
mmyers

@mmyers - еще одна замечательная вещь: если вы работаете в пространстве x ^ 2, расстояние не просто относительное.
Стивен Эверс

Спасибо, что упомянули бит относительного расстояния. Я видел слишком много ненужных операций с квадратным корнем, так же как люди, использующие A *, когда они должны использовать что-то менее точное.
Рикет

13

Самым большим из них было чтение о системе GameObject Скотта Биласа. Несмотря на то, что я не использую систему баз данных, как он, я остановил создание 6-уровневых деревьев наследования и создал систему компонентов, которая намного более управляема и пригодна для повторного использования.


10

Я должен пойти с устройством Даффа . Это был первый блок кода, который буквально заставил мою челюсть упасть. "Вы можете сделать это?!?"


О, мой бог. Очки! Они ничего не делают!
Рауль

Вложенное «do-while» внутри «switch-case» всегда заставляет меня моргать. Даже 20 лет спустя ...
Андреас

1
-1. Мне не нравится этот Сегодня это не очень полезно (вы бы использовали его memcpy, если хотите, чтобы другие люди могли читать ваш код)
bobobobo

1
@JoeWreschnig, почему бы и нет? Memcpy всегда будет более читабельным, переносимым и, вероятно, более оптимизированным.
kaoD

1
@kaoD: Потому что memcpy не эквивалентен устройству Даффа - не имеет значения, насколько «читаемым, переносимым и, вероятно, более оптимизированным» является, если он не делает то же самое! Современные трубопроводы CPU, вероятно, лучше без устройства Даффа , чем с ним из - за предсказания ветвлений и кэширования команд, но это не имеет ничего общего с memcpy.

7

Небольшой фрагмент C / C ++ из игры, которую я помог написать много лет назад:

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

В моей первой игре ( этой ) мне нужно было получить доступ к более чем 1 МБ ОЗУ, и, поскольку до появления Интернета у меня не было документации по XMS и EMS, которую приложения DOS использовали для доступа к дополнительной ОЗУ.

Итак, я закончил тем, что использовал небольшой «черный ход», который был представлен в 386 в отношении сегментных регистров. Обычно в реальном режиме адрес рассчитывается как seg*16+offограничение, которое ограничивает вас до 1 МБ.

Однако вы можете переключиться в защищенный режим, настроить сегмент по адресу 4Mb, переключиться назад и при условии, что вы не записали в регистр сегмента (что было в порядке, поскольку DOS использовала только регистры сегмента 8086), вы могли получить доступ ко всему 4Mb как плоское адресное пространство. Возврат в реальный режим был необходим, если вы хотите использовать службы DOS.

Также не было много доступных расширителей DPMI.


Почти работает в C # (нужно объявить тип делегата и вставить хотя бы одно приведение)
finnw

Вы имеете ввиду с 32-битными режимами адресации в реальном режиме? (т.е. требуется префикс размера адреса). Вы уверены, что было необходимо установить дескриптор сегмента, и что он фактически не использовал регистр сегмента как обычный 16 * FS +? Я не думал, что у сегментов даже были ограничения в 16-битном режиме, только базовый адрес (16 * их значение), поэтому вы не могли просто установить FS на что-то в 16-битном режиме и использовать [fs:esi]или что-либо еще, чтобы получить доступ к тому, что вы разыскивается?
Питер Кордес

Я не пробовал этого и не писал никакого реального кода для 16-битного режима, просто 32- и 64-битного asm, но это звучит странно. Хм, хотя правдоподобно. Современные процессоры определенно кэшируют содержимое сегментов внутри и перезагружают эти кэши только при записи в регистры сегментов, так что, возможно, именно так он сохранил базовый + предел защищенного режима (если это действительно так, и вы использовали не просто 4 МБ, начиная с 16 * FS).
Питер Кордес

5

Лично я большой поклонник Mersenne Twister для предсказуемых случайных чисел, особенно если вам нужно создать несколько экземпляров Rand

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

Вот один из упомянутых Крисом Кроуфордом (и, по-видимому, используемый Atari), который он называет «Графическим трюком»:

LDA FIRST
EOR SECOND
AND CONTROL
EOR SECOND
STA OUTPUT

Прочитайте полную статью для объяснения.


1
Эта ссылка теперь не работает, поэтому здесь можно получить объяснение.
finnw

Спасибо. Он ушел и снова изменил свой сайт. Я обновил ссылку.
Энтони,

4

Почему-то люди часто недооценивают силу шаблонов дизайна в играх. Я видел почти каждый шаблон GoF, успешно примененный к играм.


1
Одна из вещей, которые мне нравятся в программировании игр, - это отойти от стандартного способа «правильности» GoF и просто сосредоточиться на чистой прекрасной скорости! Тем не менее, я видел много плохих реализаций MVC в играх, которые приносят больше вреда, чем пользы.
Иан

Я думаю, что шаблоны дизайна имеют свое место. Не так много в играх, хотя.
блаженство

@blissfreak: В программировании игр нет ничего особенного, что делает его своего рода диким западом, где паттерны не распространены. Они смехотворно распространены, и вот несколько примеров.
Стивен Эверс

4

Math.atan2 () чрезвычайно полезен (вместе со всеми триггерами).


Это, черт возьми! Я сделал много 3D и никогда не нуждался в этом.
Skizz

+1, это единственный способ перейти от векторных компонентов x + y к радианам.
RCIX

1
@RCIX: Я хочу сказать, что это преобразование не нужно, то есть (x, y) -> угол, есть векторное решение любой проблемы угла.
Skizz

6
Я бы не назвал голую стандартную библиотечную функцию "драгоценным камнем".

1
@Skizz: Может быть, для 3d, но я не знаю другого способа взять нормализованный вектор и извлечь значение направления радиан. Который как большое значение в 2D-играх.
RCIX

3

Чтобы добавить к пифагорейскому драгоценному камню выше ...
Я всегда говорю людям, что для трехмерного программирования им нужно знать только:
- a ^ 2 + b ^ 2 = c ^ 2
- soscastoa (sin = противоположная сторона / наклонная сторона, cos = присоединенная сторона / наклонная сторона, загар = противоположная сторона / прикрепленная сторона)
- a. b = | a | * | б | * cos alpha
- a * b = | a | * | б | * sin alpha * unit vector.
Он может решить практически любую 3d (или 2d) проблему, с которой вы сталкиваетесь при разработке игры - 4 правила.
Конечно, есть более приятные способы, но это может решить их все - я должен знать, я хак, который основал свою карьеру на них.


5
re: soscastoa Я думаю, что большинство людей знают это как «sohcahtoa» (заменяя «наклонную сторону» на более конкретную, хотя, по общему признанию, более туманную, «гипотенузу»). Легче стекает с языка, и я думаю, таким образом, легче запомнить.
Асмор

1
Я всегда предпочитаю «Старый араб сидел на верблюде и воет», так как со средней школы (старшего школьного возраста) он запечатлелся в моем мозгу.
Джордж Дакетт

Там также « S Оме O л.д. H Ippy C AME й H объявления T разорвал O п ИДС»
blissfreak

3

Одна из моих любимых - версия «Life» на ассемблере и полное описание ее оптимизации в « Дзен оптимизации кода» Майкла Абраша.

Я бы порекомендовал любую из его книг всем, кто ищет кодовые драгоценные камни.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.