XNA sprite transormation - xna

Do anybody know how to apply transformation to sprite without opportunities of SpriteBatch.Draw() method ?
(Update from comments)
This is what I need: I have a circle sprite. This picture contains shadows. I need to stretch this circle (make ellipse) and rotate it, but I want the shadow does not change its position into ellipse. Rotation and scaling change every frame. I think it's possible with matrix transformation

The matrix passed into SpriteBatch.Begin is applied last. Using this is the only way to achieve a scale operation following a rotate operation through SpriteBatch (assuming your scale is non-uniform).
The downside is that, if the scale of each sprite is different, you will have to start a new batch for each.
Your other option is to write your own sprite batcher - but that seems a bit drastic.

Thanks! I've found solution, but it is very slowly =(
this.displayMatrix =
Matrix.CreateTranslation(-(new Vector3(Position, 0))) *
Matrix.CreateRotationZ(1) *
Matrix.CreateScale(new Vector3(new Vector2(1f, 2f), 1)) *
Matrix.CreateTranslation((new Vector3(Position, 0)));

Related

What's the difference of setScale and size of SKSpriteNodes in SpriteKit and Swift?

I was trying to set the size of a SKSpriteNode from a PNG image (OK with that, just a:
test = SKSpriteNode(imageNamed: "myImage")
But when it comes to resize it, I'm not sure if I should use test.setScale or test.size.
What's the difference and when should I use each of them?
setScale():
Sets the xScale and yScale properties of the node. These two parameters are the scaling factor that multiplies the width (for xScale) and the height (for yScale) of a node and its children.
Code sample:
spaceship.setScale(0.50) // decreased scale to it's half size
size():
Expresses the dimensions of the sprite (width and height), in points.
Code sample:
spaceship.size = CGSizeMake(100.0, 70.0) // Re-size the dimensions to these values
When do you use setScale and when do you use size?
Usually setScale is used to increase or decrease the sprite about the scale factor, look for example the SKAction.scaleTo used to make a zoom in or zoom out.
size is frequently used because you can express in points the exactly values you want to do to your sprite.
You should use size when you want to change the specific size of a SKSpriteNode without affecting the size of any children of that sprite node.
Scaling a sprite node not only changes the size (scale) of the node, it also scales all that sprite node's children appropriately (proportionally) as well.
If a sprite node has no children, then there's no practical difference between size and scale.
Note: I find it helpful to use size when it doesn't matter so that I know that a scale of 1.0 is always the default size - handy for animating using scaleTo instead of scaleBy and back again to default size.
If you are using a spriteNode, I would use .setScale, or .xScale or .yScale , because those are specifically for sprites. .size can also be used for the size of labels, and text views in UIKit.
Lets say you want the sprite to be 2x bigger:
theNode.xScale = 2.0
theNode.yScale = 2.0
Note that they have to be floats, not Integers
So to sum it up, .setScale is for spriteNodes and images in general, and .size is for a vast amount of things that aren't images, like labels and more. So if you are using a sprite, use .setScale. If you are resizing a block use .size.
If you believe that this is the right answer, please mark it as so so it helps anyone else with this issue. Thanks!
I alway resize using the .size property since I believe a node's physics body does not automatically scale when you use the .setScale / .xScale / .yScale. If you scale the node, you will need to redo the size of the physicsBody.

How can i draw hexagon in 2d and able to scale it?

So i made simple drawing script
This is what u can draw with it :D
So anyway my question is i wan't to make Erase Tool i already made one but it only removes 1 pixel at time instead i want to make hexagon thing and able to scale it up i just need formula to do that or simple explanation no script required
I want to be look like here I can just fill up pixels but i am not sure about how to deal with scaling part.
Looks like I'm extremely late, but if anybody else needs this help in the future, here's the solution.
You can simply loop for every pixels (a for loop for each y coordinates [as j] embedded in a for loop for each x coordinates [as i]).
Then for each of those loops, check the distance from the cursor's current position to the pixel located at (i, j), and if it's smaller than the chosen radius, change the pixel for a blank one.
The recommended way of checking the distance between two pixels in Roblox would be something like so:
(Vector2.new(x1, y1) - Vector2.new(x2, y2)).magnitude

What is the right way to zoom the camera out from a scene view?

I have a scene where my gameplay happens. I'm looking for a way to slowly 'zoom-out' so more and more space becomes visible as the time passes. But I want the HUD and some other elements to stay the same size. It's like the mouse wheel functionality in top-down games.
I tried to do it with sticking everything into display groups and transitioning the xScale, yScale. It works visually of course but game functionality screws up. For example I have a spawner that spawns some objects, its graphics gets scaled but spawner still spawns the objects from its original position, not the new scaled position..
Do I need to keep track of every X, Y position I'm using during gameplay and transition them too? (Which is probably possible but too hard for me since I use a lot of touch events for aiming and path creating etc.) Or is there an easier way to achieve this? Please please say yes :P
I'm looking forward for your answers, thanks in advance! :)
The problem is you are scaling your image, but not your position coordinates.
You need to convert from 'original coordinates' to 'scaled coordinates'
If you scale your map size to half, you should scale the move amounts by half too.
You need to 'scale' your coordinates in the same amount your image is scaled.
For example lets assume your scale factor is 0.5, you have an image:
local scaleFactor = 0.5
image.xScale = scaleFactor
image.yScale = scaleFactor
Then you would need to scale your move amounts by this factor
thingThatIsMoved.x = thingThatIsMoved.x + (moveAmount * scaleFactor)
thingThatIsMoved.y = thingThatIsMoved.y + (moveAmount * scaleFactor)
I hope this helps, I am assuming you have a moveAmount variable and updating the position on the enterFrame() event.

What sort of transform would give me the desired resultant image?

It feels simple really. I have an UIImageView:
and I want to apply an affine transform to get this image:
However, the particular transform in question eludes me. Rotating by 180° gets me this:
transform = CGAffineTransformMakeRotation(M_PI);
// similarly, CGAffineTransformMakeScale(-1, -1);
which is oviously quite far off. Translation is also problematic:
transform = CGAffineTransformMakeTranslation(x, y);
Reflecting over the line y = x and then rotating 180° gets me this:
transform = CGAffineTransformMake(0, 1, 1, 0, 0, 0);
transform = CGAffineTransformRotate(M_PI);
which is closer, but still not there. Is there something obvious that I'm missing, or is this really complicated? Does anyone know what sort of transform I'm looking for here?
Edit:
Twitter feedback is suggesting that affine transforms aren't the way to go. At the end of the day, I simply want the resultant image, so any suggested routes to success are greatly appreciated!
You are trying to move a sprite, whether you realize it or not. No transformation can move the star and keep the background. Your options are to:
- make a large background and clip it at the end, so that translation works
- make a sprite image on top of a separate background image. If you're using iOS7, you may want to use the Sprite Kit.

How to scale on-screen pixels?

I have written a 2D Jump&Run Engine resulting in a 320x224 (320x240) image. To maintain the old school "pixely"-feel to it, I would like to scale the resulting image by 2 or 3 or 4, according to the resolution of the user.
I don't want to scale each and every sprite, but the resulting image!
Thanks in advance :)
Bob's answer is correct about changing the filtering mode to TextureFilter.Point to keep things nice and pixelated.
But possibly a better method than scaling each sprite (as you'd also have to scale the position of each sprite) is to just pass a matrix to SpriteBatch.Begin, like so:
sb.Begin(/* first three parameters */, Matrix.CreateScale(4f));
That will give you the scaling you want without having to modify all your draw calls.
However it is worth noting that, if you use floating-point offsets in your game, you will end up with things not aligned to pixel boundaries after you scale up (with either method).
There are two solutions to this. The first is to have a function like this:
public static Vector2 Floor(Vector2 v)
{
return new Vector2((float)Math.Floor(v.X), (float)Math.Floor(v.Y));
}
And then pass your position through that function every time you draw a sprite. Although this might not work if your sprites use any rotation or offsets. And again you'll be back to modifying every single draw call.
The "correct" way to do this, if you want a plain point-wise scale-up of your whole scene, is to draw your scene to a render target at the original size. And then draw your render target to screen, scaled up (with TextureFilter.Point).
The function you want to look at is GraphicsDevice.SetRenderTarget. This MSDN article might be worth reading. If you're on or moving to XNA 4.0, this might be worth reading.
I couldn't find a simpler XNA sample for this quickly, but the Bloom Postprocess sample uses a render target that it then applies a blur shader to. You could simply ignore the shader entirely and just do the scale-up.
You could use a pixelation effect. Draw to a RenderTarget2D, then draw the result to the screen using a Pixel Shader. There's a tool called Shazzam Shader Editor that let's you try out pixel shaders and it includes one that does pixelation:
http://shazzam-tool.com/
This may not be what you wanted, but it could be good for allowing a high-resolution mode and for having the same effect no matter what resolution was used...
I'm not exactly sure what you mean by "resulting in ... an image" but if you mean your end result is a texture then you can draw that to the screen and set a scale:
spriteBatch.Draw(texture, position, source, color, rotation, origin, scale, effects, depth);
Just replace the scale with whatever number you want (2, 3, or 4). I do something similar but scale per sprite and not the resulting image. If you mean something else let me know and I'll try to help.
XNA defaults to anti-aliasing the scaled image. If you want to retain the pixelated goodness you'll need to draw in immediate sort mode and set some additional parameters:
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
GraphicsDevice.SamplerStates[0].MagFilter = TextureFilter.Point;
GraphicsDevice.SamplerStates[0].MinFilter = TextureFilter.Point;
GraphicsDevice.SamplerStates[0].MipFilter = TextureFilter.Point;
It's either the Point or the None TextureFilter. I'm at work so I'm trying to remember off the top of my head. I'll confirm one way or the other later today.

Resources