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

Dasar Pysics Platformer 2D, Bagian 4

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called Basic 2D Platformer Physics .
Basic 2D Platformer Physics, Part 3
Basic 2D Platformer Physics, Part 5: Object vs. Object Collision Detection

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

Menangkap Pinggiran Platform

Karena sekarang kita sudah bisa melompat, turun dari platform satu arah, dan berlarian ke sana kemari, kita juga bisa mengimplementasi menangkap pinggiran. Mekanik menangkap pinggiran sebenarnya tidak harus dibuat untuk semua game, tapi salah satu cara yang populer untuk menambah jenis gerakan pemain tanpa harus membuat sesuatu yang ekstrim seperti lompatan ganda.

Mari kita lihat bagaimana kita bisa menentukan apakah sebuah pinggiran bisa ditangkap. Untuk menentukan apakah karakter bisa menangkap pinggiran, kita akan memeriksa sisi arah pemain bergerak terus menerus. Jika kita menemukan petak kosong di atas AABB, dan menemukan petak solid di bawahnya, maka bagian atas dari petak solid tersebut adalah pinggiran yang bisa ditangkap olen karakter kita untuk berpegangan.

Mengatur Variabel

Kita kembali ke kelas Character, di mana kita akan mengimplementasi fitur menangkap pinggiran. Tidak perlu membuatnya pada kelas MovingObject karena sebagian besar objek tidak akan punya kemampuan untuk menangkap pinggiran, sehingga itu hanya membuang waktu jika kita implementasi di situ.

Pertama, kita perlu menambahkan beberapa konstanta. Kita mulai dengan membuat konstanta sensor offset.

cGrabLedgeStartY dan cGrabLedgeEndY adalah offset dari atas AABB; yang pertama adalah titik sensor pertama, dan yang kedua adalah akhir dari titik sensor. Seperti yang bisa kamu lihat, karakter perlu menemukan pinggiran dalam 2 piksel.

Kita juga membutuhkan konstanta tambahan untuk menyesuaikan posisi karakter ke petak yang kita tangkap. Untuk karakter ini, kita akan atur menjadi -4.

Selain itu, kitai perlu mengingat koordinat dari petak yang kita tangkap. Kita simpan sebagai variabel dari kelas karakter.

Implementasi

Kita perlu periksa apakah kita bisa menangkap pinggiran dari kondisi melompat, mari periksa kode yang bersangkutan. Tepat setelah kita periksa apakah karakter mendarat di tanah, kita periksa apakah kondisi untuk menangkap pinggiran terpenuhi. Kondisi utamanya adalah sebagai berikut:

  • Kecepatan vertikal lebih kecil atau sama dengan nol (karakter sedang jatuh).
  • Karakter tidak berada di langit-langit, tidak ada gunanya menangkap pinggiran jika kita tidak bisa melompat untuk menaikinya.
  • Karakter bertabrakan dengan tembok dan sedang bergerak ke arah tersebut.

Jika tiga kondisi tersebut terpenuhi, kita perlu mencari pinggiran yang perlu ditangkap. Kita mulai dengan menghitung posisi atas dari sensor, yang akan berupa pojok kiri atas atau kanan atas dari AABB.

Sekarang, seperti yang mungkin kamu bayangkan, kita akan menemui masalah yang mirip dengan masalah saat mengimplementasi pemeriksaan tabrakan, jika karakter jatuh sangat cepat, sangat mungkin untuk melewati titik pada pinggiran yang sebenarnya bisa ditangkap. Karena itu kita perlu memeriksa petak untuk ditangkap bukan dari pojok di frame saat ini, tapi dari frame sebelumnya, seperti yang pada gambar berikut:


Gambar bagiaan atas adalah karakter pada posisi di frame sebelumnya. Pada posisi ini, kita perlu mulai mencari peluang untuk mengnangkap pinggiran dari pojok kanan atas dari AABB di frame sebelumnya dan berhenti di posisi pada frame saat ini.

Sekarang kita ambil koordinat petak yang perlu kita periksa, mulai dengan mendeklarasi variabel yang dibutuhkan. Kita akan memeriksa petak dalam satu kolom, jadi yang kita butuhkan adalah koordinat X dari kolom dan koordinat Y dari bagian atas dan bawah.

Kita ambil koordinat X dari pojok AABB.

Kita ingin mulai mencari pinggiran dari posisi di frame sebelumnya hanya juka kita sudah bergerak menuju tembok di saat itu, jadi nilai X pada posisi karakter kita sebenarnya tidak berubah.

Seperti yang bisa kamu lihat, dalam kasus i ni kita menghitung topY menggunakan posisi dari frame sebelumnya, dan bagian bawahnya menggunakan frame saat ini. Jika kita tidak ada di sebelah tembok, maka kita hanya perlu melihat apakah kita bisa menangkap pi nggiran menggunakan posisi objek di frame saat ini.

Sekarang kita sudah tahu petak untuk diperiksa, kita bisa mulai mengiterasi petak-petak tersebut. Kita akan mulai dari atas ke bawah, karena urutan tersebut adalah yang paling masuk akal karena kita hanya membolehkan karakter untuk menangkap pinggiran saat sedang jatuh.

Sekarang kita periksa apakah petak yang sedang kita periksa memenuhi kondisi untuk karakter menangkap pinggiran. Kondisinya, seperti yang dijelaskan sebelumnya, adalah sebagai berikut:

  • Petak tersebut kosong.
  • Petak di bawahnya adalah petak solid (ini adalah petak yang akan kita tangkap).

Langkah berikutnya adalah menghitung posisi dari pojok petak yang ingin kita tangkap. Hal ini cukup mudah, kita hanya perlu mengambil posisi petak dan menambahkan offset sesuai dengan ukuran petak.

Setelah kita tahu nilai tersebut, kita perlu periksa apakah pojok tersebut ada diantara titik sensor kita. Tentu saja kita ingin melakukannya hanya jika kita sedang memeriksa petak yang berhubungan dengan posisi karakter di frame saat ini, yaitu tile dengan nilai koordinat Y yang sama dengan bottomY. Jika tidak, kita bisa asumsikan bahwa kita melewati pinggiran antara frame sebelumnya dan frame saat ini, jadi kita perlu menangkap pinggiran itu.

Sekarang kita sudah sampai, kita menemukan pinggiran yang ingin kita tangkap. Pertama kita perlu simpan posisi petak yang ditangkap.

Kita juga perlu menyesuaikan posisi karakter dengan pinggiran tersebut. Yang kita inginkan adalah menyesuaikan bagian atas sensor karakter dengan bagian atas petak, dan menambahkan posisi tersebut dengan cGrabLedgeTileOffsetY.

Selain itu, kita perlu mengatur kecepatan menjadi nol, dan mengubah kondisi karakter manjadi CharacterState.GrabLedge. Setelah itu, kita bisa keluar dari loop karena tidak perlu mengolah sisa petak yang ada.

Sudah selesai! Pinggiran sekarang bisa dideteksi dan ditangkap, jadi kita perlu mengimplementasi kondisi GrabLedge, yang kita lewati sebelumnya.

Kontrol Menangkap Pinggiran

Setelah karakter menangkap pinggiran, pemain punya dua pilihan: melompat ke atas atau turun ke bawah. Melompat bekerja seperti biasanya: pemain menekan tombol melompat dan kekuatan lompatan sama dengan melompat dari tanah. Turun ke bawah dilakukan dengan menekan tombol bawah, atau menekan tombol arah yang menjauhi pinggiran.

Implementasi Kontrol

Hal pertama yang perlu dilakukan adalah memeriksa apakah pinggiran ada di kiri atau kanan karakter. Kita bisa melakukan ini karena kita menyimpan koordinat pinggiran yang sedang ditangkap pemain.

Kita bisa menggunakan informasi itu untuk menentukan apakah karakter bisa turun dari pi nggiran. Untuk turun, pemain perlu untuk:

  • menekan tombol bawah
  • menekan tombol kiri saat menangkap pinggiran di kanan, atau
  • menekan kanan saat menangkap pinggiran di kiri

Ada sedikit masalah di sini. Bayangkan situasi saat kita menekan tombol bawah dan kanan, ketika karakter sedang berpegangan ke pinggiran di kanan. Itu akan menghasilkan situasi berikut:

Masalahnya adalah karakter menangkap pinggiran segera setelah melepaskannya.

Solusi sederhananya adalah untuk mengunci gerakan ke arah pinggiran selama beberapa frame setelah kita turun dari pinggiran. Untuk itu kita perlu dua variabel baru, kita beri nama mCannotGoLeftFrames dan mCannotGoRightFrames.

Saat karakter turun dari pinggiran, kita memerlukan variabel tersebut dan mengubah kondisi karakter jadi melompat.

Sekarang kita kembali ke kondisi Jump terlebih dahulu, dan pastikan kondisi tersebut mengikuti aturan kita untuk mencegah pergerakan ke kiri atau kanan setelah turun dari pinggiran. Kita reset input tepat sebelum kita periksa apakah kita perlu mencari pinggiran untuk ditangkap.

Seperti yang bisa kamu lihat, dengan cara ini kita tidak akan memenuhi syarat untuk menangkap pinggiran selama arah yang diblok sama dengan arah pinggiran yang mungkin ditangkap oleh karakter. Setiap kita mencegah sebuah input, kita menguranginya dari sisa blocking frame, jadi akhirnya kita bisa bergerak lagi, dalam hal ini, setelah 3 frame.

Sekarang kita lanjutkan ke kondisi GrabLedge. Karena kita sudah menangani turun dari pingguran, sekarang kita perlu membuat karakter bisa melompat dari posisi bergantung di pinggiran.

Jika karakter tidak turun dari pinggiran, kita perlu memeriksa apakah tombol melompat ditekan, jika iya, kita perlu mengatur kecepatan melompat vertikal dan mengubah kondisi karakter:

Selesai sudah! Sekarang menangkap pinggiran harusnya sudah bisa bekerja dengan baik di berbagai situasi.

Membuat karakter bisa melompat tepat setelah meninggalkan platform

Biasanya, untuk membuat melompat lebih mudah dalam game platformer, karakter boleh melompat jika baru saja melewati ujung platform dan sudah tidak berada di tanah. Ini adalah cara yang umum digunakan untuk meminimalkan ilusi bahwa pemain sudah menekan tombol melompat tapi karakter tersebut tidak melompat, yang mungkin akan muncul karena input lag atau pemain menekan tombol tersebut tepat setelah pemain meninggalkan platform.

Mari kita buat implementasi mekanik tersebut. Pertama, kita perlu menambahkan konstanta berisi berapa banyak frame setelah karakter meninggalkan platform pemain masih diperbolehkan untuk melompat.

Kita juga membutuhkan penanda frame di kelas Character, agar kita tahu berapa banyak frame pemain sudah ada di udara.

Sekarang kita atur mFramesFromJumpStart menjadi 0 setiap kita meninggalkan tanah. Kita lakukan ini tepat setelah kita panggil UpdatePhysics.

Dan kita tambahkan setiap frame selama kita berada di kondisi melompat.

Jika kita berada dalam kondisi melompat, kita tidak membolehkan aksi melompat di udara jika kita ada di langit-langit atau kita memiliki kecepatan vertikal yang positif. Kecepatan vertikal yang positif berarti karakter tidak melewatkan aksi melompat.

Jika tidak demikian, dan tombol melompat ditekan, yang perlu kita lakukan adalah mengatur kecepatan vertikal menjadi nilai melompat seperti jika melompat biasa walaupun karakter sudah berada dalam posisi melompat.

Sekian! Kita bisa atur cJumpFramesThreshold ke nilai yang besar seperti 10 frame untuk memastikannya bekerja.

Efek saat ini cukup berlebihan. Jika kita hanya memperbolehkan karakter melompat hanya 1-4 frame setelah meninggalkan platform tidak akan terlalu terlihat bedanya, tapi kurang lebih fitur ini membuat kita bisa mengatur seberapa tegas sistem melompat kita.

Mengubah Skala Objek

Sekarang kita buat agar kita bisa mengubah skala objek.  Kita sudah memiliki mScale pada kelas MovingObject, jadi yang perlu kita lakukan adalah memastikan nilai tersebut mempengaruhi AABB dan offset AABB dengan benar.

Pertama, kita ubah kelas AABB agar memiliki komponen skala.

Sekarang kita ubah halfSize, jadi saat kita mengaksesnya, kita mendapat nilai dari ukuran sesuai skala, bukan ukuran asli.

Kita juga ingin bisa mendapatkan atau mengatur nilai X atau Y dari half size, jadi kita perlu membuat fungsi getter dan setter untuk kedua nilai tersebut.

Selain mengatur skala AABB, kita juga perlu mengubah skala mAABBOffset, agar setelah kita mengubah skala objek, spritenya akan tetap sesuai dengan AABB seperti pada ukuran aslinya. Sekarang kita kembali ke kelas MovingObject untuk mengubahnya.

Sama dengan sebelumnya, kita ingin akses terhadap komponen X dan Y yang terpisah.

Akhirnya, kita juga perlu memastikan saat skala diubah di MovingObject, skala pada AABB juga berubah. Skala objek bisa negatif, tapi AABB tidak boleh memiliki skala negatif karena kita mengandalkan half size agar selalu positif. Karena itu, dibanding melemparkan nilai skala ke AABB, kita akan melemparkan skala yang memiliki semua komponen positif.

Sekarang yang perlu dilakukan adalah memastikan dimanapun kita menggunakan variabel secara langsung, kita menggunakannya dengan fungsi getter setter. Dimanapun kita menggunakan halfSize.x, kita perlu menggunakan HalfSizeX, jika menggunakan halfSize.y, kita perlu ganti jadi HalfSizeY, dan seterusnya. Dengan menggunakan fitur find and replace akan bisa menyelesaikan masalah ini.

Memeriksa Hasilnya

Pengaturan skala harusnya sudah bekerja dengan baik sekarang, dan karena cara kita menangani fungsi deteksi tabrakan, tidak masalah jika karakter berukuran raksasa atau kecil, karakter tersebut akan bisa berinteraksi dengan peta dengan baik.

Ringkasan

Bagian ini menyelesaikan tugas kita dengan tilemap. Di bagian berikutnya, kita akan mengatur berbagai hal untuk mendeteksi tabrakan antar objek.

Memang memakan waktu dan usaha, tapi sistem ini secara umum harusnya sangat baik. Satu hal yang kurang saat ini adalah kemampuan untuk menangani bidang miring. Banyak game tidak bergantung pada fitur tersebut, tapi sebagian sangat membutuhkannya, jadi itu adalah target pengembangan terbesar untuk sistem ini. Terima kasih sudah membaca sejauh ini, sampai jumpa di bagian berikutnya!

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.