SHMUP-DEV

SHMUP DEV FORUMS => Assistance => Topic started by: Matt McFarland on January 06, 2006, 12:14:34 AM



Title: Move in a circle, a half circle, and a circle that "Expands"
Post by: Matt McFarland on January 06, 2006, 12:14:34 AM
I'm trying to come up with many different ways to move objects in my game's engine.  I was wondering if you guys know anything about coding objects to move in a full circle that can be manipulated in size.  ie: the circle expands so they move outward too?  Or maybe just a half circle, and how would I make them move up and down and left and right on a curving wave?  I'm trying to do this all without using bsplines, any ideas?


Title: Re: Move in a circle, a half circle, and a circle that "Expands"
Post by: kemical on January 06, 2006, 12:57:54 AM
to get something moving in a circle you can do code like this:

degree +=1;
if ( degree > 360 ) { degree = 1; }
pos_x = ( centerx - ( radius * ( sin ( degree ) ) ) );
pos_y = ( centery - ( radius * ( cos ( degree ) ) ) );

new position = (pos_x,pos_y);

I think that should work.. there may be a better way also.


Title: Re: Move in a circle, a half circle, and a circle that "Expands"
Post by: ELLioT on January 07, 2006, 02:44:47 PM
I have an alternate ineresting way of moving in circles. It's based on dynamic equations of harmonic oscillators movements. It has its benfits and drawbacks though, here it is:

move_init:
  radius = 100;
  omega = 2*PI/120; // let's say you want to make a complete turn in 120 frames
  omega2 = omega*omega;
  posx = -radius;
  posy = 0;
  speedx = 0;
  speedy = radius*omega;

move_loop:
  speedx += -omega2*posx;
  speedy += -omega2*posy;
  posx +=speedx;
  posy +=speedy;
  spritepos=(posx, posy);
  goto move_loop;

As you see, the main benefit is NO sin() call, NO sin precalculation Table. If you replace omega by a power of 2, then you can avoid the 2 muls in the loop too, wich makes the method Zero-Mul Zero-Call Zero-Table. I find that 4 Adds to get a circle is quiet fun.
To make it work you need to have posx, posy, speedx, speedy declared as floating point, OR fixed point with "enough" precision.
Notice that the lower omega value is, the better is the circle shape accuracy.
Notice also that -omega*posx added to the speed on each frame is the expression of a spring force. You can add here other forces at will (friction, gravity or whatever).

Blitz code :
Code:
Const width=800
Const height=600

Graphics width,height
SetBuffer BackBuffer()

radius# = 200
omega# = 2*Pi/120
omega2# = omega*omega
posx# = -radius
posy# = 0
speedx# = 0
speedy# = radius*omega

While Not KeyDown(1)

speedx = speedx - omega2*posx
speedy = speedy - omega2*posy
posx = posx + speedx
posy = posy + speedy
Plot posx+400,posy+300

Flip

Wend

End


Title: Re: Move in a circle, a half circle, and a circle that "Expands"
Post by: ELLioT on January 07, 2006, 04:02:50 PM
I've updated the code above to make the move expand. It's all in spiralfactor:

press left right arrowes to expand / contract movement
Code:
Const width=800
Const height=600

Graphics width,height
SetBuffer BackBuffer()

radius# = 100
omega# = 2*Pi/100
omega2# = omega*omega
posx# = -radius
posy# = 0
speedx# = 0
speedy# = radius*omega
spiralstep# = .02
spiralfactor# = 1

While KeyDown(1) = 0 ; Continue until the ESCAPE key is pressed

spiralfactor = 1

If KeyDown(205)
spiralfactor = 1 + spiralstep
EndIf
If KeyDown(203)
spiralfactor = 1 - spiralstep
EndIf

speedx = (speedx - omega2*posx) * spiralfactor
speedy = (speedy - omega2*posy) * spiralfactor
posx = posx + speedx
posy = posy + speedy
Plot posx+400,posy+300

Flip

Wend

End

Notice that the discreet nature of this method accumulates some errors in the calculations along time that result in a phase shift between the X & Y oscillators. That's why you endup with an ellipse instead of a circle.
Notice that if you setup different omegas for both oscillators, you may also obtain some intersting effects.