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]



