Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Platformer
Gamedevelopment

Dasar Physics Platformer 2D, Bagian 1

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called Basic 2D Platformer Physics .
Basic 2D Platformer Physics, Part 2

Indonesian (Bahasa Indonesia) translation by Aditia Dwiperdana (you can also view the original English article)

Tabrakan Karakter

Oke, jadi begini ceritanya: kita ingin membuat platformer 2D dengan sistem simulasi physics yang sederhana, responsif, akurat, dan bisa ditebak. Kita tidak mau menggunakan physics engine 2D yang besar dalam game ini, dengan beberapa alasan:

  • respon tabrakan yang tidak bisa ditebak
  • pergerakan karakter yang sulit diatur tidak akurat
  • lebih rumit untuk digunakan
  • menggunakan lebih banyak daya proses dibanding physics sederhana

Tentu saja ada juga keuntungan menggunakan physics engine yang sudah jadi, misalnya bisa mengatur interaksi physics yang rumit dengan cukup mudah, tapi hal itu tidak dibutuhkan di game yang akan kita buat.

Physics engine buatan kita sendiri akan membantu game kita memberi pengalaman bermain yang unik dan berbeda dari yang lain, dan itu sangat penting! Walaupun kamu memulai dengan pengaturan yang dasar, bagaimana benda-benda bergerak dan berinteraksi satu sama lain akan dipengaruhi oleh peraturan yang kamu buat sendiri, bukan dibuat oleh orang lain. Ayo kita mulai!

Batas Karakter

Kita mulai dengan menentukan bentuk apa yang akan kita gunakan pada sistem physics kita. Salah satu bentuk yang paling umum digunakan untuk merepresentasikan objek fisik dalam sebuah game adalah Axis Aligned Bounding Box (AABB). AABB pada dasarnya adalah persegi yang tidak berputar.

Example of an AABB

Dalalm banyak game platformer, AABB sudah cukup sebagai perkiraan badan berbagai objek dalam game. AABB sangat efektif karena sangat mudah untuk memperhitungkan tumpang tindih antar AABB dan hanya membutuhkan sedikit data. Untuk mendeskripsikan AABB, kita hanya butuh tahu titik pusat dan ukurannya.

Tanpa berlama-lama, ayo buat struktur data untuk AABB kita.

Seperti yang disebutkan sebelumnya, yang kita perlukan hanyalah dua vektor; yang pertama adalah pusat AABB, dan yang kedua adalah half size, setengah dari ukuran persegi AABB. Kenapa setengah dari ukuran kotak? Sebagian besar perhitungan membutuhkan nilai setengah dari ukuran kotak, jadi daripada kita hitung setiap kali, kita cukup menyimpannya sebagai data.

Mari mulai dengan membuat konstruktor, agar bisa membuat struktur data dengan parameter tertentu.

Dengan ini kita bisa membuat fungsi pemeriksaan tabrakan. Pertama, kita lakukan pemeriksaan sederhana apakah kedua AABB saling bertabrakan. Hal ini sangat sederhana, kita cukup melihat apakah jarak antara kedua pusat di masing-masing sumbu lebih kecil dari total nilai half size mereka.

Berikut adalah gambar pemeriksaan pada sumbu x, pemeriksaan pada sumbu y dilakukan dengan cara yang serupa.

Demonstrating a check on the X-Axis

Seperti kamu lihat, jika total half size lebih kecil dari jarak antar pusat, tidak mungkin terjadi tumpang tindih. Perhatikan bahwa pada kode di atas, kita bisa keluar dari pemeriksaan tabrakan lebih awal jika kita tahu kedua objek tidak tumpang tindih di sumbu pertama. Tumpang tindih tersebut harus terjadi pada dua sumbu, jika AABB tersebut bertabrakan pada dunia 2D.

Menggerakkan Objek

Mari mulai dengan membuat sebuah kelas untuk objek yang dipengaruhi oleh physics dalam game. Nantinya, kita akan menggunakan kelas ini sebagai dasar untuk objek pemain. Kita sebut kelas ini MovingObject.

Sekarang kita isi kelas ini dengan data. Kita akan membutuhkan cukup banyak informasi untuk objek ini.

  • Posisi dan posisi pada frame sebelumnya
  • kecepatan dan kecepatan pada frame sebelumna
  • skala
  • AABB dan offsetnya (agar kita bisa selaraskan dengan sprite)
  • apakah objek tersebut ada di atas tanah, dan apakah ada di atas tanah di frame sebelumnya
  • apakah di sebelah kiri objek ada tembok dan kondisi tersebut di frame sebelumnya
  • apakah di sebelah kanan objek ada tembok dan kondisi tersebut di frame sebelumnya
  • apakah objek berada di langit-langit dan kondisi tersebut di frame sebelumnya

Posisi, kecepatan, dan skala adalah vektor 2D.

Sekarang tambahkan AABB dan offsetnya. Offset dibutuhkan agar kita bisa mencocokkan AABB dan sprite objek sesuai kebutuhan.

Lalu, buat variabel yang akan menunjukkan kondisi posisi objek, apakah ada di atas tanah, di sebelah tembok, atau di langit-langit. Variabel-variabel tersebut sangat penting karena mereka akan memberitahu apakah kita melompat atau misalnya kita perlu memainkan suara saat menabrak tembok.

Ini adalah dasar-dasarnya. Sekarang kita buat fungsi yang akan mengupdate objek. Untuk saat ini kita tidak akan mengatur semuanya, hanya secukupnya agar kita bisa mulai kontrol dasar untuk karakter.

Hal pertama yang perlu dilakukan adalah menyimpan data dari frame sebelumnya ke variabel yang sesuai.

Sekarang kita update posisi sesuai dengan kecepatan saat ini.

Khusus untuk saat ini saja, kita buat jika posisi vertikal kurang dari nol, kita asumsikan karakter ada di tanah. Hal ini hanya sementara, agar kita bisa mengatur kontrol karakter. Nantinya akan kita periksa tabrakan menggunakan tilemap.

Setelah ini, kita perlu update pusat AABB, agar sesuai dengan posisi baru.

Untuk project demo ini, saya menggunakan Unity. Untuk mengupdate posisi objek kita perlu mengaplikasikannya pada komponen transform. Hal yang sama perlu dilakukan untuk skala.

Seperti yang bisa kamu lihat, posisi hasil render dibulatkan ke atas. Ini untuk memastikan katakter yang dirender selalu menempel pada sebuah pixel.

Kontrol Karakter

Data

Karena sekarang kita sudah memiliki kelas MovingObjek dasar, kita bisa mulai bermain dengan pergerakan karakter. Ini adalah bagian yang sangat penting dari game, dan bisa diselesaikan secepat mungkin, tidak perlu masuk terlalu dalam ke sistem dalam game, dan akan siap saat kita perlu menguji tabrakan antara karakter dan peta.

Pertama, kita buat kelas karakter dan menurunkannya dari kelas MovingObject.

Kita perlu menangani beberapa hal di sini. Pertama, input. Kita buat sebuah enum yang mencakup semua kontrol untuk karakter. Kita buat di file lain dan beri nama KeyInput.

Seperti yang kamu lihat, karakter kita bisa bergerak ke kiri, kanan, bawah, dan melompat ke atas. Berjalan ke bawah hanya akan bekerja pada platform satu arah, saat kita ingin jatuh menembusnya.

Sekarang kita deklarasi dua array di kelas Character, satu untuk input frame ini, dan satunya untuk input frame sebelumnya. Tergantung pada game yang bersangkutan, pengaturan ini bisa masuk akal atau tidak. Biasanya, daripada menyimpan kondisi tombol di array, kondisi tombol diperiksa sesuai kebutuhan menggunakan fungsi spesifik dari engine atau framework. Tapi, memiliki array yang tidak terikat ke input asli bisa menguntungkan, misalnya jika kita ingin mensimulasikan sebuah tombol ditekan.

Array-array ini akan diindex berdasarkan enum KeyInput. Untuk menggunakan array-array tersebut dengan mudah, kita buat beberapa fungsi untuk membantu kita memeriksa sebuah tombol.

Tidak ada yang khusus di sini, kita ingin melihat apakah sebuah tombol baru ditekan, baru dilepas, atau apakah tombol itu aktif atau tidak.

Sekarang buat sebuah enum lain yang akan menyimpan semua kondisi karakter.

Seperti yang bisa kamu lihat, karakter kita bisa berdiri diam, berjalan, melompat, atau berpegangan di tebing. Setelah ini selesai, kita perlu menambahkan variabel seperti kecepatan melompat, kecepatan berjalan, dan kondisi saat ini.

Tentu saja ada beberapa data lain yang dibutuhkan di sini, seperti sprite karakter, tapi bagaimana melakukannya akan sangat tergantung pada engine yang akan kamu gunakan. Karena saya menggunakan Unity, saya akan menggunakan referensi ke sebuah Animator untuk memastikakn sprite menjalankan animasi untuk kondisi yang sesuai.

Loop Update

Sekarang kita bisa mulai mengerjakan loop update. Yang akan kita lakukan dalam loop tergantung dengan kondisi karakter saat ini.

Kondisi Berdiri

Kita mulai dengan mengisi apa yang harus dilakukan saat karakter sedang tidak bergerak dalam kondisi berdiri. Pertama, kecepatan harus diatur menjadi nol.

Kita juga ingin menampilkan sprite yang sesuai untuk kondisi tersebut.

Lalu jika karakter tidak ada di atas tanah, karakter tidak bisa berdiri, jadi kita perlu ganti kondisinya menjadi melompat.

Jika tombol GoLeft atau GoRight ditekan, kita perlu mengubah kondisinya menjadi berjalan.

Jika tombol Jump ditekan, kita perlu mengatur kecepatan vertikal manjadi kecepatan melompat, dan mengubah kondisinya menjadi melompat.

Sejauh ini penanganan kondisi tersebut sudah cukup.

Kondisi Berjalan

Sekarang buat logika untuk bergerak di atas tanah, dan langsung menjalankan animasi berjalan.

Jika kita tidak menekan tombol kiri atau kanan, atau jika kedua tombol ditekan bersamaan, kita perlu kembali ke kondisi berdiri diam.

Jika tombol GoRight ditekan, kita atur kecepatan horizontal menjadi mWalkSpeed dan pastikan sprite diatur skalanya dengan benar. Skala horizontal perlu diubah jika kita mau memutar sprite secara horizontal.

Kita hanya boleh bergerak jika tidak ada rintangan di depan karakter, jadi jika mPushesRightWall nilainya true, maka kecepatan horizontal perlu diatur jadi nol jika kita bergerak ke kanan.

Kita juga menangani arah kiri dengan cara yang sama.

Seperti pada kondisi berdiri, kita perlu periksa apakah tombol melompat ditekan, jika iya kita atur kecepatan vertikal sesuai kecepatan lompat.

Jika karakter tidak di atas tanah, maka kita perlu ubah kondisi karakter menjadi lompat tapi tanpa mengubah kecepatan vertikal, jadi karakter akan bergerak jatuh ke bawah.

Cukup sekian untuk kondisi berjalan. Sekarang kita lanjutkan ke kondisi melompat.

Kondisi Melompat

Kita mulai dengan mengatur animasi yang sesuai untuk sprite.

Pada kondisi melompat, kita perlu menambahkan gravitasi pada kecepatan karakter, jadi karakter akan bergerak semakin lama semakin cepat ke arah tanah.

Tapi perlu kita tambahkan suatu batasan agar karakter tidak bergerak jatuh terlalu cepat.

Dalam banyak game, jika karakter ada di udara, kemampuan bergeraknya akan berkurang, tapi kita akan menggunakan kontrol yang sangat sederhana dan akurat untuk memberikan fleksibilitas penuh saat karakter ada di udara. Jadi kita kita tekan tombol GoLeft atau GoRight, karakter akan bergerak ke arah tersebut sambil melompat, sama cepatnya seperti jika karakter ada di atas tanah. Dalam hal ini, kita bisa salin logika pergerakan dari kondisi berjalan.

Akhirnya kita akan membuat karakter melompat lebih tinggi jika tombol melompat ditekan lebih lama. Untuk melakukan ini, yang perlu kita lakukan adalah membuat lompatan karakter lebih rendah jika tombol melompat tidak ditekan.

Seperti yang bisa kamu lihat, jika tombol melompat tidak ditekan dan kecepatan vertikal bernilai positif, maka kita batasi kecepatan ke nilai maksimum cMinJumpSpeed (200 piksel per detik). Ini artinya jika kita hanya menekan tombol melompat sesaat, kecepatan lompat akan diturunkan menjadi 200, bukan bernilai mJumpSpeed (yang nilai awalnya 410), sehingga karakter akan melompat lebih rendah.

Karena kita belum memiliki geometri level, kita perlu melewatkan implementasi GrabLedge untuk sementara.

Update Input Sebelumnya

Saat semua proses pada frame selesai, kita bisa update nilai input sebelumnya. Mari buat fungsi baru untuk ini. Yang kita perlu lakukan di sini adalah memindahkan nilai key state dari array mInputs ke array mPrevInputs.

Di akhir fungsi CharacterUpdate, kita masih perlu melakukan beberapa hal. Pertama, update physics.

Sekarang karena physics sudah diupdate, periksa apakah kita perlu memainkan suatu suara atau tidak. Kita ingin memainkan suara saat karakter menabrak permukaan apapun, tapi saat ini karakter hanya bisa menabrak permukaan tanah karena tabrakan dengan tilemap belum diimplementasi.

Mari periksa apakah karakter jauh ke permukaan tanah. Hal ini sangat mudah untuk dilakukan dengan pengaturan saat ini, kita hanya perlu memeriksa apakah saat ini karakter ada di atas tanah, tapi tidak begitu di frame sebelumnya.

Lalu, kita update input sebelumnya.

Kurang lebih seperti ini lah seharusnya fungsi CharacterUpdate, dengan perubahan kecil tergantung dengan engine atau framework yang kamu gunakan.

Inisialisasi Karakter

Mari buat sebuah fungsi inisialisasi untuk karakter. Fungsi ini akan menggunakan array input sebagai parameter. Nantinya kita akan menyediakan parameter tersebut dari kelas manajer. Selain itu, kita perlu melakukan hal-hal berikut:

  • tentukan nilai skala
  • tentukan kecepatan melompat
  • tentukan kecepatan berjalan
  • atur posisi awal
  • atur AABB

Kita akan menggunakan beberapa definisi konstanta.

Dalam hal demo ini, kita akan atur nilai posisi awal menjadi posisi di editor.

Untuk AABB, kita perlu atur nilai offset dan half size. Offset untuk sprite dalam demo ini adalah nilai half size.

Sekarang kita bisa mengurus sisa variabel yang ada.

Kita perlu memanggil fungsi ini dari game manager. Manajer ini bisa diatur dengan berbagai cara, tergantung dari engine yang kamu gunakan, tapi ide dasarnya kurang lebih sama. Pada inisialisasi manajer, kita perlu buat array input, buat sebuah objek pemain, dan menginisialisasinya.

Lalu pada update manajer, kita perlu update pemain dan array input pemain.

Perhatikan bahwa kita mengupdate physics karakter dalam update dengan jeda yang tetap. Ini akan memastikan aksi melompat akan selalu dengan ketinggian yang sama, tidak masalah berapa frame rate saat game kita dijalankan. Ada artikel yang bagus dari Glenn Fiedler untuk bagaimana memperbaiki timestep jika kamu tidak menggunakan Unity.

Menguji Controller Karakter

Di titik ini kita bisa menguji pergerakan karakter apakah sudah enak dilihat atau belum. Jika kita tidak menyukai hasil saat ini, kita bisa mengubah berbagai parameter atau bagaimana nilai kecepatan berubah saat tombol ditekan.

An animation of the character controller

Ringkasan

Kontrol karakter mungkin terlihat tanpa beban dan tidak senyaman dibandingkan pergerakan berbasis momentum untuk sebagian orang, tapi ini semua tergantung dengan kontrol seperti apa yang paling cocok dengan game yang ingin kamu buat. Untungnya untuk mengubah bagaimana karakter bergerak cukup mudah: hanya dengan mengubah bagaimana nilai kecepatan berubah dalam kondisi berjalan dan melompat.

Sekian tutorial bagian pertama dari seri ini. Kita sudah memiliki skema pergerakan karakter, tidak lebih dari itu. Yang paling penting adalah kita sudah memiliki landasan untuk bagian berikutnya, di mana kita akan membuat karakter berinteraksi dengan tilemap.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.