Rotating a sprite around its center - xna

I am trying to figure out how to use the origin in Draw method to rotate a sprite around its center. I was hoping somebody could explain the correct usage of origin parameter in Draw method.
If I use the following Draw method (without any rotation and origin specified) the the object is drawn at the correct/expected place:
spriteBatch.Draw(myTexture, destinationRectangle, null, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, 0);
However, if I use the origin and rotation like shown below, the object is rotating around is center but the object is floating above the expecting place (by around 20 pixels.)
Vector2 origin = new Vector2(myTexture.Width / 2 , myTexture.Height / 2 );
spriteBatch.Draw(myTexture, destinationRectangle, null, Color.White, ballRotation, origin, SpriteEffects.None, 0);
Even if I set the ballRotation to 0 the object is still drawn above the expected place
spriteBatch.Draw(myTexture, destinationRectangle, null, Color.White, 0.0f, origin, SpriteEffects.None, 0);
Is seems that just by setting the origin, the placement of the object changes.
Can somebody tell me how to use the origin parameter correctly.
Solution:
Davor's response made the usage of origin clear.
The following change was required in the code to make it work:
Vector2 origin = new Vector2(myTexture.Width / 2 , myTexture.Height / 2 );
destinationRectangle.X += destinationRectangle.Width/2;
destinationRectangle.Y += destinationRectangle.Height / 2;
spriteBatch.Draw(myTexture, destinationRectangle, null, Color.White, ballRotation, origin, SpriteEffects.None, 0);

this is correct use of origin. but now your position changed also to center, it's not on top left corner anymore, its on center. and it's floating for width/2 and height/2 from position befor seting origin.
so if your texture is 20x20, you need to subtract X by 10 (width/2) and Y by 10 (height/2) and you will have original position.

Related

How coordinates points works in LinearGradient?

Can anyone please explain or describe how the coordinates points in the LinearGradient?
For example: I have my code in this way.
var gradient = new LinearGradient(0, 0, 500, 500, colors, null, Shader.TileMode.Clamp);
paint.SetShader(gradient);
paint.Dither = true;
how it display in the rectangle while applying in the rectangle ?
In Android, the coordinate system always is like what you can see above picture.
1) (0,0) is top left corner.
2) (maxX,0) is top right corner
3) (0,maxY) is bottom left corner
4) (maxX,maxY) is bottom right corner
The maxX or maxY is the screen's(or view's) max width or max height.
This new LinearGradient(0, 0, 500, 500, colors, null, Shader.TileMode.Clamp) method will be sure a Gradient line which you can see in above picture. And when you use Canvas to draw the rectangle with the paint, the colors will be rendered along this line.

Drawing a sprite from a spritesheet using XNA/Monogame

I have a spritesheet with 2 sprites. Each sprite is 40x60. The total size of the image is 40x120.
It looks like this (the red line is part of the 1st sprite). I'll tell you in a second why I added that.
It seems that for some reason, when trying to draw the second sprite, it will always take the last line of the previous sprite. I have drawn that red line to illustrate that.
This is my code that draws the 2nd sprite:
Rectangle rect = new Rectangle(0, 60, 40, 60); // Choose 2nd sprite
Vector2 pos = new Vector2(100, 100);
Vector2 origin = new Vector2(0, 0);
spriteBatch.Begin();
spriteBatch.Draw(mSpriteTexture, pos , rect, Color.White, 0.0f, origin, 6, SpriteEffects.None, 0.0f);
spriteBatch.End();
And this is how it looks when I run the program:
Any ideas what I'm doing wrong?
Note: For this example I'm using scale=6. I did this because it seems that when scale > 1 this problem will always happen. If scale = 1, it doesn't seem to happen all the time.
Had the same issue. Used SamplerState.PointClamp in my spriteBatch.Begin - call to fix it
It looks like this: (MonoGame 3.6 tho)
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null, null, viewMatrix);

In XNA , what's the difference between the rectangle width and the texture's width in a sprite?

Let's say you did this: spriteBatch.Draw(myTexture, myRectangle, Color.White);
And you have this:
myTexture = Content.Load<Texture2D>("myCharacterTransparent");
myRectangle = new Rectangle(10, 100, 30, 50);
Ok, so now we have a rectangle width of 30. Let's say the myTexture's width is 100.
So with the first line, does it make the sprite's width 30 because that's the width you set to the rectangle, while the myTexture width stays 100? Or does the sprite's width go 100 because that's the width of the texture?
the Rectangles used by the Draw-method defines what part of the Texture2D should be drawn in what part of the rendertarget (usually the screen).
This is how we use tilesets, for instance;
class Tile
{
int Index;
Vector2 Position;
}
Texture2D tileset = Content.Load<Texture2D>("sometiles"); //128x128 of 32x32-sized tiles
Rectangle source = new Rectangle(0,0,32,32); //We set the dimensions here.
Rectangle destination = new Rectangle(0,0,32,32); //We set the dimensions here.
List<Tile> myLevel = LoadLevel("level1");
//the tileset is 4x4 tiles
in Draw:
spriteBatch.Begin();
foreach (var tile in myLevel)
{
source.Y = (int)((tile.Index / 4) * 32);
source.X = (tile.Index - source.Y) * 32;
destination.X = (int)tile.Position.X;
destination.Y = (int)tile.Position.Y;
spriteBatch.Draw(tileset, source, destination, Color.White);
}
spriteBatch.End();
I may have mixed up the order of which the rectangles are used in the draw-method, as I am doing this off the top of my head while at work.
Edit; Using only Source Rectangle lets you draw only a piece of a texture on a position of the screen, while using only destination lets you scale the texture to fit wherever you want it.

move a sprite to match borders of a circle in xna

i'm trying to build a game in xna, i got a circle which i want the player to move around it, as you can see in the following picture, its working great except the drawing part which i'm not pleased with
here's a link to an image http://s12.postimage.org/poiip0gtp/circle.png
i want to center the player object to the edge of the circle so it won't look like the player is standing on air
this is how i calculate the position of the player
rad = (degree * Math.PI / 180);
rotationDegree = (float)((Math.PI * degree) / 180);
currentPosition.X = (float)(Math.Cos(rad) * Earth.radius + (GraphicsDevice.Viewport.Width / 2));
currentPosition.Y = (float)(Math.Sin(rad) * Earth.radius + (GraphicsDevice.Viewport.Height / 2));
and this is how i draw the player
spriteBatch.Draw(texture,currentPosition, null, Color.White,rotationDegree, Vector2.Zero,1f,SpriteEffects.None, 1f);
thank you.
Use the origin overload for spritebatch. Which is where the sprite is drawn according to the position.
Spritebatch.Draw(texture,Position, null,Color.White,0f,new Vector2(texture.Width / 2,texture.Height /2),1f,SpriteEffects.None, 0);
Using texture.Width / 2,texture.Height /2 for origin will center it.
It looks like what you want to do here is adjust the sprite's origin, which is the vector that you're passing into SpriteBatch.Draw(). This is used to determine the "center point" of your sprite; {0, 0} represents the sprite's upper-left corner, while {spriteWidth, spriteHeight} represents the bottom-right corner. Your sprite will be positioned and rotated relative to this origin.

XNA - Drawing zoomed 2D sprites

I have a tile based game. Each tile texture is loaded and then I draw each one next to the other, forming a continuous background. I actually followed this tutorial for the xml files.
http://www.xnadevelopment.com/tutorials/looksleveltome/looksleveltome.shtml
The sources of the textures are 50x50.
However, it works only it the scale is 1 (or lower), if the scale is greater
The results : Normal size (50 pixel and scale 1)
http://imageshack.us/photo/my-images/525/smallzp.jpg/
Larger size (Zoomed or 100 pixel in xml file)
http://imageshack.us/photo/my-images/577/largeki.jpg/
We can see there are lines between the tiles, which are not in the texture. It's actually not so bad here, but in my game tileset, that's what it does :
http://imageshack.us/photo/my-images/687/zoomedsize.png/
The same effect is present whether I increase the tile size in the xml file, change the scale when drawing or use my camera to zoom.
//zoom code
public Matrix GetTransformation()
{
return
Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(_device.Viewport.Width * 0.5f, _device.Viewport.Height * 0.5f, 0));
}
//draw
_spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.AlphaBlend, null, null, null, null,
_camera.GetTransformation());
//for each tile
theSpriteBatch.Draw(mSpriteTexture, Position, Source,
Color.Lerp(Color.White, Color.Transparent, mAlphaValue),
mRotation, new Vector2(mSource.Width / 2, mSource.Height / 2),
Scale, SpriteEffects.None, mDepth);
Is there a reason for this? A way to fix it to have a continuous texture when zoomed?
The problem is in your sampler state, the gpu is trying to sample colors near the point to interpolate them.
Use SamplerState.PointClamp in your spriteBatch.Begin() and it will be fixed.

Resources