Platformer 2D: mengapa membuat fisika bergantung pada framerate?

12

"Super Meat Boy" adalah platformer yang sulit yang baru-baru ini keluar untuk PC, membutuhkan kontrol yang luar biasa dan lompatan pixel-sempurna. Kode fisika dalam permainan tergantung pada framerate, yang dikunci menjadi 60fps; ini berarti bahwa jika komputer Anda tidak dapat menjalankan game dengan kecepatan penuh, fisika akan menjadi gila, menyebabkan (antara lain) karakter Anda berjalan lebih lambat dan jatuh ke tanah. Lebih jauh, jika vsync mati, game berjalan sangat cepat.

Bisakah mereka yang berpengalaman dengan pemrograman game 2D membantu menjelaskan mengapa game dikodekan dengan cara ini? Tidakkah perputaran fisika yang berjalan pada kecepatan konstan menjadi solusi yang lebih baik? (Sebenarnya, saya pikir loop fisika digunakan untuk bagian-bagian permainan, karena beberapa entitas terus bergerak secara normal terlepas dari framerate. Karakter Anda, di sisi lain, berjalan persis [fps / 60] secepatnya.)

Apa yang mengganggu saya tentang implementasi ini adalah hilangnya abstraksi antara mesin game dan rendering grafik, yang tergantung pada hal-hal khusus sistem seperti monitor, kartu grafis, dan CPU. Jika, karena alasan apa pun, komputer Anda tidak dapat menangani vsync, atau tidak dapat menjalankan game dengan tepat 60fps, itu akan pecah secara spektakuler. Mengapa langkah rendering memengaruhi perhitungan fisika? (Sebagian besar game saat ini akan memperlambat game atau melompati frame.) Di sisi lain, saya mengerti bahwa platformer jadul di NES dan SNES bergantung pada framerate tetap untuk sebagian besar kontrol dan fisika mereka. Mengapa demikian, dan mungkinkah membuat patformer dalam nada itu tanpa memiliki ketergantungan framerate? Apakah pasti ada kehilangan presisi jika Anda memisahkan rendering grafik dari bagian mesin yang lain?

Terima kasih, dan maaf jika pertanyaannya membingungkan.

Archagon
sumber
Bersinggungan dengan pertanyaan Anda. Berikut ini adalah artikel hebat yang membahas persis masalah yang Anda gambarkan, dan cara "tepat" untuk menangani timesteps dan frame-rate. gafferongames.com/game-physics/fix-your-timestep
num1
Sebenarnya sangat mengejutkan saya bahwa mereka akan melakukannya dengan cara ini. Saya kira itu pasti karena itu dibangun terutama untuk konsol, di mana frame rate dapat diandalkan. Mengecewakan!
Iain

Jawaban:

7

Mengapa?

Beberapa alasan, pilihlah: Mereka tidak tahu apa-apa. . Ini lebih cepat dan lebih mudah diimplementasikan. Mereka lebih fokus pada gameplay dan lebih sedikit pada kasus tepi yang mungkin tidak muncul dalam kebanyakan kasus.

Anda melakukan pekerjaan yang cukup baik untuk menjelaskan mengapa tidak. Saya yakin Anda memperhatikan ada banyak topik yang membahas masalah ini . Saya tidak yakin Anda akan menemukan jawaban yang memuaskan di luar yang saya daftarkan.

Tetrad
sumber
"Mereka tidak tahu yang lebih baik" menggambarkan mengapa saya mengambil pendekatan itu dengan "Jack is a Fool". Tapi - Saya sangat mengandalkan memanggil dt sejak frame terakhir dengan semua logika saya. Tetapi - dengan koordinat floating point, ini dapat menyebabkan beberapa bug yang aneh dan sulit ditiru
lochok
4

SMB pada awalnya adalah sebuah game konsol di mana aman untuk berasumsi bahwa itu dapat berjalan pada 60fps di semua Xbox360s (well, mungkin 50 untuk beberapa pemain PAL). Dengan asumsi cap waktu tetap menyederhanakan kode sedikit adil.

Meskipun mudah untuk skala banyak hal dengan timestep variabel - 'pos + = velocity * timestep', itu cukup rumit untuk melakukannya dengan benar ketika Anda berurusan dengan akselerasi, dan tingkat perubahan akselerasi, dan sebagainya.

Gameplay decoupling dan rendering adalah solusi yang bagus dalam teori , tetapi menerapkannya dengan baik (dengan interpolasi yang baik) cukup rumit, dan banyak hal dapat dengan mudah menjadi berantakan. Cukup umum untuk teknik ini digunakan dalam game nyata (walaupun beberapa game besar melakukannya, terutama game RTS, tetapi lebih untuk sinkronisasi game jaringan).

Ketika juga merancang untuk resolusi layar tetap serta framerate tetap, ada satu hal lain yang dapat Anda lakukan untuk membuat pengguliran menjadi lebih halus. Anda dapat memastikan bahwa gulir permainan di sejumlah piksel per frame - menghindari 'goyangan subpiksel' yang Anda dapatkan dengan menggulirkan sejumlah piksel piksel per frame.

bluescrn
sumber
1

Solusi yang jelas adalah memiliki 2 loop berjalan secara paralel - rendering setiap 1/60 detik dan loop game setiap 1/60 detik.

Tetapi dengan pengalaman saya di Flash (AS3, yang saya yakin Super Meat Boy diciptakan), penjadwal tidak selalu sangat akurat. Akurasi juga sangat tergantung pada lingkungan. Pada flash player yang berdiri sendiri, mungkin memiliki resolusi sub-milidetik. Tetapi ketika dijalankan di beberapa browser web, akurasinya menjadi seperti pada frame rate.

Jadi cara terdekat yang bisa Anda lakukan untuk memisahkan tautan render dan logika permainan adalah memiliki semua gerakan berdasarkan waktu (dan menjalankan setiap frame berdasarkan berapa banyak waktu yang berlalu sejak frame terakhir). Itu dapat memperkenalkan beberapa matematika yang lebih rumit (seperti memiliki gravitasi diterapkan secara terus menerus, daripada menambah kecepatan suatu objek pada interval yang ditetapkan). Karena gim ini bisa berhenti sesaat dan kemudian pemain Anda akan bergerak 200 piksel dalam satu langkah, deteksi dan respons tabrakan bisa menjadi lebih rumit. Jika programmer melakukan deteksi tabrakan berbasis bingkai (memeriksa tabrakan setiap timestep), mereka harus beralih ke deteksi tabrakan berbasis waktu juga. Dan jika mereka ingin itu terasa alami, mereka harus menggunakan metode gravitasi yang dijelaskan di atas, yang menyebabkan pergerakan objek menjadi kurva (berlawanan dengan garis),

Ponkadoodle
sumber
2
Meat Boy yang asli adalah game Flash. Super Meat Boy adalah game C ++.
Archagon
0

Saya tidak berpikir banyak untuk meminta game PC 2D untuk bermain di 60fps lagi. Bahkan sebagian besar game 2D dipercepat perangkat keras sekarang jadi secara pribadi saya tidak akan khawatir tentang persyaratan fps.

Pertanyaan sebenarnya adalah mengapa Anda tidak menggunakan berbasis pixel, game penuh dengan cheat dan shortcut.

Jika Anda membuat game berbasis fisika (mungkin melempar burung?) Jawabannya sudah jelas, tetapi klon super mario? Gerakan berdasarkan waktu mungkin agak banyak.

PhilCK
sumber
Tidak sulit untuk memainkannya pada 60fps, tetapi tampilan dengan kecepatan refresh asli 50Hz, 70-85Hz, dan 120Hz masih mudah ditemukan.
0

Untuk menghindari perilaku aneh dalam fisika 2d yang mereka gunakan?

Jujur saya hanya bisa menebak. Saya akan mencoba penjelasan:

Di jantung permainan adalah loop permainan utama. Yang pada dasarnya terlihat seperti ini:

while(gameRunning)
{
  updateGame(timestep);
  renderGame(timestep);
}

updateGame memperbarui gameState: memeriksa input pemain, menerapkan input pemain ke dunia game dan menjalankan simulasi fisika dll.

renderGame menggambar dan menghidupkan game.

Ini memasangkan pembaruan fisika ke rendering. Jika Anda ingin memisahkannya, Anda perlu menggunakan utas dan menyinkronkan dengan baik setiap akses data dari perenderan dan utas perbaruan untuk data bersama misalnya posisi pemain. Ini bisa dilakukan.

Masalah lain mungkin bahwa simulasi fisika membutuhkan timestep yang konstan untuk berjalan stabil. Ini tergantung pada bagaimana supermeatboy menghitung pergerakan (Sekali lagi kita bisa menebak bagaimana mereka melakukannya;)).

Pendekatan naif akan (yang saya gunakan dalam game saya * mendesah *):

position=position+speed*timestep;
speed=speed+acceleration*timestep;

Ini disebut Integrasi Euler dan umumnya dianggap sebagai ide yang buruk. Jika catatan waktu tidak ada kesalahan perhitungan konstan yang akan membuat simulasi kurang stabil. Objek mungkin bergerak dengan kecepatan yang berlebihan atau tidak semua atau terbang menembus dinding dari layar. Bahkan jika catatan waktu konstan Euler Integration menyebabkan kesalahan perhitungan kecil. Lebih baik gunakan metode integrasi lain seperti RK4 atau gunakan mesin fisika.

Selain itu mungkin ada masalah melakukan deteksi tabrakan jika timestep menjadi terlalu besar. Karena tabrakan tidak diperiksa antara dua gameUpdates, objek mungkin melewati rintangan.

Stephen
sumber