4

Why Vector2 (from XNA's library) uses float not int?

Position on computer screen is given in pixels so that cursor position can be defined by two integers. There is no such a thing like half a pixel. Why we use floats then?

In SpriteBatch class I've found 7 overloaded methods called Draw. Two of them:

public void Draw(Texture2D texture, Rectangle destinationRectangle, Color color);
public void Draw(Texture2D texture, Vector2 position, Color color);

So we can see that Draw accepts both int and float coordinates.

I came across this problem when I've been implementing screen coordinates of my game's objects. I assumed that Rectangle is good choice to hold object's size and screen coordinates. But now I'm not sure...

mskfisher
  • 3,291
  • 4
  • 35
  • 48
patryk.beza
  • 4,876
  • 5
  • 37
  • 56
  • When you're working with scalars, always use decimal numbers. or if you have a speed at 0.1f, and you keep adding it to a int, the position will remain the same. But with a float this will make your position keep increasing. – Gustavo Maciel May 05 '12 at 08:55
  • @patryk -The Vector2 is used for so many other things besides simply screen pixel positions. Most of the other uses involve arithmetic where precision finer than whole numbers is desired. – Steve H May 05 '12 at 17:37
  • Also, using `Draw(Texture2D, Rectangle, Color)` you can 'scale' texture to destination rectangle, but `Draw(Texture2D, Vector2D, Color)` will use `Texture2D`s `.Width` and `.Height`. – SkillGG Apr 19 '19 at 22:41

3 Answers3

6

Mathematically, a vector is a motion, not a position. While a position on the screen might not technically be able to be between integers, a motion definitely can. If a vector used ints then the slowest you could move would be (1, 1). With floats you can move (.1, .1), (.001, .001), and so on.

(Notice also that the XNA struct Point does actually use ints.)

Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80
4

You could use both Vector2 and Rectangle to represent your objects coordinates. I usually do it like this:

public class GameObject
{
    Texture2D _texture;

    public Vector2 Position { get; set; }
    public int Width { get; private set; } //doesn't have to be private
    public int Height { get; private set; } //but it's nicer when it doesn't change :)

    public Rectangle PositionRectangle
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }
    }

    public GameObject(Texture2D texture)
    {
        this._texture = texture;
        this.Width = texture.Width;
        this.Height = texture.Height;
    }
}

To move objects, just set their Position property to a new value.

_player.Position = new Vector2(_player.Position.X, 100);

You don't have to worry about the rectangle, as it's value depends directly on Position.

My game objects also usually contain methods to draw themselves, such as

public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
{
    spriteBatch.Draw(this._texture, this.Position, Color.White);
}

Collision detection code in your Game.Update() could just use the PositionRectangle to test for collisions

//_player and _enemy are of type GameObject (or one that inherits it)
if(_player.PositionRectangle.Intersects(_enemy.PositionRectangle))
{
    _player.Lives--;
    _player.InvurnerabilityPeriod = 2000;
    //or something along these lines;
}

You could also call the spriteBatch.Draw() with PositionRectangle, you shouldn't notice much difference.

neeKo
  • 4,280
  • 23
  • 31
3

There is such a thing as "half a pixel." Using float coordinates that aren't pixel-aligned will cause your sprites to be rendered at sub-pixel coordinates. This is often necessary to make objects appear to scroll smoothly, but it can also produce an unpleasant shimmering effect in some circumstances.

See here for a summary of the basic idea: Subpixel rendering

Cole Campbell
  • 4,846
  • 1
  • 17
  • 20
  • So what structure should I use to remember object's size (in __float__) and screen coordinates (also __float__). **Rectangle** would be perfect but it uses __int__. I'm looking for __float__ **Rectangle** equivalent without creating my own structure (I don't want to reinvent the wheel if you know what I mean;)). – patryk.beza May 05 '12 at 11:41
  • In my 2D games I generally just use Vector2 for position and a Rectangle for bounding, as Niko Drašković described in his answer. – A-Type May 08 '12 at 00:03