Saya saat ini sedang mempelajari pengembangan game dan berlatih membuat game.
Saya menggunakan banyak OOP di game saya. Misalnya, setiap rudal yang ditembak adalah turunan dari sebuah Missile
objek, dan ditambahkan ke daftar Missile
objek. Setiap tangki dalam game adalah Tank
objek. Dll
Seluruh desain program didasarkan pada ini. Sebagai contoh, memiliki daftar Missile
objek memungkinkan saya setiap frame untuk memindahkan rudal, menggambar mereka, dll. Dan memiliki instance Tank
objek untuk setiap tangki memungkinkan saya untuk memeriksa setiap tangki jika bertabrakan dengan sesuatu, dll.
Sulit bagi saya untuk membayangkan bagaimana sebuah game (yang lebih kompleks dari Pac-Man) dapat diprogram dalam bahasa non-OO. (Tanpa rasa tidak hormat kepada programmer non-OO tentu saja). Tidak hanya dalam hal berapa lama waktu yang dibutuhkan, tetapi sebagian besar dalam hal bagaimana sebuah game dapat dirancang dengan cara ini.
Saya tidak dapat membayangkan mendesain game tanpa menggunakan pemrograman berorientasi objek, karena seluruh pemahaman saya tentang bagaimana merancang sebuah game-program didasarkan pada OOP.
Saya ingin bertanya: Hari ini, apakah ada game yang tidak diprogram menggunakan OOP, serupa dengan yang saya jelaskan di atas? Apakah ada game 'profesional' yang tidak menggunakan OOP sebagai faktor utama dalam proses pengembangan?
Jika demikian, dapatkah Anda memberi saya gagasan tentang bagaimana, misalnya, deteksi tabrakan antara tank dan sejumlah rudal dapat diimplementasikan, tanpa OOP?
sumber
Jawaban:
Maka mungkin akan baik bagi Anda untuk mencoba menulis beberapa program dengan gaya non-OO. Bahkan jika Anda menemukan bahwa ini tidak pragmatis untuk Anda, Anda mungkin akan belajar banyak di sepanjang jalan yang akan membantu Anda di masa depan.
Gaya OO sangat cocok untuk permainan karena permainan hampir selalu tentang manipulasi objek stateful. Sinar laser mengenai robot dan keadaan robot berubah sementara identitasnya tetap sama.
Namun dimungkinkan untuk memprogram game dengan gaya fungsional . Dalam gaya fungsional, status tidak berubah. Objek tidak berubah. Daripada mengubah benda, Anda bertanya pertanyaan bagaimana jagat raya akan berbeda jika saya mengubah ini? dan kemudian menghasilkan seluruh alam semesta baru yang memiliki properti yang berubah. Tentu saja, Anda dapat menggunakan kembali banyak dari alam semesta yang ada sebelumnya karena tidak dapat diubah .
Dalam pemrograman fungsional setiap fungsi harus menghitung nilai kembalinya semata-mata dari informasi yang diteruskan; tidak ada bacaan dari "negara global".
Jika Anda melakukan ini, masalah mendasar yang harus Anda lewati adalah setiap pembaruan tidak merusak . Saat laser mengenai robot, Anda tidak mengubah kondisi robot. Pada akhirnya Anda menghitung semesta yang sama sekali baru yang identik dengan alam semesta lama kecuali bahwa robot memiliki keadaan yang berbeda; jika Anda membutuhkan alam semesta lama itu, ia masih ada di sana, tidak berubah.
Seri artikel blog ini memiliki lebih banyak pemikiran tentang menulis game dengan gaya fungsional:
http://prog21.dadgum.com/23.html
Artikel ini secara khusus menjawab pertanyaan "shell hits a tank" Anda:
http://prog21.dadgum.com/189.html
Bahkan, baca saja seluruh blog. Ada barang bagus di sana dan artikelnya pendek.
sumber
Setiap program berorientasi objek dapat dire-refored ke program prosedural dengan mengganti semua kelas dengan struktur dan mengubah semua fungsi anggota menjadi fungsi yang berdiri sendiri yang mengambil objek yang akan menjadi
this
argumen.Begitu
menjadi
atau ketika fungsi itu sepele, Anda cukup melakukannya
Perbedaan utama antara pemrograman berorientasi objek dan pemrograman prosedural adalah bagaimana Anda memperlakukan data Anda. Dalam OOP, data cerdas . Ia mengelola dan memanipulasi dirinya sendiri. Namun dalam pemrograman prosedural, data bodoh . Itu tidak melakukan apa-apa sendiri dan perlu dimanipulasi dari luar.
Ketika Anda bahkan menganggap struktur terlalu berorientasi objek, Anda dapat mengganti satu susunan struktur dengan banyak susunan, satu untuk semua yang merupakan variabel dari rudal. Begitu
menjadi
Dalam desain ini, suatu fungsi yang melakukan operasi yang melibatkan banyak atribut pada rudal yang sama sekarang akan mengambil indeks array bukan referensi ke struktur. Implementasinya akan terlihat seperti ini:
sumber
missile
merupakan contoh dari suatu objek. Dalam non-OOP, tidak ada contoh, apakah saya benar? Jika demikian, bagaimana Anda bisa melakukan setMissileVelocity (rudal, 100)?Missile
, yang merupakan struktur dengan beberapa bidang, sepertix
,y
,angle
danvelocity
.Saya melakukannya sebagai berikut:
this
. Untuk memanfaatkanthis
dalam pendekatan non-OO, cukup berikan contoh apa pun (lihat poin berikutnya)this
, sebagai parameter pertama.struct
fungsi-fungsi Andathis
, tetapi saya menemukan cara terbaik untuk mencapai kinerja cache yang baik untuk objek yang produktif, seperti entitas atau partikel, adalah dengan hanya mengirimkan indeks tunggal ke beberapa array primitif. ataustruct
s kecil . Jadi indeks ini digunakan untuk setiap anggota data individu dari kelas asli. Jadi misalnya jika Anda punya...
Anda akan menggantinya dengan
Sehingga Anda sekarang melewati sebuah indeks ke dalam fungsi untuk mendapatkan apa yang biasanya
this
.Ingatlah bahwa Anda mungkin ingin menggunakan array primitif seperti di atas, atau array
struct
s, tergantung pada cara terbaik untuk interleave data Anda untuk lokalitas cache yang baik (lokalitas referensi). Tentu saja, kinerja cache yang layak bergantung pada lebih dari ini - terutama, bahasa apa / platform Anda menulis kode Anda - tetapi bahkan dalam VM berbasis, bahasa yang dialokasikan secara dinamis seperti Jawa, array linear besar primitif cenderung menampilkan karakteristik kinerja yang lebih baik daripada instance objek. Alasan utama untuk ini adalah bahwa objek diakses dengan referensi dan ini berarti Anda melompati seluruh memori untuk mengakses data - tidak efisien dibandingkan dengan mengakses primitif secara berdekatan dari array besar.Untuk informasi lebih lanjut tentang membangun entitas dll sebagai array struct atau primitif, lihat Mick West's Evolve Hierarchy Anda .
sumber
Selain jawaban yang ada, Anda mungkin ingin tahu bagaimana melakukan polimorfisme dalam bahasa prosedural.
Ada dua pendekatan:
Menyimpan tipenya
Dalam hal ini struct memiliki bidang untuk pengenal tipe, mungkin enum, yang diperiksa menggunakan
switch
pernyataan ketika jenis tindakan spesifik perlu dilakukan.Cara lainnya adalah:
Menyimpan pointer fungsi
Anda tidak menyebutkan bahasa pemrograman tempat Anda memiliki pengalaman, tetapi dalam berbagai bahasa mereka juga disebut panggilan balik, delegasi, acara atau fungsi urutan tinggi atau hanya objek fungsi.
Dalam hal ini Anda tidak akan menyimpan tipe, tetapi menyimpan pointer / referensi ke fungsi yang melakukan tindakan tertentu. Ketika jenis tindakan spesifik perlu dilakukan, Anda cukup memanggil fungsi ini. Yang ini sangat mirip dengan metode virtual biasa.
Dengan memungkinkan pengaturan setiap fungsi secara mandiri Anda mendapatkan pola strategi gratis.
Mengenai paragraf terakhir Anda dengan deteksi tabrakan. Saya pikir Anda mungkin memiliki beberapa jenis tank dan Anda memiliki beberapa jenis rudal, dan setiap kombinasi berpotensi memiliki hasil yang berbeda ketika mereka bertabrakan. Jika ini yang Anda cari, Anda memiliki masalah yang belum diselesaikan oleh bahkan bahasa OOP: pengiriman ganda dan multi-metode yang dapat memiliki banyak
this
parameter dari jenis yang berbeda. Untuk masalah ini ada lagi dua alternatif:sumber