Як втілити подорож у грі?


10

Мені було цікаво, як втілити подорож у часі в гру. Нічого супер складного, просто переворот часу, як, наприклад, у Braid, де користувач може перемотати назад / перемотати час на 30 секунд чи що завгодно.

Я багато шукав по Інтернету, але мої результати зазвичай називали використання часу, як, наприклад, "це 3:00", або таймер тощо.

Єдине, про що я міг придумати, - це використовувати 2 масиви, один для x-позиції гравця, а другий для y-позиції гравця, а потім повторення цих масивів та розміщення персонажа в цій позиції під час перемотування назад / швидкого перемотки вперед. Чи може це спрацювати? Якби це спрацювало, яким би мав бути масив і як часто я повинен зберігати х і у гравця? Якщо це не працює, що ще я можу спробувати?

Спасибі заздалегідь!


11
Ви не читаєте новини ( ust.hk/eng/news/press_20110719-893.html )? Вони щойно показали, що подорож у часі неможливий. Тому кодувати неможливо.

Потрібно продумати можливу семантику для подорожі у часі, лише після цього ви можете почати думати про реалізацію.
Paŭlo Ebermann


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

5
import universal.back2future.FluxCapacitor;
поштовх

Відповіді:


6

Ідея масиву в значній мірі реалізована в Braid. Коли єдині речі, що діють на персонаж, - це гравітація, введення з клавіатури / джойстика та інші символи, вам потрібно лише зберігати положення та швидкість на кожному кроці, щоб знати все важливе про цього персонажа. Якщо ви зберігаєте 10 знімків в секунду на персонаж, то це все ще менше 50 Кб за хвилину історії одного персонажа - це легко керується в більшості систем, і ви можете знайти способи, більш ефективні, ніж цей.


Це вірний шлях. Наприклад, зберігайте активні команди: натискання клавіш із позначками часу. Ви можете екстраполювати більшість інших поведінки, якщо система детермінована. Відстежувач 10 кадрів в секунду добре підходить для системи перемотування назад, ще менше може бути прийнятним, якщо фактичні команди зберігаються, фактично стан або зміна стану об'єктів.
кармінгтон

4

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

Але я думаю, що ваша ідея масиву також звучить.


Напевно, це не чудова ідея - окрім того, що є більш об'ємною пам'яттю (кожного разу, коли ви додаєте швидкість сутності до її позиції, вам потрібно зберігати це як "дію") , вона в значній мірі вимагає математики з фіксованою точкою, оскільки якщо ви використовуєте плаваючий - точка для ваших позицій / швидкості (x+v)-vможе не дорівнювати x.
BlueRaja - Danny Pflughoeft

1
@BlueRaja - Не бачиш, де цей підхід буде обтяжливим для пам’яті. При 100 FPS та зберіганні останніх 10 секунд вам потрібно зберігати 1000 n-тюпелів команд, де n - максимум 5 або близько того. Або, ще краще, ви зберігаєте лише абсолютне положення у кожному з цих кадрів, а для перемотування назад ви просто анімуєте персонажа назад по цьому шляху. Це також усуне будь-які можливі проблеми з плаваючою точкою та поверне вас саме туди, де ви почали.
Хакворт

3

Замість того, щоб мати два окремих масиви, ви, мабуть, повинні мати один клас, який описує позицію гравця (напевно, на Java вже є клас Point ... Я останнім часом хлопець C #) і використовувати один єдиний масив для утримання минулих позицій.

Потрібно встановити "буфер дзвінка", тобто, дійшовши до кінця масиву, ви повернетеся до початку масиву, перезаписавши найдавніші записи. Якщо ви подорожуєте назад у часі, відбувається навпаки (коли ви дістаєтесь до початку, обведіть до кінця).

Якщо ви хочете зберегти минулі дані на 30 секунд, вам потрібно знати частоту кадрів, якщо ви хочете попередньо виділити простір і використовувати масив фіксованого розміру. Якщо ви візуалізуєте гру зі швидкістю 10 кадрів / секунду, 30 разів, це 300 елементів.


2

GDCVault на своїй сторінці провів лекцію Джона Блоу (творця Braid ) під назвою The Implementation of Rewind in Braid за $ 3,95. Б'юсь об заклад, це інформація, яку ви хочете;)

EDIT: Напевно, на Java не буде, але ідеї мають бути дотримані.


Чи знаєте ви, чи продають вони також стенограму чи лише аудіо?
o0 '.

Я не зміг знайти нічого за допомогою швидкого пошуку сайту. Можливо, ви могли б використовувати якесь програмне забезпечення для транскрипції ?
NoobsArePeople2

1

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

Однак я б запропонував використовувати чергу для реалізації буфера. Оновити набагато дешевше, ніж масив, і вам не потрібно знати заздалегідь частоту кадрів:

update():
   time_queue.push(player.positions)
   if current_time() - start_time > n:
       queue.pop()

Це ще не враховує різну частоту кадрів або що має статися, якщо ви насправді здійснюєте будь-який час, подорожуючи часом, тому я пропоную вам зберігати штамп часу з кожним записом і перевіряти це:

update():
    time_queue.push({
        'pos': player.positions,
        'time': current_time()
    })
    first_entry = queue.peek()
    while current_time() - first_entry['time'] > n:
       queue.pop()
       first_entry = queue.peek()

Сподіваюся, це допомагає!


1

Є модель дизайну під назвою Memento , я думаю, що це відправна точка для гри, як Braid

Шаблон memento - це модель дизайну програмного забезпечення, яка забезпечує можливість відновлення об'єкта до його попереднього стану (скасування відкату).

Шаблон пам’яті використовується двома об’єктами: оригінатор та доглядач. Оригінатор - це якийсь об'єкт, який має внутрішній стан. Доглядач збирається щось зробити з оригінатором, але хоче мати можливість скасувати зміни. Доглядач спочатку запитує в оригінатора предмет пам’яті. Тоді воно робить будь-яку операцію (або послідовність операцій), яку він робив. Щоб повернутись до стану перед операціями, він повертає об'єкт memento оригінатору. Сам об’єкт пам'яті - непрозорий об’єкт (той, який доглядач не може або не повинен змінювати). Під час використання цього шаблону слід бути обережним, якщо оригінатор може змінити інші об'єкти чи ресурси - шаблон пам’яті працює на одному об’єкті.

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

Довідкова інформація тут: http://dofactory.com/Patterns/PatternMemento.aspx


2
Я не бачу, як це має допомогти. Схоже, це "миттєвий відкат", в той час як ОП просила щось гладке, як це Брейд. Може, я щось неправильно прочитав?
o0 '.

Цей шаблон не має на увазі для одного відката, наприклад, ви можете створити "часовий шкала" дій. Ось бразильський запис у блозі про використання цього шаблону: abrindoojogo.com.br/padroes-de-projeto-memento Ось приклад, зроблений у Flash: abrindoojogo.com.br/files/fasteroids.swf Переміщення: Стрілки | Стрілка: Космос | Дії назад: Backspace
Marcelo Assis

1

Для XBox360 була випущена гра, яка передбачала маніпуляцію часом. Це було посередньо, тому наразі не можу згадати назву. У будь-якому випадку в інтерв'ю з розробником для нього вони окреслили, як їм вдалося керувати часом:

Кожен X кадр (із меншими значеннями X, що призводить до більш дрібної маніпуляції), ви робите «знімок» ігрового світу в цей момент і пов’язуєте його з ігровим часом.

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

Потім ігровий світ перетворюється між знімком у поточний час та знімком X кадрів у майбутньому.

Потім, коли ви хочете повернути час, просто встановіть напрямок часу, щоб він був зворотним, щоб він був ітераційним між поточним і кадром X-знімка в минулому (відключаючи можливість створювати майбутні знімки).


+1 для точки про деталізацію знімків.
Омар Кухеджі

0

Ви можете просто ставитися до віртуального часу гри як до іншого космічного виміру. Тож подорож у часі ззовні - це простий n + 1 розмірний рух у віртуальній Всесвіті гри.

Якщо припустити деяку взаємодію з користувачем і якусь фізичну систему, яка визначає поведінку вашого Всесвіту, коли немає вводу користувача, все, що вам потрібно записати, - це вплив взаємодії користувачів (наприклад, зміни в векторах швидкості / прискорення розмірності n + 1) , оскільки ваша фізика повинна бути зворотною.

Таким чином, вам знадобиться набагато менше пам'яті, щоб обчислити стан ігрової Всесвіту в будь-який момент часу.


Як я вже згадував в іншому коментарі, фізика у відеоіграх зазвичай не(x+v)-vx
обертається

0

Скажімо, сутність має позицію швидкості, обертання, x і y. Це, прискорення, основні стани руху, значення, як би ви їх не називали. Ви можете зберегти дані двома способами:
1. Зберегти обертання, положення x і y
2. Зберегти обертання, x швидкість і швидкість y

Якщо у вас фіксована швидкість, ви також можете зберегти обертання або зберегти лише одну швидкість для обох осей.

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

Однак, використання списку об'єктів для кількох значень є необхідним. Якщо у вас є приємна система таймерів, яка, наприклад, викликає методи оновлення 20 разів за секунду, а отже, незалежна від fps, ви можете створити масив з 20 * 30 об'єктів для зберігання значень руху, необхідних вам за останні 30 секунд . Використовувати простий масив не рекомендується, оскільки вам доведеться перемістити кожен елемент, один індекс залишив кожен виклик оновлення.

Виходячи з цього, ви можете пройти список або все, що потрібно повернути назад. Якщо ви дійсно хочете отримати «реалістичний» ефект, використовуйте цю техніку для всіх рухомих об’єктів. Але це пов'язано з ігровим дизайном.

Якщо ви знищуєте предмети, не забудьте об'єднати їх, щоб не підкреслити свого акуратного друга містера Гарбіса;)

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