need help with missle code please

BlitzMax Forums/BlitzMax Programming/need help with missle code please

i've typed up some rough code as a place to start, and it
works and looks fairly decent, but not as well as i'd like.

1. how would i get the missle to go in a straight line even on and angle, instead of doing the over 1, up 1 type thing.

2. how do i get a trail to follow the missle, regardless of
the angle. as is right now it follows it from then center of origin, and when the missle rotates the trail doesn't always line up.
also i'd like the trail to start at the end of the missle, and not the middle.

any help would be appreciated.



'move missle to target
    If missleon = 1
        'create the smoke and fire trail
        Local r=Rand(0,100)
        If  r>95
            TParticles.CreateParticle(mx#+Sin(mx#),my#+Cos(my#),500,"smoke",0.01,1)
            TParticles.CreateParticle(mx#+Sin(mx#),my#+Cos(my#),10,"fire",0.1,1)
        EndIf
        
        'move
        If mx# < tmx# then mx#:+mxspeed#
        If mx# > tmx# Then mx#:-mxspeed#

        If my# < tmx# then my#:+myspeed#
        If my# > tmx# Then my#:-myspeed#

        If mx# = tmx# And my# = tmy# Then missleon = 0

        'get the angle between missle and target 
        'to point the missle at the target
        misslerot# = Angle360b#(mx#,my#,tmx#,tmy#)
    EndIf

Function Angle360b#(x1,y1,x2,y2)
    'Returns a 360 degree angle between 2 points, 0..359 degrees
    'By Snarkbait, 9 Mar 2008
    Return (ATan2(y2-y1,x2-x1)+450) Mod 360
End Function


here's some code if it helps:


SeedRnd MilliSecs()

Global ParticleList:TList = CreateList()

'A partical object, handles particals
Type TParticle
	'set fields
	Field x:Float,y:Float,a:Float = 1,r:Int		'x cords, y cords, alpha, rotation
	Field ox:Int,oy:Int	'original x, original y
	Field img:TImage	'partical image
	Field dx:Float,dy:Float, da:Float	'x direction, y direction(if it moves at all), direction alpha(if it fades)
	Field maxdistance:Int		'The max distance it can live/travel, in frames.
	Field fade:Int		'If the particle fades or remains constant
	Field z:Int	'the level it's drawn at
	
	'Create a new partical to be updated
	'X cord, Y cord, Partical Image, (Direction in degrees, traveling speed, frames that it lasts, if it fades)
	Method Create:TParticle(_x:Int, _y:Int, _img:TImage, _dir:Int = 0, _speed:Float = 0, frames:Int = 1, _fade:Int = False, _z:Int = 0)
		ListAddLast(ParticleList,Self)
		x = _x
		y = _y
		ox = _x
		oy = _y
		img = _img
		dx = Sin(_dir) * _speed
		dy = Cos(_dir) * _speed
		da = 1.0 / frames
		maxdistance = frames
		

		If _fade
			fade = True
		End If
	End Method
	
	'Update a particle object
	Method Update:TParticle()
		x:+dx
		y:+dy
		If fade a:-da
		SetRotation(r)
		SetAlpha(a)
		DrawImage img,x,y
		SetRotation(0)
		SetAlpha(1)
		
		maxdistance:- 1
		If Not maxdistance Then
			Destroy()
		End If
		

	End Method
	
	'Updates all the particles at a Z level
	Method UpdateAll(z:Int = 0)
	
	End Method
	
	Method SetPAlpha(alpha:Float)
		a = alpha
	End Method
	
	Method SetPRotation(rot:Int)
		r = rot
	End Method
	
	Method Destroy()
		ParticleList.Remove(Self)
	End Method
	
	Method SetX(_x:Int)
		x = _x
	End Method
	
	Method SetY(_y:Int)
		y = _y
	End Method
	
	Method DistanceTraveled:Float()
		Local returnx:Float=Abs(ox-y)
		Local returny:Float=Abs(oy-y)
		Return returnx+returny	
	End Method
	
	
End Type


'places a partical at said point for said duration, fading optional, as is moving
Function EmitPartical(_x:Int, _y:Int, image:TImage, frames:Int, fade:Int = True, dir:Int = 0, speed:Float = 0)

	Local part:TParticle = New TParticle.Create(_x, _y, image, dir, speed, frames, fade)

End Function


AppTitle = "Partical trail test"
Graphics 800,600,0
SetBlend alphablend

'Create a dot image (our partical)
Global dot:TImage = CreateImage(20, 20) 
DrawOval 0, 0, 20, 20
GrabImage(dot,0,0)

While Not KeyHit(KEY_ESCAPE)
Cls
	EmitPartical(MouseX(),MouseY(),dot,10)
	For Local UpdateParticles:TParticle = EachIn ParticleList
		UpdateParticles.Update()
	Next
Flip
Wend
End


1. you first need to separate the direction of travel from speed of travel based on x and y, usually dx and dy
dx = cos(missileangle)
dy = sin(missileangle)
they are the direction of movement for one unit movement.
To move an object one unit, all you you need to do is to add dx and dy to the current position:
missilex = missilex+dx
missiley = missiley+dy
if you want to add a speed variable all you need to do is:
missilex = missilex+dx*speed
missiley = missiley+dy*speed
If you want to change direction, all you have to do is change the angle and recalculate dx and dy.

2. the easyest way is to set the image handle to the base of the missile.
but if you want to do it the more complicated way:

set the handle to the center of the image.
calculate the distance between the center of the image/missile to the base/tail of the missile.
D = sqr((x2-x1)^2+(y2-y1)^2)
or
D = sqr((imagewidth/2)^2+(imageheight/2)^2)
you have to do the previous only once.
To find where to place the particle you need to add or subtract 180 degrees from the direction of the missile this will give you the angle of the tail of the missile.

{
particleangleposition = missileangle+180

px = cos(particleangleposition)* D
py = sin(particleangleposition)* D

} this are done everytime it changes direction/angle.

particlepositionx = missilex+px
particlepositiony = missiley+py

and you don't need to move the particle/s only create them/it and keep on drawing them/it for a certain amount of time then delete as time passes by.

I hope this helps?
I posted some code in the code archives a while back:
http://www.blitzmax.com/codearcs/codearcs.php?code=2045
it doesn't help for number 2 but it will give you an idea for number 1.

thankyou for the help guys.

parts of that stuff does seem like some different stuff i've already tried with the same results.
ie. the trail is of to the side not directly under the missle. also for some strange reason the missle will only goto a certain y level and stop.
this is implementing in the code that Jesse wrote.

anyways thanks again for the help, and i'm gonna study the code some more and hack away at it til i get it tomorrow/today when i'm not so tired.
----------------------------------------
Edit:

ok i lied i haven't gone to bed yet.
i was tinkering around and got the trail to work,(looks cool btw.. big thanks for that cause it was really bugging me)

what i did was my missle pic is 24 by 64 so i
setimagehandel(image,12,64)
px = Cos(particleangleposition)' * d
py = Sin(particleangleposition)' * d

i had to rem out them *d so maybe i misinterpreted the way it was supposed to be done.

i can live with my pathetic way of moving the missle
If mx# < tmx# Then mx#:+misslespeed#
If mx# > tmx# Then mx#:-misslespeed#
If my# < tmy# Then my#:+misslespeed#
If my# > tmy# Then my#:-misslespeed#

because in this paticular game it works fine, but im still gonna play around with that once i get some sleep and can think a little clearer

sorry to bring back an old topic, but i've been playing with this some more and got it working. i had to multiply dy by (-1) to get it working though.

anyway i whipped up a quick test program, so here it is. i hope it can help others out.

Graphics 800,600

Global a							'angle
Global x# = 400,y# = 300			'ball position
Global dx# ,dy#						'x/y directions
Global tx# ,ty#						'target x/y position
Global movespeed#  = 5.5			'how fast ball moves
Global moveon = 0					'toggle on/off ball movement
Global mx,my						'holders for mouse x/y position
Local quit = 0

While quit = 0
Cls
	If moveon = 1 Then Move()
	DrawOval(x-5,y-5,10,10)

DrawText "x: "+x,10,10
DrawText "y: "+y,10,20
DrawText "tx: "+tx,10,30
DrawText "ty: "+ty,10,40
DrawText "a: "+a,10,50
DrawText "dx: "+dx,10,70
DrawText "dy: "+dy,10,80

Flip
	mx = MouseX()
	my = MouseY()
		
	If MouseHit(1)			
		tx = mx
		ty = my
		a = Angle360#(x,y,tx,ty)	
		dx = Sin(a)*movespeed#
		dy = (Cos(a)*movespeed#)*-1
		moveon = 1
	EndIf
	
	If AppTerminate() Then quit = 1
	If KeyDown(key_escape) Then quit = 1
	FlushMouse
Wend
End

Function Angle360#(x1,y1,x2,y2)
	'Returns a 360 degree angle between 2 points, 0..359 degrees
	'By Snarkbait, 9 Mar 2008
	Return (ATan2(y2-y1,x2-x1)+450) Mod 360
End Function

Function Move()	
	x:+dx
	y:+dy
	
	If x > tx - (2+movespeed) And x < tx + (2+movespeed) Then x = tx
	If y > ty - (2+movespeed) And y < ty + (2+movespeed) Then y = ty
	If x = tx And y = ty Then moveon = 0	
End Function



here you go:

Graphics 800,600

Global a#							'angle
Global x# = 400,y# = 300			'ball position
Global dx# ,dy#						'x/y directions
Global tx# ,ty#						'target x/y position
Global movespeed#  = 5.5			'how fast ball moves
Global moveon = 0					'toggle on/off ball movement
Global mx,my
Global l#
						'holders for mouse x/y position
Local quit = 0

While quit = 0
Cls
	If moveon = 1 Then Move()
	DrawOval(x-5,y-5,10,10)

DrawText "x: "+x,10,10
DrawText "y: "+y,10,20
DrawText "tx: "+tx,10,30
DrawText "ty: "+ty,10,40
DrawText "a: "+a,10,50
DrawText "dx: "+dx,10,70
DrawText "dy: "+dy,10,80
DrawText "distance: "+l,10,90

Flip
	mx = MouseX()
	my = MouseY()
		
	If MouseHit(1)			
		tx = mx
		ty = my
		a = Angle360#(x,y,tx,ty)	
		dx = Cos(a)*movespeed#
		dy = Sin(a)*movespeed#
		moveon = 1
	EndIf
	
	If AppTerminate() Then quit = 1
	If KeyDown(key_escape) Then quit = 1
	FlushMouse
Wend
End

Function Angle360#(x1,y1,x2,y2)
	'Returns a 360 degree angle between 2 points, 0..359 degrees
	'By Snarkbait, 9 Mar 2008
	Return ATan2(y2-y1,x2-x1)
End Function

Function distance#(x1,y1,x2,y2)
	Return Sqr((x2-x1)^2+(y2-y1)^2)
End Function

Function Move()	
	x:+dx
	y:+dy
	l# = distance(x,y,tx,ty)' find distance to target
	If l < movespeed  ' if distance is less than move speed
		x = tx
		y = ty
		moveon = 0
	EndIf
End Function


always use cos for x and sin for y
create your image pointing right always sence 0 angle is to the right and you won't go wrong.
like this
-->
instead of like this
^
|
|

wow unbelieveable, no wonder i was having so much trouble with it. i must have studied your's and Yahfree's code amoung other exampels on the forums over and over again off and on over these past months trying to figure out what i was doing wrong, i could have sworn i saw cos,sin the other way around even when i picked it up again today because of one of my current projects i couldn't figure out why i needed to multiply dy by (-1) to get it to work and i studied both your codes in this thread again and still could have sworn that cos,sin were the other way around. thanks for straightening me out but gee maybe i need glasses lol. although my code above works great and actually looks really cool in both my original game that this thread was started for and my current project both with the image created facing upwards, now i'm intrigued and will change things over, but definately not until i get some sleep.

also in one of my other threads Warpy mentioned possibly compiling together a games math tutorial of sorts, i haven't heard anything else about it since though but i hope he does because i think that it would be invaluble not only to me but many others.

for now i just have to drill it in my head x-cos y-sin ;-)
thanks again

http://www.essentialmath.com/tutorial.htm

There you go.

cool thanks.