Collision(something strange goin'on...)

BlitzPlus Forums/BlitzPlus Programming/Collision(something strange goin'on...)

Valgar(Posted 2003) [#1]
I have made a simple prog to test collision(from wich i made my collision routines).
I have the old mouse pointer with a jet,and when i use the right-mouse-button i create an alien ship that go from left to right...
I use images collide and set the energy of the alien...
But something strange goin'on somethimes the alien self-destruct itself (LOL) and somethimes i only need two missile to destroy it (ROFL).
Where's the error?
I think that it's in the variable that contains the x and y location but don't figured out yet -_-'

Here's the code:

Graphics 640,480,32,1
SetBuffer BackBuffer()
Global posizionex
Global posizioney
Global posalienx
Global posalieny
Global aereo=LoadImage("d:\jet1.tga") ;a simple sprite
Global terreno=LoadImage("d:\terreno.bmp") ;a simple texture of 256*256
Global missil=LoadImage("c:\missile2.bmp") ;a simple sprite
Global alien=LoadImage("d:\velivolo1.tga") ;a simple sprite
MidHandle aereo
MidHandle missil
MidHandle alien
HidePointer
Const limite_sx=100
Const limite_dx=540
Global b.alieno
Type missile ;an object called missile
Field posx Field posy Field avanzamento Field contatore
End Type

Type alieno
Field movx,movy,movimento,energia
End Type

Repeat Cls
DrawImage aereo,MouseX(),MouseY()
If MouseHit(2)=1
create_alien()
EndIf
move_alien()
If MouseHit(1)=1 ;if i hit the mouse button i create a missile
create_missile()
EndIf
play_missile() ;this start the missil anim
Flip
Until KeyDown(1)=1
End


Function create_missile()
a.missile=New missile
a\posx=MouseX() ;the x position of missile creation is the mouse coords(the same coords of my jet of course)
a\posy=a\posy+MouseY()-45 ;the missile creation start a bit up to the jet(for simulating the launch-bay hehe)
a\avanzamento=4 ;the speed of the missile
a\contatore=0 ;the starting value of the animation
End Function

Function play_missile()
For a.missile=Each missile
posizionex=a\posx
posizioney=a\posy
DrawImage missil,a\posx,a\posy
a\posy=a\posy-a\avanzamento ;this move the missile up
a\contatore=a\contatore+a\avanzamento ;this start the counter of the missile course
;If a\contatore=> 200 Then Delete a ;if the course reach 200 the missile explode(hehe)
If ImagesCollide(missil,posizionex,posizioney,0,alien,posalienx,posalieny,0)
Delete a ;if the missile collide with the alien the missile stop it's existance :P
EndIf
Next
End Function

Function create_alien()
b.alieno=New alieno
b\movx=100
b\movy=60
b\movimento=1
b\energia=5 ;the "teoric" energy of the alien,from when reach 0 the alien explode
End Function

Function move_alien()
For b.alieno =Each alieno
posalienx=b\movx
posalieny=b\movy
DrawImage alien,b\movx,b\movy
b\movx=b\movx + b\movimento

If b\movx => limite_dx
b\movx=b\movx-b\movimento
b\movimento=-1
EndIf

If b\movx =< limite_sx
b\movx=b\movx+b\movimento
b\movimento=+1
EndIf

If ImagesCollide(missil,posizionex,posizioney,0,alien,posalienx,posalieny,0)
b\energia=b\energia-1 ;if the alien collide with the missile the energy go down of one unit
Text 400,400,b\energia
EndIf
If b\energia=<0 Then Delete b
Next
End Function


I don't need at all costs pixel-perfect collision detection,i think that "rectangle" collision with many rectangle to simulate the "shape" of the object works also very well and is faster;i think correct or wrong?


Ross C(Posted 2003) [#2]
eh....i dunno where to start LOL. you have a slight problem tho in your code. if you create more than one bullet or more than one alien, when it comes to check collisions, it will only check against one alien and one bullet.

You should really create another field called "image". that way, each object in the type will have it's own alien ship.

Type alieno 
Field movx,movy,movimento,energia
field image
End Type


to get the type to use the image.(remember don't copy the image, because if alot of copying and freeing of images happens in your game then it will cause memory fragmentation, and will slow down performance :D )

Function create_alien() 
b.alieno=New alieno
b\image=alien; make b\image represent your image in this type object
b\movx=100 
b\movy=60 
b\movimento=1 
b\energia=5 ;the "teoric" energy of the alien,from when reach 0 the alien explode 
End Function


your also need to change this for the missile too.


Ross C(Posted 2003) [#3]
right, i've added in a few things. Another thing i done was to put all your collision detection in the animate missile function. here's why.

the way you were doing it

loop through each rocket and see if it has collided with an alien ship. Since your using types the way you've written it, it will only check against one alien

the way i did it

set up a loop to loop through each rocket. the program selects the first rocket and loops through all the aliens checking the collisions between the rocket and the alien ships. the program then goes to the next rocket then checks against all the aliens again, etc

it's alot of collsion detection, but it makes sure you get everything. that's why you had strange things like

the alien self-destruct itself (LOL) and somethimes i only need two missile to destroy it (ROFL).



so here's the fixed code

Graphics 640,480,32,1
SetBuffer BackBuffer() 
Global posizionex 
Global posizioney 
Global posalienx 
Global posalieny 
Global aereo=LoadImage("d:\jet1.tga") ;a simple sprite 
Global terreno=LoadImage("d:\terreno.bmp") ;a simple texture of 256*256 
Global missil=LoadImage("c:\missile2.bmp") ;a simple sprite 
Global alien=LoadImage("d:\velivolo1.tga") ;a simple sprite
MidHandle aereo 
MidHandle missil 
MidHandle alien 
HidePointer 
Const limite_sx=100 
Const limite_dx=540 
Global b.alieno 
Type missile ;an object called missile 
	Field posx Field posy Field avanzamento Field contatore 
	Field image
End Type 

Type alieno 
	Field movx,movy,movimento,energia,image
End Type 

Repeat
	Cls 
	DrawImage aereo,MouseX(),MouseY() 
	If MouseHit(2)=1 
		create_alien() 
	EndIf 
	move_alien() 
	If MouseHit(1)=1 ;if i hit the mouse button i create a missile 
		create_missile() 
	EndIf 
	play_missile() ;this start the missil anim
	Flip 
	Until KeyDown(1)=1 
End 


Function create_missile() 
	a.missile=New missile
	a\image=missil
	a\posx=MouseX() ;the x position of missile creation is the mouse coords(the same coords of my jet of course) 
	a\posy=a\posy+MouseY()-45 ;the missile creation start a bit up to the jet(for simulating the launch-bay hehe) 
	a\avanzamento=4 ;the speed of the missile 
	a\contatore=0 ;the starting value of the animation 
End Function 

Function play_missile() 
	For a.missile=Each missile 
		posizionex=a\posx 
		posizioney=a\posy 
		DrawImage a\image,a\posx,a\posy 
		a\posy=a\posy-a\avanzamento ;this move the missile up 
		a\contatore=a\contatore+a\avanzamento ;this start the counter of the missile course 
		;If a\contatore=> 200 Then Delete a ;if the course reach 200 the missile explode(hehe)
		For b.alieno=Each alieno
			If ImagesCollide(a\image,a\posx,a\posy,0,b\image,b\movx,b\movy,0) ;if the alien collide with the missile the energy go down of one unit
					b\energia=b\energia-1
					Text 400,400,b\energia 
					If b\energia=<0 Then Delete b
					Delete a ;if the missile collide with the alien the missile stop it's existance :P
					Exit ;exit loop if missile is dead. will cause error as they's no missile to check against the aliens
			EndIf
		Next
	Next 
End Function 

Function create_alien() 
	b.alieno=New alieno
	b\image=alien
	b\movx=100 
	b\movy=60 
	b\movimento=1 
	b\energia=5 ;the "teoric" energy of the alien,from when reach 0 the alien explode 
End Function 

Function move_alien() 
	For b.alieno =Each alieno 
		posalienx=b\movx 
		posalieny=b\movy 
		DrawImage b\image,b\movx,b\movy 
		b\movx=b\movx + b\movimento 
		
		If b\movx => limite_dx 
			b\movx=b\movx-b\movimento 
			b\movimento=-1 
		EndIf 
		
		If b\movx =< limite_sx 
			b\movx=b\movx+b\movimento 
			b\movimento=+1 
		EndIf 
		Text b\movx,b\movy-20,b\energia
	
	Next
End Function


hey, if you've got any further questions please post back :D


Valgar(Posted 2003) [#4]
Greath i have tried the improved code and it works wonderful!(to tell the truth i have only copyied and pasted it but i haven't looked at it well -_-' )
The big things that i see is:adding a field type called image
adding all the collision detection in the anima missile function

I think that there's a lot of collision detection but for a simple games works well.
I only think when i add 20 or more type of aliens hehe

There's an alternative way of doing collision detection instead of doing pixel-perfect?
I ask this because nobody see if my bullet explode exactly when touch the alien,so if i use a simple metod of doing collision (something like a "bounding box"...)nobody notice the difference!
Many thanks for the help!


Ross C(Posted 2003) [#5]
well, in my space shooter i've got quite a few collisions on the go and i think most of them are pixel perfect ones.
the other command you can use, that uses bounding box collisions is
ImagesOverlap (image1,x1,y1,image2,x2,y2)


that command is VERY quick

glad i could help!