point of impact

BlitzMax Forums/BlitzMax Programming/point of impact

ok so I was trying to add a small explosion animation to the point of impact on a players ship.

problem was finding out how to determine the point of impact on the player ship. guess i have to do a type to handle the updating of the explosion and stuff

I guess using the last known position values of the impacting object won't cut it?

Im not sure of your implementation of your game. Is it 2D or 3D? What method are you using for your collision, boundingVolumes or Full per pixel/polygon collision?

its 2d. I am using imagescollide.

@North
that value changes as soon as it is fired again.

How big are the collision objects? If they're smaller missiles then can't the point of impact be the position of the missile as North suggests?
If they're larger objects (such as asteroids) you'll either have to use polygon collisions (which is quite advanced to find an impact point) or set a number of hotspot testing points around each object. It won't be exact but it should be close enough.
If they collision objects rotate or scale then you'll need to apply the same to the hotspots.
This might help.

yeah they are missles impacting. the thing is that when a missle impacts, it is then deleted and the x and y are gone, or should i do the explosion at the x and y then delete it :)

When the missile impacts, create an explosion object and set it's x/y to the missile x/y. Then you can delete the missile but still have the explosion.

right true, well i set the explosion to the missle x y and it works. didnt before, maybe because the function wasn't complete. thanks alot guys...sorry for confusion.

Function Explode()	
	MidHandleImage(explosion)	
	
	If hit = True 	
		
		SetAlpha 1.0
		SetRotation 0
		
		DrawImage explosion,missle.x,missle.y,frame			
	
		frame :+ 0.3
		If frame > 6 
			hit = False
			frame = 0
		End If
	End If	
End Function


when the animation reaches the last frame, hit becomes false and it stops the animation and resets frame to 0. so when an explosion happens again it starts from frame 0.

i created a type called txplosion as well which works well, but i went with functions as it was simpler and made more sense to create it with a function if it was possible(which it is) than to use OOP.

but im proud of the texplosion type I did. and i can use it for anything else i want to create, any anim, any explosion thing :)

I think you should revisit the texplosion object again. The way you're coding will limit you with missile/explosions.
Your function doesn't pass any missile object so it will use whatever missile.x/y is last set regardless of whether it relates to that explosion. In addition, you can't get rid of missile while it's being used.
I see you've also gone with the 'global to program' option for HIT which is poor design.

yeah I stated in the other thread, I went back to using texplosion, since it can handle multiple explosions using the same fields of the type.


When the missile impacts, create an explosion object and set it's x/y to the missile x/y. Then you can delete the missile but still have the explosion.


i actually already have the explosion object instanced in the type, i globaled it. and i have it called in the loop. exobject.explodeship()
to do an explosion of a ship when hit = true.

But you are saying that ON impact, of if impact, (on collision :) then create an explosion object, do its animation and then delete itself. better memory management? But is it that abd when I only have two objects for explosion anyway? Guess for simple stuff like this it isn't, but the practice is good to do it that way right.

also I used hit as a global just to finish it and test the animation and stuff make sure it was working before I changed it. :)

there are a couple of booleans which I have declared as global in my globals.bmx to control the life and death of the player, such as playing... dead... etc, is that oK? because i have some functions which need to know the state of those conditions, so they can do what I want them to do, based on whether the player is alive or dead.

I guess I can put HIT in a field in the explosion type, and put if object.hit = true in my function.

Plug and Play baby ;)
This ones for free.

Strict

Graphics 640, 480, 0

While Not KeyHit( KEY_ESCAPE )
	Cls

	If MouseHit( 1 )
		TExplosion.Create( MouseX(), MouseY(), 4+Rand( 48 ) )
	EndIf

	GCCollect( )

	TExplosion.UpdateAll( )
	TExplosion.RenderAll( )

	GCCollect( )

	Flip
Wend

'/**
' * TYPE EXPLOSION
' */
Type TExplosion

	'/**
	' * LOCAL EXPLOSION DATA
	' */
	Field Px:Float, Py:Float	'position
	Field Time:Int				'time exposition has existed for
	Field TimeToLive:Int		'life span of explosion
	Field Size:Float			'size of explosion (radius)
	
	'/**
	' * LINKED EXPLOSION LIST
	' */
	Global FstExp:TExplosion	'first explosion in linked list
	Global LstExp:TExplosion	'last explosion       ''
	Field  NxtExp:TExplosion	'next explosion       '' (relative to instance)
	Field  PrvExp:TExplosion	'previous explosion   '' (relative to instance)

	'/**
	' * TEXPLOSION CONSTRUCTOR
	' */
	Method New( )
		'add to linked list
		If LstExp <> Null
			LstExp.NxtExp = Self
			self.PrvExp = LstExp
			LstExp = Self			
		Else
			FstExp = Self
			LstExp = Self
		EndIf		
	End Method
					
	'/**
	' * CREATE A NEW EXPLOSION
	' */
	Function Create( aPx:Float, aPy:Float, aSize:Float, aTTL:Int=-1 )	
		'create a new position
		Local TExp:TExplosion = New TExplosion
		'store positions
		TExp.Px = aPx
		TExp.Py = aPy
		'store size
		TExp.Size = aSize
		'check time to live
		If aTTL > 0
			TExp.TimeToLive = aTTL
		Else
			'automaticly calculate explosion size
			'replace to suit your vibes
			TExp.TimeToLive = aSize*20
		EndIf
	End Function

	'/**
	' * UPDATE ALL TEXPLOSIONS
	' */
	Function UpdateAll( )
		'start off with first in the list
		Local TExp:TExplosion = FstExp
		'update all in turn
		While TExp <> Null
			'update explosion time
			TExp.Time = TExp.Time+32
			'time to live checks
			If TExp.Time > TExp.TimeToLive
				'kill the explosion
				TExp.Kill( )
			EndIf
			'move to next explosion
			TExp = TExp.NxtExp
		Wend
	End Function

	'/**
	' * RENDER ALL TEXPLOSIONS
	' */
	Function RenderAll( )
		'start of with first in the list
		Local TExp:TExplosion = FstExp		
		'render all in turn
		While TExp <> Null
			TExp.Render( )
			'move to next explosion
			TExp = TExp.NxtExp		
		Wend		
	End Function
	
	'/**
	' * KILL THE HOST TEXPLOSION
	' */
	Method Kill( )
		'update previous explosion
		If self.PrvExp <> Null
			self.PrvExp.NxtExp = Self.NxtExp
		EndIf
		'update next explosion
		If Self.NxtExp <> Null
			self.NxtExp.PrvExp = Self.PrvExp
		EndIf
		'change linked list general
		If FstExp = Self Then FstExp = self.NxtExp
		If LstExp = Self Then LstExp = self.PrvExp
	End Method

	'/** 
    ' * GET THE EXPLOSION SIZE
    ' */
	Method GetSize:Float( )	
		'explosion scale based on time
		Local scale:Float = (Float( Time )/TimeToLive)*90
		scale = Sin( scale )
		'return the size
		Return size*scale
	End Method

	'/**
	' * RENDER THE EXPLOSION 
	' */
	Method Render( )
		Local MySize:Float = GetSize( )
		SetColor 255, 195, 85
		SetBlend( ALPHABLEND )
		SetAlpha 1-(MySize/Size)
		DrawOval Px-MySize-2, Py-MySize-2, MySize*2+4, MySize*2+4
	End Method

End Type


You should use a better blending function than SIN because its a bit wimpy. ALso the timing for the explosion is dictated by the frame rate. This is realy bad and you should integrate it with your game timer. Changing from DrawOval to your frame based animation should be rather breezy. Other than that I hope you can put this code to good use, have fun.

thanks, thats some nice code!

looks like i could use it for a shield hit effect too. i want my shield invisible around the ship. setalpha 0. but still for the image to be there, so when a missle collides with the shield, it flares for a bit then goes back down to its invisible self.

as I suspected, setting the point of impact to missle x and y, works for one missile. If you are firing multiple missiles, hitting the target one after the other, you dont see the explosion. my guess is because a new missile x and y has started before the other one has reached the target.... so only the last missiles impact animation will be done.

Are you using global variables to implement your misiles or a type structure? Can you see more than one missile on the screen at a time? You could adapt the explosion code I wrote to handle the creation of missiles with a direction, etc.
If you would like to do that then I could walk you through it.

My guess is your code design is wrong. Everything needs to be seperate objects.
This *might* help
SuperStrict
Graphics 640 , 480
SeedRnd MilliSecs()
While Not KeyHit(KEY_ESCAPE)
	Cls
	If MouseHit(1) tmissile.create(MouseX() , MouseY() )
	tmissile.update()
	texplosion.update()
	tmissile.render()
	texplosion.render()
	Flip -1
Wend
Type tmissile
	Global list:TList=CreateList()
	Field x:Int
	Field y:Int
	Field speed:Int
	Field life:Int
	Function Create(x:Int , y:Int)
		Local temp:tmissile = New tmissile
		temp.x = x
		temp.y = y
		temp.speed = Rand(1 , 3)
		temp.life=Rand(20,100)
		ListAddLast list,temp
	End Function
	Function update()
		For Local all:tmissile = EachIn list
			all.y = all.y - all.speed
			all.life:- 1
			If all.life < 0 Or all.y < 0
				If all.life < 0
					texplosion.create(all.x , all.y) 
					ListRemove list , all
				Else
					ListRemove list,all
				EndIf
			EndIf
		Next
	End Function
	Function render()
		SetColor 255,255,255
		For Local all:tmissile = EachIn list
			DrawOval all.x-4 , all.y-4 , 8 , 8
		Next
	End Function
End Type
Type texplosion
	Global list:TList=CreateList()
	Field x:Int
	Field y:Int
	Field size:Int=8
	Function Create(x:Int , y:Int)
		Local temp:texplosion = New texplosion
		temp.x = x
		temp.y = y
		ListAddLast list,temp
	End Function
	Function update()
		For Local all:texplosion = EachIn list
			all.size:+1
			If all.size > 20 ListRemove list , all
		Next
	End Function
	Function render()
		SetColor 255,0,0
		For Local all:texplosion = EachIn list
			DrawOval all.x-(all.size/2) , all.y-(all.size/2) , all.size , all.size
		Next
	End Function
			
End Type
	


i dont know, it just isn't working, my mind is clay right, probably tired from work. its 3 a.m

I normally leave something and come back to it fresh and solve it. but this is frustrating to leave.

my objects are separate because they move separate update separate and impact separate. when one missile impacts and gets deleted, all the rest are not deleted. each missile impact does its damage, i can multiple missiles all over the screen, so that means each missile object is updated separate. i more feel the problem is with how i can creating the explosion.

Give your TMissile the methods 'explode' and 'remove'

explode deals with the animation of the fireball
remove does just that

Maybe you could just post all the relevant pieces of code here, no?

ok I followed tonyg's code a little more closely, it was as I suspected. The missile code was fine, it was just an explosion for each impact that wasn't being done.

so I added a create function for the explosion, then put the update and draw functions in the main loop. The update does an update for each explosion and the draw, draws each explosion.

the create function is called in my collision code when the missile impacts a target, which starts the ball rolling updating it and drawing it.

I had the drawing stuff basically in the update, and then I called the draw function in the update function, these ways didn't work. I wanted this way though to avoid putting more than neccessary in the loop.

i think i can probably put them all now in one function and call that function in the loop

func goInLoop()
update()
draw()
end func

put goInloop() in the main loop? :)