Saya telah membaca dua utas lainnya di sini tentang gerakan: Gerakan berbasis waktu Vs Gerakan berbasis frame rate? , dan Kapan saya harus menggunakan langkah waktu tetap atau variabel?
tapi saya pikir saya kurang memiliki pemahaman dasar tentang gerakan frame independent karena saya tidak mengerti apa yang dibicarakan oleh salah satu dari kedua thread tersebut.
Saya mengikuti bersama dengan tutorial SDL lazyfoo dan sampai pada pelajaran frame independen. http://lazyfoo.net/SDL_tutorials/lesson32/index.php
Saya tidak yakin apa yang ingin dikatakan oleh bagian gerakan dari kode ini, tetapi saya pikir ini adalah ini (tolong perbaiki saya jika saya salah): Untuk memiliki frame independent, kita perlu mengetahui seberapa jauh suatu objek ( mis. sprite) bergerak dalam jangka waktu tertentu, misalnya 1 detik. Jika titik bergerak pada 200 piksel per detik, maka saya perlu menghitung berapa banyak bergerak dalam detik itu dengan mengalikan 200 pps dengan 1/1000 detik.
Apakah itu benar? Pelajaran mengatakan:
"kecepatan dalam piksel per detik * waktu sejak frame terakhir dalam detik. Jadi jika program ini berjalan pada 200 frame per detik: 200 pps * 1/200 detik = 1 piksel"
Tapi ... saya pikir kita mengalikan 200 pps dengan 1/1000 detik. Apa bisnis ini dengan frame per detik?
Saya akan menghargai jika seseorang bisa memberi saya sedikit penjelasan lebih rinci tentang bagaimana bingkai gerakan independen bekerja.
Terima kasih.
TAMBAHAN:
SDL_Rect posRect;
posRect.x = 0;
posRect.y = 0;
float y, yVel;
y = 0;
yVel = 0;
Uint32 startTicks = SDL_GetTicks();
bool quit = false;
SDL_Event gEvent;
while ( quit == false )
{
while ( SDL_PollEvent( &gEvent ) )
{
if ( gEvent.type == SDL_QUIT )
quit = true;
}
if ( y <= 580 )
{
yVel += DOT_VEL;
y += (yVel * (SDL_GetTicks() - startTicks)/1000.f);
posRect.y = (int)y;
}
startTicks = SDL_GetTicks();
SDL_BlitSurface( bg, NULL, screen, NULL );
SDL_BlitSurface( dot, NULL, screen, &posRect );
SDL_Flip( screen );
}
Kode itu yang memindahkan satu titik ke bawah layar. Saya pikir saya sudah melakukan semuanya dengan benar sejauh ini. Itu bergerak ke bawah layar tetapi ada sedikit hal aneh yang terjadi yang tidak bisa saya jelaskan. Titik seharusnya tetap pada y = 580 ketika sampai lebih dari nilai-y. Namun, setiap kali saya menjalankan program, titik tersebut akan berakhir di lokasi yang berbeda, yang berarti sedikit lebih banyak dari 580, sehingga titik tersebut setengah atau lebih dari setengah layar (titik adalah 20 piksel, layar dimensi 800x600). Jika saya melakukan sesuatu seperti klik dan tahan bilah judul program, dan kemudian lepaskan, titik menghilang dari layar. Kenapa variabel setiap kali? Adapun masalah bilah judul saya pikir itu karena ketika saya memegang bilah judul, penghitung waktu masih berjalan, dan waktu yang berlalu semakin besar, menghasilkan jarak yang lebih besar titik bergerak di bingkai berikutnya. Apakah itu benar?
sumber
yMovement = (yVel * (SDL_GetTicks() - startTicks)/1000.f);
lalu lakukan:if(y + yMovement <= 580){ y += yMovement; } else { y = 580; }
Jawaban:
CATATAN: Semua fraksi dimaksudkan untuk mengapung.
Bingkai gerakan independen bekerja dengan mendasarkan gerakan dari waktu. Anda mendapatkan jumlah waktu yang dihabiskan sejak frame terakhir (jadi jika ada 60 frame dalam satu detik, setiap frame membutuhkan 1,0 / 60,0 detik, jika semua frame mengambil jumlah waktu yang sama) dan cari tahu berapa banyak pergerakan yang dilakukan. diterjemahkan menjadi.
Jika Anda ingin entitas Anda memindahkan jumlah ruang tertentu untuk unit waktu tertentu (kami akan mengatakan 100 piksel untuk setiap detiknya) maka Anda dapat mengetahui berapa piksel yang harus Anda pindahkan per frame dengan mengalikan jumlah gerakan per detik (100 piksel) dengan jumlah waktu yang dilewati dalam detik (1.0 / 60.0) untuk mengetahui berapa banyak gerakan yang harus terjadi dalam bingkai saat ini.
Ini bekerja dengan mencari tahu berapa banyak gerakan yang harus Anda lakukan per frame dengan menggunakan jumlah waktu yang berlalu dan kecepatan yang ditentukan dengan beberapa unit waktu (detik atau milidetik lebih disukai). Jadi perhitungan Anda mungkin terlihat seperti:
movementPerSecond * (timeElapsedInMilliseconds / 1000.0)
Saya harap itu masuk akal bagi Anda.
Saya ingin menggerakkan pria saya 200 piksel ke kanan setiap detik. Jika frame saat ini dijalankan 50 milidetik setelah frame sebelumnya, maka saya harus menggerakkan pria saya sepersekian dari kecepatan yang ditentukan sebelumnya (yang 200 piksel). Saya harus memindahkannya 50/1000 dari jarak karena hanya 1/20 (50/1000 = 1/20) waktu telah berlalu. Oleh karena itu masuk akal untuk hanya memindahkannya 10 piksel (jika 19 frame lebih terjadi, 50 milidetik terpisah satu sama lain, maka jumlah total gerakan dalam detik itu adalah 200 piksel, jumlah yang kita inginkan).
Cara kerja frame independen bekerja adalah frame biasanya muncul pada langkah waktu variabel (ada jumlah waktu berbeda yang terjadi antara frame berikutnya). Jika kita terus-menerus memindahkan suatu entitas dengan jarak konstan setiap frame, maka pergerakannya didasarkan pada frame rate. Jika ada banyak waktu di antara frame, game akan tampak bergerak terlalu lambat dan jika tidak ada banyak waktu di antara frame, game akan tampaknya akan cepat. (terlalu sedikit waktu antar frame = banyak frame = lebih banyak pergerakan) Untuk mengatasinya, kami menggunakan kecepatan dalam hal waktu dan melacak waktu antara frame. Dengan begitu kita tahu sudah berapa lama sejak kita terakhir memperbarui posisi dan seberapa jauh kita harus memindahkan entitas.
Frame per detik: Ini adalah jumlah frame yang terjadi per detik. Biasanya frame rate adalah berapa kali gim ditarik / diberikan sedetik atau berapa kali perputaran gim diselesaikan satu detik.
Fixed Varie Variable Time Step: Ini mengacu pada jumlah waktu antar frame. Biasanya, waktu antar frame tidak akan konstan. Sistem / inti tertentu seperti fisika akan membutuhkan beberapa satuan waktu untuk mensimulasikan / menjalankan sesuatu. Biasanya, sistem fisika lebih stabil / scalable jika langkah waktu diperbaiki. Perbedaan antara langkah waktu tetap / variabel ada dalam nama. Langkah waktu tetap adalah seperti apa itu: langkah waktu yang terjadi pada tingkat waktu yang tetap. Langkah waktu variabel adalah langkah waktu yang terjadi pada tingkat waktu yang berbeda / berbeda.
sumber
Dalam dinamika bingkai kode Anda untuk (misalnya) memindahkan suatu entitas akan terlihat seperti ini:
Jika Anda ingin menjadi frame-independent, bisa terlihat seperti ini:
sumber
Mengenai pertanyaan tambahan.
Titik Anda berhenti di lokasi yang berbeda setiap kali karena Anda tidak memeriksa batas (y> 580) ketika Anda memindahkannya. Anda hanya berhenti memperbarui lebih jauh setelah 580 masa lalu.
Pada frame terakhir sebelum Anda menyeberang 580 Anda bisa mulai dari 579 atau Anda bisa di 570 atau Anda bisa di 100. Anda juga bisa melangkah 1 pixel maju atau 1000, tergantung pada berapa lama frame terakhir waktu untuk mengeksekusi.
Ubah saja kondisi IF Anda menjadi seperti ini dan Anda akan baik-baik saja.
sumber