# 2D wave-like sprite movement XNA

I'm trying to create a particle that will 'circle' my character. When the particle is created, it's given a random position in relation to my character, and a box to provide boundaries for how far left or right this particle should circle. When I use the phrase 'circle', I'm referring to a simulated circling, i.e., when moving to the right, the particle will appear in front of my character, when passing back to the left, the particle will appear behind my character.

That may have been too much context, so let me cut to the chase:

In essence, the path I would like my particle to follow would be akin to a sine wave, with the left and right sides of the provided rectangle being the apexes of the wave. The trouble I'm having is that the position of the particle will be random, so it will never be produced at the same place within the wave twice, but I have no idea how to create this sort of behavior procedurally.

• So this is 2D side view? Or what? – MichaelHouse Mar 29 '12 at 3:42
• @Byte56 Yes, the game itself is a 2D side scroller, and if you can imagine it, it would be as though the particles would circle my character's feet or hips from a side view. – TheBroodian Mar 29 '12 at 6:37

When the object is created, create a variable t = 0. Increment this at regular intervals; this is your time.

When placing the object, don't give it a random position. Place it at phi = rand(0, 2*pi). This is your phase term.

If your gaze direction is parallel to the plane of rotation, evaluate x = A*cos(t*f + phi) where f is your frequency. You will play with f until you get the right rate of rotation. You will add x to the x-coordinate of the character to obtain the position of the object. You will check if (t*f) mod (2*pi) is 0 to decide whether to draw the object's sprite behind or above the character. A is the maximum distance from the character, i.e. the radius of rotation.

If your gaze direction is not parallel, you will evaluate x = A*cos(t*f + phi) and y = B*sin(t*f + phi) where A is half the width of your bounds rectangle, and B is half the height. In other words, maximum vertical and horizontal distances. Your rectangle better be centered on the character, or else.

You will add x to the player's x and y to the player's y to obtain the position of the object. You will again consult (t*f) mod (2*pi) to determine draw order.

• Thank you very much! That was probably the best and most thorough answer I've ever read on stack exchange. I'll try implementing this right away. – TheBroodian Mar 30 '12 at 3:40
• Glad to help! It may interest you to know that my answer was basically hacked together from the equations for a simple harmonic oscillator. For the second x/y case, though, I can't verify if real physical oscillators behave that way, but I don't think you would care about that. – Superbest Mar 30 '12 at 9:31
• I'm not creating an actual oscillator, but what I am creating does oscillate in essence, so this was very helpful. After playing with it for a while it works like a charm, thanks again! – TheBroodian Mar 31 '12 at 0:35

Before you make it random, first make it be at em-placed points (iterate to functionality, it works) like directly along the rotation vector of the character.

I think one of the things that might be tripping you up is thinking of it as a sine-wave instead of thinking of it as a circle. Instead of having the sprite follow a given function have it position determined by:

Vector2(Player.position.x +(cos(Player.rotation)*k),Player.position.y + (sin(Player.rotation)*k))
//Can be extended to vector3, and could move along a hemisphere if you wanted


Where Player is the player that holds a position and a rotation member, and k is some distance you want the sprite to be at from the player. to generate this randomly then you would replace the rotation of the player with some random value.

alternatively this implementation might make more sense depending on how you are holding/calculating you data.

Vector2(Player.position.x +(Player.rotation.x*k),Player.position.y + (Player.rotation.y*k))


This method assumes the rotation is a normalized vector that the player sprite is looking along. this method stops the requirement to use trig functions, and still gives you a circle. To make this one more random then you can maybe replace the rotation vector with a random normalized vector (if it is not normalized then you will not have a circle)

Where you made reference that the sprites position was to be pseudo-random then you could replace the player.rotation with a copy rotated some random angle. the amount of that angle will be a testing/feel thing.

• "Before you make it random, first make it be at em-placed points (iterate to functionality, it works) like directly along the rotation vector of the character." What are 'em-placed points'? "I think one of the things that might be tripping you up is thinking of it as a sine-wave instead of thinking of it as a circle." - this is exactly true, however, I was only using a sine wave as an example for anybody reading to better imagine what it may look like in-game. But I do definitely want it to behave as a circle, and not as a wave. – TheBroodian Mar 29 '12 at 6:40
• Also, after looking at the logic you've been kind enough to give me as an example, how would I use that in my update method to advance the position of my particle along the circle? – TheBroodian Mar 29 '12 at 6:48
• em-placed means to put at a given predefined location, or determined from something else. to answer you second part please see update, and thank you for bringing that to my attention. – gardian06 Mar 29 '12 at 8:14
• After studying your first sample, I think I'm beginning to understand how this would work; I have one more question, though. I would like my particles to function independently once they're placed into the game world- so if I didn't want it to rely on a member within my player class, what would I substitute those with? – TheBroodian Mar 29 '12 at 10:35