Bagaimana cara menerapkan perjalanan waktu ke dalam game?

10

Saya bertanya-tanya bagaimana menerapkan perjalanan waktu ke dalam game. Tidak ada yang super kompleks, hanya pembalikan waktu seperti yang ada di Braid, di mana pengguna dapat memundurkan / memajukan waktu dengan 30 detik atau apa pun.

Saya banyak mencari di web, tetapi hasil saya biasanya disebut menggunakan waktu seperti pada "ini jam 3:00" atau timer dan semacamnya.

Satu-satunya hal yang dapat saya pikirkan adalah menggunakan 2 array, satu untuk posisi x pemain dan yang lainnya untuk posisi y pemain, dan kemudian mengulangi melalui array tersebut dan menempatkan karakter pada posisi itu ketika mereka mundur / maju cepat waktu. Bisakah itu berhasil? Jika itu akan berhasil, seberapa besar array harus dan seberapa sering saya harus menyimpan x dan y pemain? Jika tidak berhasil, apa lagi yang bisa saya coba?

Terima kasih sebelumnya!

Alex
sumber
11
Apakah Anda tidak membaca berita ( ust.hk/eng/news/press_20110719-893.html )? Mereka baru saja menunjukkan bahwa perjalanan waktu tidak mungkin. Karena itu, tidak mungkin untuk membuat kode.
Anda perlu memikirkan kemungkinan semantik untuk perjalanan waktu, hanya setelah itu Anda dapat mulai memikirkan implementasi.
Paŭlo Ebermann
2
Pelajari sendiri beberapa vektor matematika . Jika Anda mengusulkan dua array terpisah yang menunjukkan Anda belum pernah bekerja dengannya. Saya menganggap mereka penting bagi seorang programmer game untuk mengetahui karena seberapa banyak mereka dapat menyederhanakan hal-hal.
doppelgreener
5
import universal.back2future.FluxCapacitor;
jhocking

Jawaban:

6

Ide array cukup banyak bagaimana itu diterapkan di Braid. Ketika satu-satunya yang bertindak pada karakter adalah gravitasi, input keyboard / joypad, dan karakter lain, Anda cukup hanya perlu menyimpan posisi dan kecepatan pada setiap langkah untuk mengetahui segala sesuatu yang penting tentang karakter itu. Jika Anda menyimpan 10 foto per detik per karakter maka masih kurang dari 50 ribu menit untuk satu menit sejarah karakter - mudah dikelola pada kebanyakan sistem, dan Anda dapat menemukan cara yang lebih efisien daripada itu juga.

Kylotan
sumber
Ini adalah jalur yang benar. Misalnya menyimpan perintah aktif: tekan tombol dengan cap waktu. Anda dapat memperkirakan sebagian besar perilaku lain jika sistem bersifat deterministik. 10 fps tracker baik-baik saja untuk sistem mundur, bahkan lebih sedikit mungkin dapat diterima, selama perintah yang sebenarnya dipertahankan, pada dasarnya keadaan atau perubahan statek objek.
karmington
4

Baca di Pola Perintah . Ini menyediakan untuk membatalkan tindakan (dan untuk kemudian melakukannya kembali.) Itu akan menangani lebih dari sekadar posisi kapal, tetapi semua tindakan yang dilakukan pemain.

Tapi saya pikir ide array Anda juga masuk akal.


sumber
Mungkin bukan ide yang bagus - selain lebih banyak menggunakan memori (setiap kali Anda menambah kecepatan entitas ke posisinya, Anda perlu menyimpannya sebagai "aksi") , itu cukup banyak membutuhkan matematika titik tetap, karena jika Anda menggunakan floating -point untuk posisi / kecepatan Anda, (x+v)-vmungkin tidak sama dengan x.
BlueRaja - Danny Pflughoeft
1
@BlueRaja - Jangan lihat di mana pendekatan itu akan menghabiskan banyak memori. Pada 100 FPS dan menyimpan 10 detik terakhir, Anda perlu menyimpan 1000 n-tupel perintah, di mana n paling banyak 5 atau lebih. Atau, lebih baik lagi, Anda hanya menyimpan posisi absolut di masing-masing bingkai itu, dan untuk mundur, Anda cukup menghidupkan karakter di belakang sepanjang jalur itu. Itu juga akan menghilangkan kemungkinan masalah titik apung dan membawa Anda kembali tepat ke tempat Anda mulai.
Hackworth
3

Daripada memiliki dua array terpisah, Anda mungkin harus memiliki satu kelas yang menggambarkan posisi pemain (mungkin sudah ada kelas Point di Jawa ... Saya seorang pria C # belakangan ini) dan menggunakan satu array tunggal untuk menahan posisi masa lalu.

Anda perlu mengatur "ring buffer", yang berarti bahwa ketika Anda sampai di akhir array, Anda berputar kembali ke awal array, menimpa entri tertua. Jika Anda melakukan perjalanan ke masa lalu, yang terjadi adalah kebalikannya (ketika Anda sampai di awal, lingkari hingga akhir).

Jika Anda ingin menyimpan data masa lalu senilai 30 detik, Anda perlu mengetahui frame rate Anda jika Anda ingin pra-mengalokasikan ruang dan menggunakan array ukuran tetap. Jika Anda membuat game dalam 10 frame / detik, kali 30 detik, itu adalah 300 elemen.

Eric J.
sumber
2

GDCVault memiliki ceramah oleh Jon Blow (pencipta Braid ) di situs mereka yang disebut Implementasi Rewind in Braid seharga $ 3,95. Saya berani bertaruh ini memiliki info yang Anda inginkan;)

EDIT: Mungkin tidak akan berada di Jawa tetapi ide-idenya harus berlaku.

NoobsArePeople2
sumber
Apakah Anda tahu apakah mereka menjual transkrip juga, atau hanya audio?
o0 '.
Saya tidak dapat menemukan apa pun melalui pencarian cepat situs. Mungkin Anda bisa menggunakan beberapa perangkat lunak transkripsi ?
NoobsArePeople2
1

Seperti yang dikatakan Erik J , menyimpan posisi masa lalu pemain sebagai kumpulan objek titik dalam buffer cincin terdengar masuk akal.

Namun, saya akan menyarankan menggunakan antrian untuk mengimplementasikan buffer. Jauh lebih murah untuk memperbarui daripada array dan Anda tidak perlu tahu frame rate Anda sebelumnya:

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

Ini belum mempertimbangkan berbagai frame rate atau apa yang harus terjadi jika Anda benar-benar melakukan perjalanan waktu, jadi saya sarankan Anda menyimpan cap waktu dengan setiap entri dan periksa sebagai gantinya:

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()

Semoga ini membantu!

HumanCatfood
sumber
1

Ada pola desain yang disebut Memento , saya pikir itu adalah titik awal untuk permainan seperti Braid

Pola kenang-kenangan adalah pola desain perangkat lunak yang memberikan kemampuan untuk mengembalikan> suatu objek ke keadaan sebelumnya (undo via rollback).

Pola kenang-kenangan digunakan oleh dua objek: pencetus dan juru kunci. Pencetus adalah beberapa objek yang memiliki keadaan internal. Pengasuh akan melakukan sesuatu kepada pencetusnya, tetapi ingin dapat membatalkan perubahan. Pengasuh pertama-tama meminta objek kenang-kenangan untuk pencetus. Kemudian ia melakukan operasi apa pun (atau urutan operasi) yang akan dilakukannya. Untuk kembali ke keadaan sebelum operasi, ia mengembalikan objek kenanga ke pencetus. Objek kenang-kenangan itu sendiri adalah objek buram (yang tidak dapat diubah oleh juru kunci). Saat menggunakan pola ini, perhatian harus diambil jika pencetusnya dapat mengubah objek atau sumber daya lain - pola kenang-kenangan beroperasi pada satu objek.

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

Info tambahan di sini: http://dofactory.com/Patterns/PatternMemento.aspx

Marcelo Assis
sumber
2
Saya gagal melihat bagaimana ini seharusnya membantu. Sepertinya itu adalah "rollback instan", sementara OP meminta sesuatu yang halus seperti Braid. Mungkin saya salah membaca sesuatu?
o0 '.
Pola ini tidak menyiratkan pada rollback tunggal, Anda dapat membuat "timeline" tindakan, misalnya. Berikut adalah posting blog Brazillian tentang penggunaan pola ini: abrindoojogo.com.br/padroes-de-projeto-memento Berikut adalah contoh yang dibuat dalam Flash: abrindoojogo.com.br/files/fasteroids.swf Bergerak: Panah | Tembak: Luar Angkasa | Tindakan mundur: Backspace
Marcelo Assis
1

Ada game yang dirilis untuk XBox360 yang melibatkan manipulasi waktu. Itu biasa-biasa saja, jadi saya tidak ingat judulnya saat ini. Bagaimanapun, dalam sebuah wawancara dengan pengembang untuk itu, mereka menguraikan bagaimana mereka mengelola manipulasi waktu:

Setiap X frame (dengan nilai X yang lebih rendah yang mengarah ke manipulasi yang lebih halus), Anda mengambil "snapshot" dari gameworld pada saat itu, dan mengaitkannya dengan waktu dalam game.

Saat bermain melalui permainan secara normal, maju-maju, setiap input dan suatu reaksi berkontribusi pada set snapshot pada suatu waktu di masa depan.

Dunia game kemudian beralih di antara snapshot pada waktu saat ini, dan frame X snapshot di masa depan.

Kemudian, ketika Anda ingin membalikkan waktu, cukup atur arah waktu untuk mundur, sehingga ia beralih antara frame X saat ini dan snapshot di masa lalu (sambil menonaktifkan kemampuan untuk membuat snapshot masa depan).

Jordaan Mylonas
sumber
+1 untuk poin tentang rincian dari snapshot.
Omar Kooheji
0

Anda cukup memperlakukan waktu virtual gim sebagai dimensi lain yang mirip ruang. Jadi perjalanan waktu dari luar adalah gerakan sederhana n + 1 dimensi di alam semesta virtual game.

Dengan asumsi beberapa interaksi pengguna dan semacam sistem fisika yang menentukan perilaku alam semesta Anda ketika tidak ada input pengguna, yang perlu Anda catat adalah efek interaksi pengguna (misalnya, perubahan dalam vektor kecepatan / percepatan n + 1 dimensi) , karena fisika Anda harus dapat dibalik waktu.

Dengan cara ini Anda akan membutuhkan lebih sedikit memori untuk menghitung keadaan semesta permainan pada waktu yang ditentukan.

biziclop
sumber
Seperti yang saya sebutkan di komentar lain, fisika dalam video game biasanya tidak dapat dibalikkan waktu, karena ketika menggunakan angka floating-point, (x+v)-vmungkin tidak sama denganx
BlueRaja - Danny Pflughoeft
0

Katakanlah suatu entitas memiliki kecepatan, rotasi, posisi x dan y. Ini adalah, dengan percepatan, status gerakan dasar, nilai-nilai, apa pun sebutannya. Anda dapat menyimpan data dengan dua cara:
1. Simpan rotasi, posisi x dan y
2. Simpan rotasi, kecepatan x dan kecepatan y

Jika Anda memiliki kecepatan tetap, Anda juga bisa hanya menyimpan rotasi, atau hanya menyimpan satu kecepatan untuk kedua sumbu.

Menyimpan rotasi diperlukan dalam permainan, kecuali jika entitas Anda memiliki rotasi statis, apa yang tidak dalam kebanyakan kasus.

Yang mengatakan, menggunakan daftar objek untuk beberapa nilai diperlukan. Jika Anda memiliki sistem pengatur waktu yang bagus, yang, misalnya, memanggil metode pembaruan 20 kali dalam satu detik, dan karena itu fps independen, Anda dapat membuat array 20 * 30 objek untuk menyimpan nilai pergerakan yang Anda butuhkan selama 30 detik terakhir . Menggunakan array sederhana tidak dianjurkan, karena Anda harus memindahkan setiap elemen satu indeks kiri setiap panggilan pembaruan.

Berdasarkan ini, Anda dapat pergi melalui daftar atau apa pun untuk kembali. Jika Anda benar-benar ingin mendapatkan efek "realistis", gunakan teknik ini untuk semua objek yang bergerak. Tapi ini terkait desain game.

Jika Anda menghancurkan benda, ingatlah untuk mengumpulkannya, untuk memastikan bahwa Anda tidak membuat teman Anda yang rapi, Tuan Garbage;)

Marco
sumber