Following a path...

BlitzMax Forums/BlitzMax Beginners Area/Following a path...

Hi guys,

I'm interested in trying to make a 'shoot the gems' kind of game. What I need help on is the concept of making the gems follow a pre-determined path?

Thanks heaps!

Cheers,
Sam

You could make the path out of points (x,y) and store each path in a separate file then load them into Types.

You could also draw the path into a special map and then follow it pixel by pixel.

The other one is: mark certain points as base-path and connect them using bezier-curves - so you avoid a big bunch of points to make a nice curve-movement.


bye
MB

But how important is that big bunch anno 2007/2008? If one path has 1024 points (512 x and 512 y), then a whopping 1024 of those paths will only cost 1MB when using bytes or 2MB using shorts ..

if you say:

point1: 10,10
point2: 11,11

then you missed more than a dozen of fractional points between - else (adding more points) you will not have only 1000 pathpoints.

Using bezier curves you are able to get each point you are interested in and so you also remove jagging when eg. rotating a ball around the curve.


bye
MB

Why not use vectors? i was wondering about the same thing so i cooked up this example.
Note: if you dont need turning, you can remove the heavy duty math thingy, and replace DirX/Y with dx/dy.
SuperStrict

Graphics 640,480, 0

Global Path:Float[] = [ ..
	100.0,100.0 ,..
	500.0,100.0 ,..
	500.0,400.0 ,..
	100.0,400.0 ,..
	100.0,100.0 ..
]

Const POINT_RADIUS:Int = 16
Const TURN_SPEED:Float = 120
Const MOVE_SPEED:Float = 3

Global X:Float = 0
Global Y:Float = GraphicsHeight() / 2
Global DirX:Float=1,DirY:Float=0
Global Curr:Int

Repeat

	' normalized distance vector
	Local dx:Float = (Path[Curr] - X)
	Local dy:Float = (Path[Curr+1] - Y)
	Local dist:Float = Sqr( dx*dx + dy*dy)	
	dx :/ dist
	dy :/ dist
	
	' turn vector towards next point (found this on the net somewhere. dont ask, i hate math!)
	If dy*DirX - dx*DirY > 0 Then
		DirX = Cos( Pi / 180.0 * TURN_SPEED) * DirX - Sin( Pi / 180.0 * TURN_SPEED) * DirY
		DirY = Cos( Pi / 180.0 * TURN_SPEED) * DirY + Sin( Pi / 180.0 * TURN_SPEED) * DirX
		If dy*DirX - dx*DirY < 0 Then
			DirX = dx
			DirY = dy
		EndIf
	Else
		DirX = Cos( -Pi / 180.0 * TURN_SPEED) * DirX - Sin( -Pi / 180.0 * TURN_SPEED) * DirY
		DirY = Cos( -Pi / 180.0 * TURN_SPEED) * DirY + Sin( -Pi / 180.0 * TURN_SPEED) * DirX
		If dy*DirX - dx*DirY < 0 Then
			DirX = dx
			DirY = dy
		EndIf	
	EndIf

	' move towards point
	X :+ DirX * MOVE_SPEED
	Y :+ DirY * MOVE_SPEED
	
	' check if we are within next point
	If PointInSpot( X,Y, Path[Curr],Path[Curr+1], POINT_RADIUS) Then
		Curr :+ 2
		If Curr >= Path.Length-1 Then Curr = 0
	EndIf
	
	SetColor 128,128,128
	DrawPolyLine path
	
	SetColor 0,0,255
	DrawOval X-8,Y-8, 16,16
	
	' draw next point
	SetColor 0,255,0
	DrawOval Path[Curr]-8,Path[Curr+1]-8, 16,16	

	Flip
	Cls
	
Until KeyHit(KEY_ESCAPE) Or AppTerminate()
End


Function PointInSpot:Int( x1:Float,y1:Float, x2:Float,y2:Float, radius:Float)
	Local dx:Float = x2 - x1
	Local dy:Float = y2 - y1
	Return Sqr( dx*dx + dy*dy) <= radius
EndFunction

Function DrawPolyLine( xy:Float[])
	For Local i:Int = 0 Until xy.Length - 2 Step 2
		DrawLine xy[i], xy[i+1], xy[i+2], xy[i+3]
	Next
EndFunction