Noktaları ve boyutları ne zaman yapılar olarak göstermeliyim?


9

Basit Ruby 2D oyun geliştirme çerçevemin bir parçası olarak, oyun nesnelerimin konumu (x ve y değerleri) ve boyutu (genişlik ve yükseklik) var.

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

Gördüğüm başka bir yaklaşım, pozisyona bir Pointyapı olarak ve boyutun bir Sizeyapı olarak ele alınmasıydı:

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

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

Bazı çerçeveler ilkini kullanır (sanırım GDX, Gosu ...). Diğerleri ikincisini kullanır (cocos2d-iphone). Sorun şu ki, her iki davranışın da avantajlarını ve dezavantajlarını (oyun geliştirmede) tamamen açık değil - bazı çerçevelerin neden diğerini seçtiğini bilmiyorum.

Dikkate almam gereken önemli farklılıklar var mı?

Yanıtlar:


8

Hatta bazıları Rectanglesınıfı bile kullanıyor :

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

Bu sadece bir tasarım seçeneği, gerçekten önemli değil. Kendi kodunuzu yapıyorsanız, kendinizi daha rahat hissedin. Bazı API, çerçeve veya motor kullanıyorsanız veya bir oyunu düzenliyor / değiştiriyorsanız, kodun geri kalanıyla tutarlı bir şekilde olmaya çalışın ve tıpkı yakındaki kodda olduğu gibi yapın.

Böyle iki ayrı vektör ile gitmek söyleyebilirim:

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

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

Bu şekilde nesneler arasındaki açı gibi şeyleri daha kolay işleyebilirsiniz:

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

vektörleri dikdörtgenlerden çıkarmak veya düz şamandıralardan oluşturmak yerine.


2

Genel olarak, her zaman ayrı bir veri yapısı kullanın. Kodunuzun kullanımını, okunmasını ve bakımını önemli ölçüde kolaylaştırır. Ne sıklıkla gerek yok xayrı yne sıklıkta vs vb, bir vektör ofset hesaplamak için uzunluk ihtiyaç ürünü nokta mı? Ortak vakayı hedefleyin; Noktalar ve vektörler için genellikle tek tek bileşenler üzerindeki işlemler yerine tüm "nesne" üzerindeki işlemler olacak şekilde yazdığınız kodun çalışmasını tekrar tekrar kolaylaştırır.

Yapacağım tek istisna, düzgün bir şekilde profil oluşturduktan sonra ayrı yapının çok yavaş olduğunu görüyorsunuz. Ruby gibi diller, kullanıcı tanımlı basit "değer-değeri" mümkün kılmaz ve benim tecrübelerime göre, nokta ve vektörlerin "referans" türler olması hem zaman zaman hem de acıdır ve geçicilere dikkat etmeden büyük bir yavaşlama olabilir. . Örneğin, biri için xbiri diğeri için olmak üzere iki veri dizisine sahip olmak y, sonra tek bir Pointnesne dizisine sahip olmak avantajlı olabilir ; Bununla birlikte çalışmak çok daha acı vericidir, bu yüzden bunu sadece değerli bir performans ölçütünüz varsa değerli kılın!


+1, ama ön optimizasyonun tüm kötülüğün kökü olduğunu belirtmek isterim.
Gustavo Maciel

3
@GustavoMaciel: gerçekten. Gerçek: Cruella de Vil kişiliğini temizlemeden önce gardırobunu optimize etmeye çalışıyordu ve ona nereden geldiğine bakın.
Sean Middleditch
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.