Log In  


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 :)


5

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]