I have a particle engine which creates an emitter at my mouse position.
particleEngine.EmitterLocation = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);
It's in the Update method in Game1.cs.
I have another class which is called Ball.cs with its bouncing physics, and Texture2D texture; Vector2 position.
Now how do I make the emitter / particles follow the ball instead?
pass a reference to the particleEngine to the Ball class and set the EmitterLocation to the ball's location.
Example:
Game1, Initialize (for instance):
ParticleEngine particleEngine = new ParticleEngine();
Ball ball = new Ball(particleEngine);
In the Ball class:
class Ball
{
ParticleEngine particleEngine;
Vector2 position;
public Ball(ParticleEngine particleEngine)
{
this.particleEngine = particleEngine;
}
public void Update(GameTime gameTime)
{
//Update position
particleEngine.EmitterLocation = new Vector2(this.position.X, this.position.Y);
}
}
I don't know how your particle engine works or anything about your code structure, but with the information given I did my best to implement an understandable example.
Related
Here is the code for a project im working on, where an enemy moves back and forth at the bottom of the screen.
class enemy1
{
Texture2D texture;
public Vector2 position;
bool isAlive = false;
Random rand;
int whichSide;
public enemy1(Texture2D texture, Vector2 position)
{
this.texture = texture;
this.position = position;
}
public void Update()
{
if (isAlive)
{
if (whichSide == 1)
{
position.X += 4;
if (position.X > 1000 + texture.Width)
isAlive = false;
}
if (whichSide == 2)
{
position.X -= 4;
if (position.X < 0)
isAlive = false;
}
}
else
{
rand = new Random();
whichSide = rand.Next(1, 3);
SetInStartPosition();
}
}
private void SetInStartPosition()
{
isAlive = true;
if (whichSide == 1)
position = new Vector2(0 - texture.Width, 563 - texture.Height);
if (whichSide == 2)
position = new Vector2(1000 + texture.Width, 563 - texture.Height);
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.White);
}
}
Now i want there to be a few enemys going back and forth but they start at differant positions so it looks like there is a few enemys going back and forth at the bottom of the screen. I have managed to draw a few other enemies on the screen, except they do not behave like the first enemy. They just are pictures on a screen not moving anywhere. So now all i have is the hero moving around and one enemy at the bottom of the screen, along with 5 other enemys sitting at the top of the screen doing nothing. How do i easily add a new sprite from a class that has the same behavior, at any time, while not making a billion variables to store them in?
Generally it's a good idea to have similar logic contained within the proper class, so if all Sprites where to do the same thing, then all you would need to do is put your movement code inside a public method and then call that method inside Update().
So, if your Sprite class looks something like this:
public class Sprite
{
private Vector2 Position;
public Sprite(Texture2D texture, Vector2 position)
{
Position = position;
}
//then just add this
public void MoveSprite(int amount)
{
position.X += amount;
}
}
Now, the object name "Sprite" is pretty generic, you will more than likely have many "Sprites" in your game.
So you're going to want to follow good OOP practices and maybe name this specific sprite something different and then have it derive from this class we're looking at right now. (But i'm not going to make design decisions for you)
This was a vague question, but that's my best shot at an answer for you.
I am developing a XNA based 2D-game for Windows Phone 7.1. My requirement is to flick an object, based on the amount and angle of flick, it will animate in a vertical projectile motion. For e.g. there is a lake infront of you, and you want to throw a stone into it. The same motion has to be replicated with camera being human's eye.
There are 3 levels of distance to be covered. The distance covered in Y-axis is more than the distance covered in X-axis.
I could see many equations given for projectile motion in horizontal (X-) axis but none to show projectile motion in Y-axis.
Any idea how to achieve this projectile motion in terms of X- and Y- coordinates?
If you use a Vector2 instead of an angle, you can implement a very rudimentary physics engine which will be simple and accurate.
The object to be flicked will have a Vector2 Velocity and a Vector2 Position.
Then you can just add the distance between the mouse as a Vector2 to the Velocity, and add the Velocity to the Position every frame, and then add gravity.
Here is a sample implementation:
public class FlickObject
{
public Vector2 Velocity;
public Vector2 Position;
public FlickObject () {}
public void Update(GameTime t)
{
Position += Velocity;
}
}
And in the game class (when the user flicks the object):
flickObject.Velocity += FlickDistance;
Where FlickDistance is the distance between the mouse (or however you calculate it) and the object.
To finish it off, add gravity:
flickObject.Velocity += new Vector2(0, GRAVITY);
Where GRAVITY is set to some positive value.
Currently, my game using some pixel detections.
For exemple, for sprites, i retrieve the pixel of its position.
When i move it, the position values have some decimals like :
thePixel = new vector(position.X, position.Y);
//thePixel = (52.2451, 635.2642)
so i have to Round These values
thePixel = new vector((float)Math.Round(position.X, 0), (float)Math.Round(position.Y, 0));
//thePixel = (52, 635)
I would like to know if there are some other ways to get perfect position (means, without decimal) without Rounding them.
Is it maybe a moving method problem ?
Thx for reading, hope you can help.
You can't really get around the need to round your values, but you can make it a lot nicer to code by using an extension method:
public static class Vector2Extensions
{
public static Vector2 Floor(this Vector2 vector)
{
return new Vector2((float)Math.Floor(vector.X), (float)Math.Floor(vector.Y));
}
}
(As you can see, personally I prefer Floor to Round. I also have one for Ceiling.)
Then you can just use it like this:
HandleCollision(position.Floor());
Of course, if you're doing per-pixel collision detection - your collision maths should probably be integer-based (not stored as float in a Vector2). You could use Point. Turns out I have an extension method for that too:
public static class Vector2Extensions
{
public static Point AsXnaPoint(this Vector2 v)
{
return new Point((int)v.X, (int)v.Y);
}
}
Then:
HandleCollision(position.AsXNAPoint());
Or possibly:
HandleCollision(position.Floor().AsXNAPoint());
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...
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.)
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.
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
I'm looking for the best option on how to handle snapping sprites to a tilemap. I'm trying to make a Chu Chu Rocket clone. If you dont know the game. It is a tilebased game where you place arrows on a specfic tile to direct unts around the maps. So I need to snap the sprites to the center of the tile at all times and then detect a collision with either an arrow which takes up a whole tile or a wall or other obstruction. Any ideas on what the based way would be to detect those things since it would require different kinds of collision detection i believe.
The easiest way to snap the sprites to a tile is to draw them centered at a tile. The collision detection can be done in your update function by checking against your level object.
class Mouse
{
public int XTile;
public int YTile;
public int XDelta;
public int YDelta;
}
//in Update
if (Level[mouse.YTile][mouse.XTile] == Tiles.Arrow)
{
//change mouse.XDelta and mouse.YDelta based on the direction of the arrow
}
if (Level[mouse.YTile + YDelta][mouse.XTile + XDelta] == Tiles.Wall)
{
//change mouse.XDelta and mouse.YDelta based on wall rules
}
//in Draw
int tileSize = 32; //or whatever size tile you are using
spriteBatch.Draw(mouseSprite, new Vector2(mouse.XTile * tileSize,
mouse.YTile * tileSize), Color.White);
//or, if the mouseSprite doesn't take up the whole tile
int sizeDifference = tileSize - mouseSprite.Width;
spriteBatch.Draw(mouseSprite, new Vector2(mouse.XTile * tileSize + sizeDifference / 2f,
mouse.YTile * tileSize + sizeDifference / 2f), Color.White);