So, I'm spawning a horizontal line of enemies that I would like to have move in a nice wave. Currently I tried:

 Enemy.position.X += Enemy.velocity.X;
 Enemy.position.Y += -(float)Math.Cos(Enemy.position.X / 200) * 5;

This...kind of works. But the wave is not a true wave. The top and bottom of one pass are not the same (e.g. 5 for the top, and -5 for the bottom (I don't mean literal points, I just meant that it's not symmetrical)).

Is there a better way to do this? I would like the whole line to move in a wave, so it looks fluid. By that, I mean that it should look like each enemy is "following" the one in front of it. The code I posted does have this fluidity to it, but like I said, it's not a perfect wave.

Any ideas?

Thanks in advance.

  • \$\begingroup\$ Is your window size 200? \$\endgroup\$ – MichaelHouse Mar 29 '12 at 2:14
  • \$\begingroup\$ How is it not a perfect wave? Wolfram Alpha suggests your formula is just fine. Could you post a screenshot? \$\endgroup\$ – doppelgreener Mar 29 '12 at 2:15
  • \$\begingroup\$ No, no. My window size is 1280x720. I should have specified. That's just my arbitrary number to constrain the wave so it's not giant. \$\endgroup\$ – electroflame Mar 29 '12 at 2:15
  • \$\begingroup\$ This is the wave you should expect for your window size \$\endgroup\$ – MichaelHouse Mar 29 '12 at 2:24
  • \$\begingroup\$ Now that I'm looking at the functions you guys provided, it is a little strange that it doesn't work. Give me a moment to try something. EDIT: It works fine if I just spawn 1 enemy. It's only the trailing enemies that have issues. It looks like the trailing enemies are a bit "lower" to start. \$\endgroup\$ – electroflame Mar 29 '12 at 2:27

Perhaps it's as simple as:

Enemy.position.X += Enemy.velocity.X;
Enemy.position.Y = -(float)Math.Cos(Enemy.position.X / 200) * 5;

Notice the Enemy.position.Y is just using = not +=


Try with this instead:

Enemy.position.Y = -(float)Math.Cos(Enemy.position.X / 100);

EDIT again

With offset to put 0 at the middle of your window:

Enemy.position.Y = -(float)Math.Cos(Enemy.position.X / 100) + ScreenHeight/2;


Enemy.position.Y = StartPosition.Y + (-(float)Math.Cos(position.X / 100) * 100); 

As you found that to work.

  • \$\begingroup\$ Unfortunately, that doesn't work. That eliminates the wave entirely, and the enemies just move across the top of the screen (0 on the Y) \$\endgroup\$ – electroflame Mar 29 '12 at 2:34
  • \$\begingroup\$ That's pretty strange. Clearly the Y value couldn't equal zero, what are the Y values being set to? This is what should be happening with the new setting. \$\endgroup\$ – MichaelHouse Mar 29 '12 at 2:40
  • \$\begingroup\$ Alright, now we're getting somewhere. With the /100 I can now see that, while still being 'centered' around 0, it is still doing a very slight wave. So now maybe I need to offset it? \$\endgroup\$ – electroflame Mar 29 '12 at 2:53
  • 2
    \$\begingroup\$ Success! Here's the new line: position.Y = OriginalPosition.Y + (-(float)Math.Cos(position.X / 100) * 100); This makes a fantastic wave. Many thanks, Byte. You nudged me in the right direction. If you change your answer to relect the line I just stated, I'll mark you as the answer. ;) \$\endgroup\$ – electroflame Mar 29 '12 at 2:57

It should be as simple as: Enemy.position.Y = -(float)Math.Sin(Enemy.position.X), no?

This assumes you have a wave of enemies that move horizontally. The path of motion would be the exact same as the plot of y = sin x, or rather Enemy.position.Y = sin(Enemy.position.X).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.