follow path

BlitzMax Forums/BlitzMax Beginners Area/follow path

hub(Posted 2006) [#1]
Hi !
In my game i want add satellites (red) to the player ship (white). (LMB to create a satellite). My problem : Red satellites don't follow exatly the player movement (see the white twist, cord, tie up (sorry for bad english : Systran translation ;-))





Chris C(Posted 2006) [#2]
have a look at scotts flocking stuff in the tutorials


hub(Posted 2006) [#3]
scott code seems to be interesting but i've some difficulties to understand and adapt it to my purpose ! my satellite are not ennemies, just virtual ships at side of player ship. When it move they follow the player (Gradius). Is there an easier method to do this ?


Chris C(Posted 2006) [#4]
I havent had chance to look at scotts code in a little while, but I'm firly sure you can use it extend the behaviour so the satellites will fly around while staying seperated from you and each other...
Scott is busy writing a tutorial I'm recon that once its finished I'm sure you'll see how to easly use it in your project rather than having to adapt it...


Mark1nc(Posted 2006) [#5]
You could do something like this:
Local ddx# = joyx-s.x
Local ddy# = joyy-s.y 
Local dist# = Sqr(ddx*ddx + ddy*ddy)+0.001
If dist > 150 ' too far away - move closer
	s.x = s.x + ddx/dist
	s.y = s.y + ddy/dist
ElseIf dist < 64 ' too close - move away
	s.x = s.x - ddx/dist
	s.y = s.y - ddy/dist
EndIf



Dreamora(Posted 2006) [#6]
You could look at spring forces and simple create a virtual spring between the satellites and the ship, this way they would follow.
A spring is simply a direction force which holds the following formula:

Force = (PosShip - PosSatellite)(PosShip - PosSatellite) * k

where k is the spring constant.
After that you can simply apply this force vektor to the satellite.
This means your satellite need a virtual weight (you can use this as a second constant to make different satellite type to react with different speeds while you keep k constant for all satellites) because
accelerationSatellite = force / WeightSatellite

then

speedSatellite = speedSatellite + accelerationSatellite

Note: speed, acceleration, position, force are all 2D vectors if you want to do it in 2D or 3D vectors if you do it in 3D


klepto2(Posted 2006) [#7]
Here is a small sample using scotts spritebeviors.

Strict

Import sas.spritebehaviors

Graphics 800,600



Parameters.SeparationWeight= 8
Parameters.AlignmentWeight= 4
Parameters.CohesionWeight= 10
Parameters.ObstacleAvoidanceWeight=10
Parameters.WallAvoidanceWeight= 99
Parameters.WanderWeight = 50
Parameters.SeekWeight=5
Parameters.FleeWeight=1
Parameters.ArriveWeight=1
Parameters.PursuitWeight=1
Parameters.OffsetPursuitWeight=1
Parameters.InterposeWeight=1
Parameters.HideWeight=1
Parameters.EvadeWeight= 0.01
Parameters.FollowPathWeight=0.05
Parameters.ViewDistance = 25

Global colrad:Double = 32

Global world:GameWorld = GameWorld.Create(GraphicsWidth(),GraphicsHeight())
Delta.Start()

Local Leader:Sprite = Sprite.CreateForSteering(Null, world, CreateVector(MouseX(),MouseY()), Rand(0,359), CreateVector(0,0), 1, 4, 4, 180, .5)
		Leader.SetCollisionRadius(colrad)
		Leader.GetSteering().ObstacleAvoidanceOn() ' Turn on the flocking behaviors 
		Leader.SetWorldWrap(True)			' allow the prites to wrap from on side to the other of the screen
		world.AddVehicle(Leader)





Local ld = 40
Local ax, ay

ax = MouseX()- ld
ay = MouseY()- ld

While Not KeyDown(KEY_ESCAPE)
	
		Cls
		SetColor 255,255,255
		Leader.SetPosition(MouseX(),MouseY())
				
		If MouseDown(1) Then
			Local s1:sprite = Sprite.CreateForSteering(Null, world, CreateVector(ax,ay), Rand(0,359), CreateVector(0,0), 1, 4, 4, 180, .5)
			s1.SetCollisionRadius(colrad)
			s1.GetSteering().ObstacleAvoidanceOn() ' Turn on the flocking behaviors 
			s1.GetSteering().FlockingOn() ' Turn on the flocking behaviors  
			s1.GetSteering().SeekOn(Leader)
			s1.SetWorldWrap(True)			' allow the prites to wrap from on side to the other of the screen
			world.AddVehicle(s1)
	
			ax = MouseX()- ld
			ay = MouseY()- ld
			ld = ld + 20
			FlushMouse()
		End If
		
		world.Update(Delta.Time())	' update the agents
		world.Render()				' render the world
		Flip
		Delta.update()

Wend


You need to have the sas.spritebehaviors module installed from his side and build it.


hub(Posted 2006) [#8]
@all : many Thanks for your answers.
@Dreamora : where is my error ? k and Weight values ?




Dreamora(Posted 2006) [#9]
No, it was an error on my side, because I missed 2 things:

1. You need to define a length in which the spring does not push or pull
2. I gave you the formula for the spring energy, not force


Here is the working one, sorry for making headache


Strict


Graphics 800,600


Global jposx
Global jposy


Global Satellites_list:TList = CreateList()

Type TSatellite

	Field x#
	Field y#
	Field SpeedX#
	Field SpeedY#

	
	Function Create:TSatellite (x:Int, y:Int)
	
		Local n:TSatellite = New TSatellite
		
		n.x# = x
		n.y# = y
		
		ListAddLast Satellites_list, n
		
		Return n
	
	End Function
	
	Function Update()
	
		
		Local Weight# = 5.0
		
		Local k# = 0.01
		Local spring_neutral_length# = 8.0
	
		For Local s:TSatellite = EachIn Satellites_list
		
			Local dx#	= s.x - Float(jposx)
			Local dy#	= s.y - Float(jposy)
			
			Local ForceX# = (spring_neutral_length-dx) * k
			Local ForceY# = (spring_neutral_length-dy) * k 
			
			Local AccelerationX# = Float(ForceX# / Weight#)
			Local AccelerationY# = Float(ForceY# / Weight#)
			
			s.SpeedX# = s.SpeedX# + AccelerationX#
			s.SpeedY# = s.SpeedY# + AccelerationY#
			
			s.x# = s.x# + s.SpeedX#
			s.y# = s.y# + s.SpeedY#
			
			DebugLog s.x
			DebugLog s.y
			
			SetColor 255,0,0
			DrawOval s.x,s.y, 20,20
			
		Next
	
	End Function

End Type

While Not KeyDown(KEY_ESCAPE)
	
		Cls
		jposx = MouseX()
		jposy = MouseY()
		SetColor 255,255,255
		DrawOval MouseX(), MouseY(), 10,10
		TSatellite.Update()
		
		If MouseDown(1) Then
			Local s1:TSatellite = TSatellite.Create (MouseX()+10, MouseY()+10)
			FlushMouse()
		End If
		
		Flip
Wend



hub(Posted 2006) [#10]
awesome dreamora. Is there a method to avoid the 'spring effect'. Imagine that the link between the player and the satellite is a rigid stick !