I've tried to dissect several tweet jam carts but have failed to figure how to move something along a wave pattern.
I want to move a circle between two x/y points in a wave. I know I have to use sin() and cos() but just don't know how to apply them, or to what.
I've done some Googling and even bought myself a "Trig for Dummies" book, so I'm slowly (very slowly) trying to learn math I've never been exposed to. I'm 20+ years removed from my last math class so it's frustrating but I'm motivated.
My specific purpose is bullet patterns but I know once the match clicks, I can use it in all sorts of place and make cool stuff like the rest of y'all.
If there's a simple snippet someone can share that I can look at and dissect it, I would appreciate it. Or any other links/resources they know of.
Instead of [x,y] as your coordinate, do [ x+cos(n), y+sin(n) ] where n is the degrees.
Sine and Cosine are cyclical, and always yield values between -1 and +1 (the unit). Thus, Sin(90) is the maximum, +1. The important thing to take from this is that once you multiply the unit by a scaling factor, you get +/- the unit size. Another helpful thing is that Cos(0) yields +1, and Sin(0) yields +0; it lets you determine where your cycle happens.
I'm not 100% sure, but I think Cos(n) is really just Sin(n+90). And in fact, you can do an offset inside the braces to change were on the wave your curve starts
So for example, if you wanted to shoot a bullet to the right, and have it zigzag up and down, the movement would be described as [x,y] = [ t, sin(t)*10 ]. You could multiply it by -10 or offset t by +/-180 if you wanted to flip the wave.
here's a litlle toy I just wrote, that does what you said: move between two points, in a wave, using trigonometry (well, sinus only)
just copy/paste in pico8 :
rl={x=63,y=63} --rocket launcher tg={} --target rk={ f=0 } --rocket function _update60() if (rk.f<=0) then -- spawn target -- at least @ 32 from launcher repeat tg.x=rnd(128) tg.y=rnd(128) dx=rl.x-tg.x dy=rl.y-tg.y until (dx*dx+dy*dy>32*32) --launch rocket... --time to reach,60-180 frames rk.f=60+flr(rnd(121)) -- direction of main axis local dx=tg.x-rl.x local dy=tg.y-rl.y -- position on main axis rk.mx=rl.x rk.my=rl.y -- velocity on main axis rk.vx = dx/rk.f rk.vy = dy/rk.f -- normal to main direction local l=sqrt(dx*dx+dy*dy) rk.nx=-dy/l rk.ny=dx/l -- stray oscillations -- 1 is 0-left-0-right-0 -- note: will miss target when not multiple of 0.5 rk.os=(1+flr(rnd(4)))*0.5 rk.dt=rk.os/rk.f rk.t=0 -- stray phase (0 starts left, 0.5 starts right) rk.ph=flr(rnd(2))/2 --stray damping -- <1 will narrow the path -- >1 will widen it rk.dp = 0.99+rnd(.02) --amplitude @start if (rk.dp<=1) then rk.amp = 10+rnd(30) else rk.amp = 5+rnd(15) end else --fly, rocket, fly rk.f-=1 --countdown --move along main axis rk.mx+=rk.vx rk.my+=rk.vy --stray damping rk.amp*=rk.dp --real position rk.t+=rk.dt local stray=rk.amp*sin(rk.ph+rk.t) rk.px=rk.mx+rk.nx*stray rk.py=rk.my+rk.ny*stray end end function _draw() cls() --launcher circfill(rl.x,rl.y,4,7) --target circfill(tg.x,tg.y,4,7) circfill(tg.x,tg.y,3,8) circfill(tg.x,tg.y,2,7) circfill(tg.x,tg.y,1,8) --rocket circfill(rk.px,rk.py,2,9) print('dp:'..rk.dp..' ph:'..rk.ph..' osc:'..rk.os, 0,120,7 ) end |
have fun :)
Here's a much simpler example:
--init x=0 y=64 angle=0 function _update() cls() --increment x+=1 y+=sin(angle)*3 angle+=0.03 --draw pset (x,y,7) --wrap x if (x>128) x=0 end |
So basically, you need to modify one axis with a sine of an increasing angle.
Hope that helps!
[Please log in to post a comment]