Kapan saya harus mewakili titik dan ukuran sebagai struktur?


9

Sebagai bagian dari kerangka kerja pengembangan game Ruby 2D yang sederhana, objek permainan saya memiliki posisi (nilai x dan y) dan ukuran (lebar dan tinggi).

class MyGameObject
  attr_accessor :x
  attr_accessor :y
  attr_accessor :width
  attr_accessor :height
  ...

Pendekatan lain yang saya lihat adalah memperlakukan posisi sebagai Pointstruktur, dan ukuran sebagai Sizestruktur:

Point = Struct.new(:x, :y)
Size = Struct.new(:width,:height)

class MyGameObject
  attr_accessor :position   # Point instance
  attr_accessor :size       # Size instance
  ...

Beberapa kerangka kerja menggunakan yang pertama (saya pikir GDX, Gosu ...). Lainnya menggunakan yang terakhir (cocos2d-iphone). Masalahnya adalah, tidak sepenuhnya jelas bagi saya keuntungan dan kerugian dari kedua perilaku (dalam pengembangan game) - Saya tidak tahu mengapa beberapa kerangka kerja memilih satu dan bukan yang lain.

Apakah ada perbedaan signifikan yang harus saya pertimbangkan?

Jawaban:


8

Beberapa bahkan menggunakan Rectanglekelas:

class Rectangle
{
    float x, y, w, h;
}
class GameObject
{
    Rectangle dimensions;
}

Ini hanya pilihan desain, tidak masalah. Jika Anda melakukan kode Anda sendiri, buat apa yang Anda rasa lebih nyaman. Jika Anda menggunakan beberapa API, kerangka kerja atau mesin, atau mengedit / memodifikasi permainan, cobalah untuk secara konsisten dengan sisa kode dan lakukan seperti yang ada di kode terdekat.

Saya akan mengatakan untuk pergi dengan dua vektor terpisah, seperti ini:

class Vector2
{
    float x, y;
    //helper functions like operator overload, dot, length, distance, etc.
}

class GameObject
{
    Vector2 position;
    Vector2 size;
    Vector2 direction;
}

Dengan cara ini Anda dapat menangani hal-hal seperti sudut antara benda lebih mudah, seperti:

GameObject foe;
GameObject player;
Vector2 dist = player.position - foe.position;
dist.normalize();
float angleBetween = acos(dist.dot(foe.direction));

alih-alih harus mengekstrak vektor dari persegi panjang, atau membuatnya dari mengapung polos.


2

Secara umum, selalu gunakan struktur data yang terpisah. Itu membuat kode Anda secara signifikan lebih mudah digunakan, dibaca, dan dipelihara. Seberapa sering Anda perlu xmemisahkan dari yvs seberapa sering Anda perlu menghitung offset vektor, panjang, titik produk, dll? Bertujuan untuk kasus umum; membuat kode yang Anda tulis berulang kali lebih mudah untuk dikerjakan, yang untuk titik dan vektor, biasanya akan menjadi operasi pada seluruh "objek" daripada operasi pada komponen individu.

Satu-satunya pengecualian yang akan saya buat adalah, setelah memprofilkan dengan benar , Anda menemukan struktur terpisah terlalu lambat. Bahasa seperti Ruby tidak membuat "nilai-nilai" yang didefinisikan oleh pengguna menjadi mungkin dan, dalam pengalaman saya, memiliki titik dan vektor menjadi tipe "menurut referensi" kadang-kadang terasa menyakitkan dan dapat menjadi pelambatan besar tanpa perhatian yang hati-hati pada waktu. . Sebagai contoh, dapat menguntungkan untuk memiliki dua array int, satu untuk xdan satu untuk y, kemudian memiliki satu array Pointobjek; itu jauh lebih menyebalkan untuk dikerjakan, jadi hanya lakukan pemisahan itu jika Anda memiliki metrik kinerja yang valid untuk menunjukkan bahwa itu layak!


+1, tetapi saya ingin menyebutkan bahwa preoptimisasi adalah akar dari semua kejahatan.
Gustavo Maciel

3
@GustavoMaciel: memang. Fakta: Cruella de Vil hanya mencoba mengoptimalkan pakaiannya sebelum membersihkan kepribadiannya, dan mencari tahu di mana itu membuatnya.
Sean Middleditch
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.