-
|
|
What the heck? Rectangle collision and origin problems...
|
Hello,
I've been happy playing with Rectangles in XNA. So far everything has been great when I call the Intersects() function and the SpriteBatch.Draw() hasn't been an issue. Till now anyway, recently I wanted to include rotation in on my draw loop, and some funky things have been happening...
Normally, using the origin parameter of SpriteBatch.Draw(), I use 0,0. This keeps collision for my rectangles fine, but when I rotate them, they rotate from the upper left corner. I do not want this. I need them to rotate from the center of the rectangle, so I've been using rectangle width / 2, height / 2, for the origin parameter. This makes rotation work fine like I wanted it too, but COMPLETELY messes up the location fields of the rectangle! Now everything I draw is actully located halfway down from where it should be(where the top of the image first starts, so basically the rectangle's location is drawn halfway down where the target image appears).
What gives? What do I do? Why does it happen like this? It appears the Draw() funciton is actually physically messing with the location fields of the rectangle. It seems to purposely go out of it's way to set the top and bottom fields(Or I should say X and Y fields) of the rectangle to the that of the origin, yet the image still gets drawn starting halfway up from where the rectangle starts.
I'd like to keep using Rectangles, and SpriteBatch.Draw(), but I need to be able to rotate rectangles by the center, and not the corner. Any suggestions?
|
|
-
|
|
Re: What the heck? Rectangle collision and origin problems...
|
I can think of a few ways this might be going wrong for you. Could you post some of your drawing code so we can see exactly what you're doing?
|
|
-
-
- (2459)
-
premium membership
-
Posts
722
|
Re: What the heck? Rectangle collision and origin problems...
|
Can't you just subtract new Vector2(width/2, height/2) from your position? This seems normal when the origin isn't in the top corner.
|
|
-
|
|
Re: What the heck? Rectangle collision and origin problems...
|
Also the origin is based on the source rectangle size, not the dest rectangle size.
Game hobbyist hell-bent on coding a diabolical Matrix
|
|
-
|
|
Re: What the heck? Rectangle collision and origin problems...
|
Well, if you need to see what's going on I will, but it's a very simple program... I'm mainly concerned about the spriteBatch.Draw() method, and why it's messing with the location of the rectangle.
When I draw 2 sprites using a new Vector2(0,0) for the origin, the Intersects function works fine. The Top and Bottom properties of the rectangle are correct.
In my update routine, I have a width + height method that will increase the width and the height of the player's rectangle.
After calling this method, the Intersects function still works fine! An enlarged rectangle will intersect with another unenlarged rectangle no problem.
However I'm still rotating the sprites by the corner, not the center.
Now, when I use sprite.width /2 and sprite.height /2 for the origin, the rotation works like I want it too!
But then the properties of the rectangle get all messed up. The location of the rectangle becomes the origin! If I move the rectangle to the top of the screen(0,0), the upper half and left side of the sprite become invisible, because it's located off screen, because it's new "origin" is the center of the rectangle, not the top left.
Which makes sense, because I set the origin to (/2,/2) but the only reason I'm setting the origin to that is so the rotation of the sprite will rotate by the center and not the top. With the origin being set to the center of the rectangle, the rectangle's new location becomes the origin. The Top and Bottom properties are also affected by the origin(the top is considered the center, and the bottom is considered below where it normally is...). The "Center" property is effected too!
This all happens when I use a new origin for spriteBatch.Draw(), and scarier yet is that I will feed it a completely new rectangle with the same properties as the one I normally use, yet the original one is still altered afterwards. It's vodoo I don't understand, if I ask the original rectangle for it's location(right before the actual spriteBatch.Draw() method even), centerX,centerY etc... it's all fine if I use (0,0) for the origin of the draw, but the second I use new Vector2(/2,/2), the properties of the rectangle will be changed. Try it yourself you'll see!
Is there anyway to rotate by the center and still use 0,0 for the origin? That's basically what I'd like to do...
|
|
-
|
|
Re: What the heck? Rectangle collision and origin problems...
|
A rectangle is a value type, so calling spritebatch.Draw(tex, destRect...) is passing a copy of destRect to the Draw method, so the Draw method cannot
possibly change the original values in destRect.
abo:Is there anyway to rotate by the center and still use 0,0 for the origin? That's basically what I'd like to do...
No. You need to manage the values of your drawing rectangles to offset the origin.
Game hobbyist hell-bent on coding a diabolical Matrix
|
|
-
|
|
Re: What the heck? Rectangle collision and origin problems...
|
Noogy:Can't you just subtract new Vector2(width/2, height/2) from your position? This seems normal when the origin isn't in the top corner.
Amazing....
Thanks!
I honestly don't know why exactly it works, or how, but that fixed my problems strangely enough. (Though I had to add += width and height/2 to my location just fyi to anyone else out there). And it still rotates from the center :).
I really don't understand why setting the origin through the Draw() method messes with the actual rectangle's location x and y fields, but I'll have to ask Microsoft about that one I guess. Now to figure onto scaling..
Thanks!
|
|
-
|
|
Re: What the heck? Rectangle collision and origin problems...
|
Craig Martin:A rectangle is a value type, so calling spritebatch.Draw(tex, destRect...) is passing a copy of destRect to the Draw method, so the Draw method cannot
possibly change the original values in destRect.
Right, exactly, so why is it when I call the public field RectangleA for it's X,Y, and Center coordinates, they are changed based off of the value given to origin, which is a vector2, and not even a member related to rectangle? (Heck not even a method related to Rectangle, but in SpriteBatch!) Strange magic at work I say...
|
|
-
-
- (347)
-
premium membership
-
Posts
101
|
Re: What the heck? Rectangle collision and origin problems...
|
I'd say you are modifying the rectangle elsewhere. As has been stated previously, there is no way that the call to SpriteBatch.Draw (any of its overloads) can modify the rectangle you have passed in.
Perhaps if you posted the lines involving the rectangle setup and rendering, someone may spot your bug.
|
|
|