Зникає в старих іграх. Потрібна допомога, щоб з'ясувати, як алгоритм був виведений


12

Вибачте, це питання трохи езотеричне, але я просто не можу це вийти з голови!

Я дивлюся на алгоритм зникання, який використовується в аркадній грі DoDonPachi (а також у багатьох інших старих іграх):

введіть тут опис зображення

Я написав сценарій пітона, щоб виділити кілька пікселів і відстежувати їх протягом тривалості зникнення. Ось представницький зразок результатів. Перший рядок кожної групи є початковим значенням кольору, тоді як кожен наступний рядок - це різниця між значенням кольору поточного кадру та значенням кольору попереднього кадру.

Starting Value: (132, 66, 189)
Frame 1:    [9, 9, 8]
Frame 2:    [8, 8, 8]
Frame 3:    [8, 8, 8]
Frame 4:    [8, 8, 9]
Frame 5:    [9, 9, 8]
Frame 6:    [8, 8, 8]
Frame 7:    [8, 8, 8]
Frame 8:    [8, 8, 9]
Frame 9:    [9, 0, 8]
Frame 10:   [8, 0, 8]
Frame 11:   [8, 0, 8]
Frame 12:   [8, 0, 9]
Frame 13:   [9, 0, 8]
Frame 14:   [8, 0, 8]
Frame 15:   [8, 0, 8]
Frame 16:   [8, 0, 9]
Frame 17:   [0, 0, 8]
Frame 18:   [0, 0, 8]
Frame 19:   [0, 0, 8]
Frame 20:   [0, 0, 9]
Frame 21:   [0, 0, 8]
Frame 22:   [0, 0, 8]
Frame 23:   [0, 0, 8]
Frame 24:   [0, 0, 0]
Frame 25:   [0, 0, 0]
Frame 26:   [0, 0, 0]
Frame 27:   [0, 0, 0]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Starting Value: (132, 0, 0)
Frame 1:    [9, 0, 0]
Frame 2:    [8, 0, 0]
Frame 3:    [8, 0, 0]
Frame 4:    [8, 0, 0]
Frame 5:    [9, 0, 0]
Frame 6:    [8, 0, 0]
Frame 7:    [8, 0, 0]
Frame 8:    [8, 0, 0]
Frame 9:    [9, 0, 0]
Frame 10:   [8, 0, 0]
Frame 11:   [8, 0, 0]
Frame 12:   [8, 0, 0]
Frame 13:   [9, 0, 0]
Frame 14:   [8, 0, 0]
Frame 15:   [8, 0, 0]
Frame 16:   [8, 0, 0]
Frame 17:   [0, 0, 0]
Frame 18:   [0, 0, 0]
Frame 19:   [0, 0, 0]
Frame 20:   [0, 0, 0]
Frame 21:   [0, 0, 0]
Frame 22:   [0, 0, 0]
Frame 23:   [0, 0, 0]
Frame 24:   [0, 0, 0]
Frame 25:   [0, 0, 0]
Frame 26:   [0, 0, 0]
Frame 27:   [0, 0, 0]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Starting Value: (165, 156, 222)
Frame 1:    [9, 8, 8]
Frame 2:    [8, 8, 8]
Frame 3:    [8, 8, 8]
Frame 4:    [8, 9, 9]
Frame 5:    [9, 8, 8]
Frame 6:    [8, 8, 8]
Frame 7:    [8, 8, 8]
Frame 8:    [8, 9, 9]
Frame 9:    [9, 8, 8]
Frame 10:   [8, 8, 8]
Frame 11:   [8, 8, 8]
Frame 12:   [8, 9, 9]
Frame 13:   [9, 8, 8]
Frame 14:   [8, 8, 8]
Frame 15:   [8, 8, 8]
Frame 16:   [8, 9, 9]
Frame 17:   [9, 8, 8]
Frame 18:   [8, 8, 8]
Frame 19:   [8, 8, 8]
Frame 20:   [8, 0, 9]
Frame 21:   [0, 0, 8]
Frame 22:   [0, 0, 8]
Frame 23:   [0, 0, 8]
Frame 24:   [0, 0, 9]
Frame 25:   [0, 0, 8]
Frame 26:   [0, 0, 8]
Frame 27:   [0, 0, 8]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Starting Value: (156, 90, 206)
Frame 1:    [8, 8, 8]
Frame 2:    [8, 8, 9]
Frame 3:    [8, 8, 8]
Frame 4:    [9, 9, 8]
Frame 5:    [8, 8, 8]
Frame 6:    [8, 8, 9]
Frame 7:    [8, 8, 8]
Frame 8:    [9, 9, 8]
Frame 9:    [8, 8, 8]
Frame 10:   [8, 8, 9]
Frame 11:   [8, 8, 8]
Frame 12:   [9, 0, 8]
Frame 13:   [8, 0, 8]
Frame 14:   [8, 0, 9]
Frame 15:   [8, 0, 8]
Frame 16:   [9, 0, 8]
Frame 17:   [8, 0, 8]
Frame 18:   [8, 0, 9]
Frame 19:   [8, 0, 8]
Frame 20:   [0, 0, 8]
Frame 21:   [0, 0, 8]
Frame 22:   [0, 0, 9]
Frame 23:   [0, 0, 8]
Frame 24:   [0, 0, 8]
Frame 25:   [0, 0, 8]
Frame 26:   [0, 0, 0]
Frame 27:   [0, 0, 0]
Frame 28:   [0, 0, 0]
Frame 29:   [0, 0, 0]

Як бачимо, з кожного кольорового компонента в кожному кадрі віднімається або 8, або 9. Крім того, 9 завжди з’являється три кадри після 8, навіть незважаючи на те, що початкове віднімане значення відрізняється для кожної кольорової складової. Зауважимо також, що кожен кольоровий компонент досягає 0 (тобто чорного) з різницею 8 або 9, а не якийсь довільний залишок. Це означає, що віднятий цикл значень 8,8,8,9 ніколи не порушується! (Цей алгоритм був, ймовірно, написаний для того, щоб останній кадр вицвітання був таким же рівним, як і інші.)

Тепер це спантеличує мене. Згідно з моїми підрахунками, якщо ви реверсуєте процес - тобто візьміть цикл 8,8,8,9 і підсумуєте його, щоб знайти всі можливі комбінації в 29 кадрах - ви отримаєте лише 52 унікальних числа. Але як це буває, кожен кольоровий компонент є учасником цього набору! Це означає, що або кольори були вибрані спеціально для цього алгоритму вицвітання (малоймовірно), або алгоритм вицвітання був розроблений навколо кольорової палітри гри. Але як на землі хтось міг зрозуміти, що якщо ви візьмете 8,8,8,9, змініть цикл відповідним чином і продовжуєте віднімати цифри від кожного кольорового компонента у вашій палітрі, ви зрештою досягнете 0 для кожного кольору? ! Повинно бути якийсь математичний трюк, який мені не вистачає. Що це?


2
Чому б просто не пограти з альфою? Ось так я і роблю для анімації з вимкненням / виведенням.
DogDog

Я не намагаюся копіювати алгоритм у власному коді, просто намагаюся розібратися, як він був виведений.
Архагон

Я відчуваю, що це те, що ви сказали, кольори були вибрані на основі послідовності 8,8,8,9. Враховуючи таку послідовність, вони мали можливість обрати один з 52 * 52 * 52 кольорів. Цікава примітка: якщо ви почнете з 0 і додасте послідовність 8,8,8,9, ви отримаєте 255. Що дозволяє їм використовувати чорно-білі.
Луїс Естрада

@Apoc: Стиль вицвітання помітно відрізняється від альфа-в’янення. Подивіться, як кожне значення кольору зменшується на фіксовану кількість (шаблон числа), а не на відсоток від його початкового значення? Це означає, що існують обставини, за яких ви, можливо, віддасте перевагу використовувати його у порівнянні з більш поширеними методами. Ретро стиль, наприклад.
AlbeyAmakiir

Відповіді:


20

Насправді, за схемою 8-8-8-9 є проста логіка. Це виникає природно, якщо ви використовуєте лише 32 рівні інтенсивності (5 біт на компонент), але хочете відобразити це на 8-бітовому дисплеї на компонент.

Подумайте, чи є у вас 5-бітний рівень інтенсивності та хочете розширити його до 8 біт. Найпростішим, що можна зробити, було б просто зрушити ліворуч і залишити низький три біт нуля. Проблема полягає в тому, що вона не йде зовсім до чистого білого. Найвищий рівень інтенсивності, який ви можете досягти, становить 11111000 або 248. Отже, ви не використовуєте повний діапазон інтенсивності 8-бітного дисплея.

Дійсно, те, що ви хочете зробити, - це такий розрахунок, як intensity8 = round(intensity5 * 255.0 / 31.0)масштаб масштабу [0, 31] до [0, 255]. Однак є акуратний трюк, щоб досягти цього без будь-якої математики з плаваючою комою чи діленнями: встановіть три низькі три біта, рівні три високих біта. Тобто для перетворення інтенсивності з 5-бітного в 8-бітне, що ви робите

intensity8 = (intensity5 << 3) | (intensity5 >> 2);

Тоді інтенсивність 11111 буде відповідати 11111111 (31 карта до 255), і проміжні результати також зроблять щось здорове, наприклад 10000 -> 10000100 (16 -> 132).

Цей набір чисел саме те, що у вас є. Беручи червоний компонент вашого першого прикладу, у вас є:

132    10000100
123    01111011
115    01110011
107    01101011
 99    01100011
 90    01011010
 82    01010010
 74    01001010

Зауважте, як низькі три біти завжди рівні трьом бітам. Різниця 9 виникає, коли і біт 0, і біт 3 перевертаються одночасно.

Я не впевнений, чому 5-бітні рівні інтенсивності були б використані в цій ситуації; можливо, це була межа апаратних засобів аркадної машини? Примітно, що 5-бітове значення RGB становить 15 біт, що чудово вписується в 16-бітове слово. У будь-якому випадку, це пояснює дивну схему 8-8-8-9.


1
16 біт на піксель називали "High Color". (Це приблизно все, що я пам’ятаю про це) en.wikipedia.org/wiki/High_color
буксири

1
Після швидкої поїздки по wikipedia, Sega Saturn ( en.wikipedia.org/wiki/Sega_Saturn#Video ) згадує 15-бітний кольоровий режим відображення, а також GameBoy Advance ( en.wikipedia.org/wiki/Game_Boy_Advance )
буксири

1
Це геніально! Це все має сенс зараз. Дякую!
Архагон

У грі, мабуть, було 16-бітове забарвлення, і художники, ймовірно, хотіли витіснити більше кольорів зі своєї гри за рахунок прозорості, надавши кольорову схему RGBA 5551.
Архагон

0

Ви повинні заглянути в режим 13h або 256 кольорову палітру. Тоді у вас було стільки кольорів і те, що ви робили, возився з усією палітрою, оскільки не міг обчислити нові кольори, яких у ній не було.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.