Bagaimana menangani fisika platform yang bergerak dalam platformer?


8

Jadi setelah beberapa jam mencari di internet, saya belum menemukan jawaban yang menyenangkan tentang bagaimana menangani platform bergerak dalam game platform 2d. Jadi saya memutuskan untuk membuat prototipe sederhana di mana Anda berinteraksi dengan 2 platform yang berbeda, yang bergerak secara vertikal dan satu secara horizontal. Saya ingin bantuan untuk membedah dan melihat apa yang tidak berfungsi, dan bagaimana cara memperbaikinya. Saya telah mengirimkan file .fla + .as file di bawah ini, disertai dengan tautan ke file .swf yang dapat diputar.

Tujuannya adalah untuk membuat Pahlawan berinteraksi dengan platform seolah-olah mereka adalah benda padat yang dapat ia berdiri di atasnya, didorong bersama, melompat ke / di bawah dll.

Masalah dengan prototipe saya adalah ini:

  • Ketika Anda berdiri di platform yang bergerak secara horizontal, tanpa bergerak (tidak menyentuh tombol apa pun), Pahlawan bergerak bersama dengan platform, tetapi dengan sedikit keterlambatan menyebabkan pahlawan bergeser sedikit ke belakang.

  • Ketika Anda berdiri di platform yang bergerak secara horizontal, dan melompat, Anda bergerak bersama dengan platform di udara (beberapa game lebih suka memilikinya seperti ini, tetapi itu tidak terasa alami dan tidak diinginkan di sini). Yang mungkin disebabkan oleh Pahlawan mempertahankan kecepatan pada sumbu X dari platform.

  • Ketika Anda melompat ke sisi bawah pada platform yang bergerak secara vertikal, sementara platform bergerak ke bawah, Anda tenggelam di dalamnya sebentar. Pahlawan menembus seolah-olah tabrakan itu tidak ada untuk sesaat.

  • Ketika Anda melompat pada platform yang bergerak secara vertikal, veloctiy pada sumbu Y dipertahankan, jadi ketika Anda berjalan keluar dari platform, Anda jatuh pada kecepatan yang lebih tinggi. Dengan kecepatan kecepatan yang dipertahankan, + gravitasi yang ditambahkan (ini sebagian besar karena saya tidak dapat menemukan cara untuk mengatur ulang kecepatan pada sumbu Y ke 0 ketika Anda mendarat di platform, tanpa pemain membeku di udara).

Saya seorang programmer pemula jadi saya yakin ada cara yang LEBIH BAIK untuk melakukan ini, dan saya ingin mendengar semuanya. Setiap ide tentang cara meningkatkan kode atau metode lain di mana Anda dapat mengimplementasikan platform yang bergerak ke dalam game berbasiskan permainan dipersilakan. Pada akhirnya, saya mencoba menemukan cara yang mantap untuk menangani platform yang bergerak di platformer 2d.

SWF yang dapat diputar: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.html (Bergerak dengan tombol panah, Lompat dengan tombol X, Jalankan dengan tombol Z)

Sourcecode AS-file: http://dl.dropbox.com/u/28271061/Platformerhowto.as

SourcefileFLA: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.fla

Jika Anda lebih suka membaca kode melalui Pastie online: http://pastie.org/2266764



Saya membaca utas itu, tetapi karena saya tidak menggunakan node dengan cara apa pun, rasanya seperti tidak menyelesaikan masalah. Game yang saya bangun berbasis ubin, tetapi platform yang bergerak akan diimplementasikan seperti di atas (bergerak bebas). Menggunakan node akan membutuhkan penulisan ulang mesin saya secara keseluruhan, yang sudah lama saya habiskan. Saya kira saya berharap seseorang akan melihat kode dan menawarkan solusi yang mirip dengan apa yang diusulkan, atau menemukan peningkatan pada kode.
Kid

Anda akan menggunakan node setelah Anda mengimplementasikan solusi itu untuk memindahkan platform, bahkan jika itu satu-satunya tempat Anda menggunakannya. Ini akan menyelesaikan masalah geser Anda.
doppelgreener

2
"(beberapa permainan lebih suka memilikinya seperti ini, tetapi tidak terasa alami dan tidak diinginkan di sini)" Bagaimana tidak "terasa alami"? Google Inersia dan Momentum ...
Riki

1
@Felheart, Alami dalam hal bermain game, bukan dunia fisik nyata. Jika Anda memainkan Super Mario Bros atau platformer klasik mana pun, Anda akan melihat bahwa mereka TIDAK menjaga momentum saat melompat di platform yang bergerak. Ini mengganggu perasaan berdiri dan berinteraksi dengan platform yang bergerak.
Kid

Jawaban:


17

Mari pisahkan masalah Anda menjadi masalah yang berbeda ...

Sebuah kata tentang kualitas kode

Kode Anda saat ini memiliki platform Anda secara langsung mengendalikan kecepatan pemain Anda dan bahkan konstanta gravitasi dunia . Ini hacky, dan ini prosedural ketika harus berorientasi objek. Setelah Anda mulai mengembangkan game ini, segalanya akan menjadi sangat cepat .

Anda perlu memperbaiki kode Anda. Menerapkan kelas pemain, kelas platform, dan kelas lantai. Pisahkan kekhawatiran mereka: minta pemain mengartikan kontrol keyboard dan mengontrol bagaimana dia berlari dan melompat, dan minta platform mengubah momentumnya seperlunya (dengan menambahkan kecepatan mereka sendiri ke kecepatan pemain yang sudah ditentukan, bila perlu).

Mintalah pemain Anda menentukan di mana benda tersebut terkait dengan objek bertipe lantai (platform dan lantai sama-sama memiliki BodyType = BodyTypes.Floor, atau sesuatu) dan tentukan sendiri di mana benda tersebut mengenai benda itu, bagaimana ia harus bereaksi dan apakah benda itu jatuh atau di tanah.

Ini mungkin pantas mendapatkan topik yang terpisah karena ini merupakan masalah yang terpisah dari semua yang Anda kemukakan. Namun, Anda harus melakukannya di beberapa titik.

Inersia horizontal / vertikal saat meninggalkan platform

Untuk mengatasi masalah kecepatan vertikal dan horizontal Anda, perhatikan dua hal:

  • Mengenai kecepatan horizontal: Kode Anda hanya mengatur kecepatan horizontal ke 0 ketika pemain menyentuh tanah (pada garis Pastie 200) atau platform.
  • Mengenai kecepatan vertikal: Pemain Anda memiliki akselerasi jatuh yang konstan. Ketika dia berjalan dari platform vertikal, akselerasi jatuh ini terus ditambahkan ke gerakannya yang sudah menurun.

Pemain Anda hanya menderita inersia : momentumnya dipertahankan hingga sesuatu menghentikannya.

Solusi: Kedua masalah akan diselesaikan dengan solusi jSepia untuk Bagaimana cara menangani platform yang bergerak dalam game platform? karena akan sepenuhnya memisahkan proses pergerakan pemain dari bagaimana platform memindahkannya. Anda tidak akan jatuh lebih cepat saat berjalan dari platform vertikal dan tidak akan menjaga momentum horizontal Anda melompat dari platform horizontal, karena platform tidak akan lagi mempengaruhi vx dan vy pemain Anda .

Catatan: Anda mungkin mengalami kesulitan dalam mengimplementasikan solusi jSepia sebelum kode Anda di-refactored.

Menyelip dari sisi ke sisi di sekitar platform horisontal

Pemain Anda sebenarnya tidak bergerak secara horizontal secepat platform bergerak. Tidak jelas bagi saya mengapa. Masalah ini mungkin juga akan diselesaikan dengan mengimplementasikan solusi jSepia dan dengan benar melakukan refactoring kode Anda (yang terakhir hanya akan membuat penyebabnya menjadi jelas).

Deteksi tabrakan: tumpang tindih dengan platform vertikal

Lihat garis Pastie 381: setiap langkah itu mengatur ulang vy pemain ke 0 selama pemain bertabrakan dengan bagian bawah platform vertikal. Pada langkah berikut, vy ditingkatkan oleh percepatan gravitasi dan kemudian pemain dipindahkan (dan kemudian diatur ulang ke 0 lagi).

Ini berarti selama pemain Anda bertabrakan dengan bagian bawah platform, dia bergerak ke bawah dengan kecepatan konstan (gravitasi konstan). Platform vertikal lebih cepat dari itu sehingga tumpang tindih dengannya. Jika platform vertikal bergerak dari jarak yang lebih jauh, platform akan meluncur ke arahnya sampai pemain terdaftar berdiri di atas platform.

Solusi: Jangan mengatur ulang vy pemain ke 0. Cukup atur vy pemain ke kecepatan vertikal platform ( jika platform bergerak ke bawah ). Pemain Anda kemudian akan menjauh dari platform vertikal setidaknya secepat platform, dan mempercepatnya.


Luar biasa! Pertama terima kasih atas solusi untuk melompat dan menembus platform vertikal (berhasil!). Dan kedua, Anda benar, kode ini mengerikan di negara bagian ini. Meskipun ini bukan gim itu sendiri, ini adalah prototipe cepat yang dibuat untuk bereksperimen dan memahami platform bergerak dengan lebih baik. Namun demikian, jika saya menerjemahkan ini ke kode permainan yang sebenarnya, saya harus menyimpan kode yang lebih terstruktur dan berorientasi objek. Ini akan memperlancar transfer. Sekarang, mengenai solusi jSpeias, saya pikir saya mendapatkan konsep node-tree, hanya saja saya tidak tahu bagaimana cara mengimplementasikannya dengan benar.
Kid

Pikiran pertama saya adalah membuat nilai-nilai Boolean yang akan menggambarkan status pemain, seperti: "onFloor", "onPlatform", "onGround", "jatuh", "melompat", dll. Dan kemudian jalankan melalui pernyataan-if di enterFrame event yang memeriksa keadaan saat ini dan mengubah properti Pemain yang sesuai (?) Misalnya: if (Hero.onPlatform == true) {Player.x = platform.x (relatif terhadap pemain global x);}. Sesuatu dengan cara itu.
Kid

Saya sedang mengerjakannya ketika kita berbicara, tetapi pada saat yang sama saya memisahkan kode ke dalam kelas yang berbeda seperti yang Anda sarankan, yang juga sedikit membingungkan (berkomunikasi antara platform / tabrakan / kelas pemain membungkuk pikiran).
Kid

@ Kid: Playermemiliki metode GetPositiondan variabel internal parent(untuk simpul induknya) dan position(untuk posisinya relatif terhadap induknya). Player.GetPosition()kembali position + parent.GetPosition(). Induknya melakukan hal yang sama hingga Anda mencapai akar pohon - simpul dunia. Ketika pemain Anda bergerak, Anda hanya berurusan dengan positionvariabel pribadi . Pemain Anda ditarik pada layar game sesuai dengan GetPosition()nilai. Saya akan memberitahu Anda bagaimana transisi antar node. ;)
doppelgreener

Memiliki kelas pemain yang mengetahui cara memodifikasi kecepatannya sendiri tentu saja tidak menjunjung tinggi pemisahan kekhawatiran
Andy Ray
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.