• 15
• 15
• 11
• 9
• 10

# [Algorithm] Fairy movement

This topic is 2080 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,
I'm programming a 2D game and I'm trying to make something cool with the light.
I wrote a little tile-based light engine which kinda works, and I would like to test it's efficiency.

I would like to recreate something like the fairies from the Zelda games. An entity (little fairy) flying arround the hero, enlightening the area.
The light part is ok, but I'm having some trouble on the movement algorithm.
I tried some pseudo-brownian movement, but it's not really what I want, the fairy flies away and never come back (which is sad), it should chill around the hero, but not too far.

Do you have any idea ?

Thanks ! (this message may contain some noob english mistakes, it's not my native language)

##### Share on other sites
Well depending on your code, I would most probably get the fairy entity to take in the players x,y and z position, with that position make a rectangle or a box, The fairy could then move randomly but it will always have to stay in the box, if the fairy was to move out the box it would stop being random and move towards the player.

Hope this helps, also without any code im not sure what language or how you have implemented this already.

##### Share on other sites
Thanks for you reply, I'm coding with Java using the lib Slick2D.
Here is my code implementing some pseudo-brownian algorithm :

 public class Fairy { private Image image; private Vector2f pos; // Velocity private Vector2f v; // Acceleration private Vector2f a; public Fairy(Vector2f sc) throws SlickException { this.image = new Image("data/particle.png"); this.pos = new Vector2f(sc.x - image.getWidth()/2, sc.y - image.getHeight()/2); this.v = new Vector2f(0, 0); this.a = new Vector2f(0, 0); } public void update(Vector2f sc) { Vector2f oldPos = new Vector2f(pos); this.v.x += this.a.x; this.v.y += this.a.y; this.a.x += getAccelerationRand(); this.a.y += getAccelerationRand(); this.v.x *= 0.9f; this.v.y *= 0.9f; this.pos.x = oldPos.x + this.v.x; this.pos.y = oldPos.y + this.v.y; } public void draw() { this.image.draw(this.pos.x, this.pos.y); } private float getAccelerationRand() { float rand = (float)Math.random(); if(Math.random() < 0.5f) rand *= -1; return rand * 0.01f; } } 

It's a 2D game, and I don't really need to use Z-axis. Currently there is no bounds, the fairy goes where it want (like a particle in a fluid, colliding with smaller particles).
I could indeed make the fairy stop and go back to the player location if it's gone too far, but maybe it wont be realistic and random enough, I have to test it ^^

##### Share on other sites
Something simple which might produce the desired effect:

- the fairy has a target position, and each frame attempts to steer towards this position (like a homing missile)
- every so often, a new target position is selected at random within a certain range of the player

The target position could be absolute or relative to the player. You can play with the range, frequency of target changes etc.

##### Share on other sites
You can probably benefit from a bit of experimentation with steering behaviors. It's easy to combine some sort of random motion with a force that pushes towards a desired distance from the player, and thinking of these things as combined steering behaviors is helpful.

##### Share on other sites
Could be a solution, but wouldn't be the movement to robotic-like ?
The "chill-around" move should me smooth.

I'll try and tell you if I'm happy with that, thanks.

##### Share on other sites
Maybe you could bias the velocity and acceleration slightly, so the fairy tends to move towards the player:

 this.a.x += (player.pos.x - this.pos.x) * 0.005; this.a.y += (player.pos.y - this.pos.y) * 0.005; this.v.x += (player.pos.x - this.pos.x) * 0.02; this.v.y += (player.pos.y - this.pos.y) * 0.02; 

I'd be tempted to scale the acceleration down on each step, too, so it can't get arbitrarily large:

 this.a.x *= 0.9f; this.a.y *= 0.9f;