9
\$\begingroup\$

As part of my simple Ruby 2D game development framework, my game objects have position (x and y values) and size (width and height).

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

Another approach I've seen was treating the position as a Point structure, and the size as a Size structure:

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

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

Some frameworks use the former (I think GDX, Gosu...). Others use the latter (cocos2d-iphone). The problem is, it isn't entirely clear to me the advantages and disadvantages of both behaviors (in game development) - I don't know why some frameworks chose one and not the other.

Are there significant differences I should consider?

\$\endgroup\$

2 Answers 2

8
\$\begingroup\$

Some even use the Rectangle class:

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

It's just a choice of design, it doesn't really matter. If you're doing your own code, make what you feel more confortable. If you're using some API, framework or engine, or editing/modding a game, try to be consistently with the rest of the code and do just like is in nearby code.

I would say to go with two separate vectors, like this:

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

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

This way you can handle things like angle between objects easier, like so:

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

instead of having to extract the vectors from rectangles, or create them from plain floats.

\$\endgroup\$
2
\$\begingroup\$

In general, always use a separate data structure. It makes your code significantly easier to use, read, and maintain. How often do you need x separate from y vs how often do you need to calculate a vector offset, length, dot product, etc.? Aim for the common case; make the code you write repeatedly easier to work with, which for points and vectors, is typically going to be operations on the entire "object" rather than operations on individual components.

The only exception I would make is, after properly profiling, you find the separate structure is too slow. Languages like Ruby do not make simple user-defined "by-value" possible and, in my experience, having points and vectors be "by-reference" types is both a pain at times and can be a massive slowdown without careful attention to temporaries. It can be advantageous, for instance, to have two arrays of ints, one for x and one for y, then to have a single array of Point objects; it's much more of a pain to work with though so only do that split if you have valid performance metrics to indicate it's worthwhile!

\$\endgroup\$
2
  • \$\begingroup\$ +1, but i'd like to mention that preoptimization is the root of all evil. \$\endgroup\$ Jul 9, 2013 at 21:01
  • 3
    \$\begingroup\$ @GustavoMaciel: indeed. Fact: Cruella de Vil was just trying to optimize her wardrobe before cleaning up her personality, and look where that got her. \$\endgroup\$ Jul 9, 2013 at 21:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .