After stating yesterday my despair at the lack of a float version of a rectangle for XNA, I went and did some research late last night and early this morning and after a load of bug fixing and random errors, it is alive! Or at least, now uses floats instead of ints. I haven’t gone back over my collision code beyond making it work as it did for ints, but considering everything looks the same right now, I’m pretty sure it won’t be too difficult. It also means moving forward I will be able to make future features like colliding of at an angle much easier.
I just wanted to write a brief explanation here so that if anyone else is curious they will know how to in the future. So my google search lead me to my own lecturers website, http://www.robmiles.com/journal/2011/4/17/positioning-sprites-with-rectangles-and-vectors-in-xna.html, where Rob explains rectangle positioning using Vectors. When I realised this was possible I started to look over the overloads for SpriteBatch.Draw to see which I could use for Vector based assets. I found “SpriteBatch.Draw (Texture2D, Vector2, Nullable, Color, Single, Vector2, Vector2, SpriteEffects, Single)” which draws a texture at a specified location with a specified scale. This allows the provisional use of floats instead of ints to define positions (huzzah).
So I had the first stages, and for testing purposes I did a lot of slow change overs; changing the Rectangle.X uses to Position.X, using Vectors etc. After this I realised the easiest way for me to implement the new Draw method would be to recreate the Rectangle class as the new Rectanglef, which uses floats and vectors. At a basic level this involves just replicating any functions I have used (X,Y,Width,Height,Top,Bottom etc), but this will mean in the future I can write in my own version of intercept which may work properly, we’ll see. Once I had created this method, I wrote into the constructors for my top-level classes to transfer the Rectangle data into Rectanglef and then renamed all the Rectangle uses to be Rectanglef.
While on the subject of setting up, there was one other issue where the Scale part of the .Draw method scales and image based on the size of the original texture, which is clearly very unhelpful when we want a game which is playable on multiple resolutions. The solution to this for me was to have the scale as 1/ the texture width or height then multiplied by the value I actually wanted that had been put into to initial rectangle; 1f / (float)_texture.Width * _rectangle.Width.
This all means I could use the code almost exactly as it was with a few renames and changed variables and the new Draw method. For your reference here is the Rectanglef class if you want to use it in the future. If you think of anything else you can add to it please feel free to message me, but the version below is the simplest form I needed at the time:
class Rectanglef
{
public float X;
public float Y;
public float Width;
public float Height;
public Rectanglef(float x, float y, float width, float height)
{
X = x;
Y = y;
Width = width;
Height = height;
}
public float Top
{
get { return Y; }
}
public float Bottom
{
get { return Y + Height; }
}
public float Left
{
get { return X; }
}
public float Right
{
get { return X + Width; }
}
public Vector2 Position
{
get { return new Vector2(X,Y); }
}
}
Leave a Reply