Source:BoxCollision.pb
;Comtois 03/12/04
;Tut sur les Box Collisions
;l'exemple est en 2D , mais le principe est le même pour la 3D.
;la différence réside dans le test de l'encadrement
;en 2D on a collision si xa2>xb1 And xa1<xb2 And ya2>yb1 And ya1<yb2
;en 3D on a collision si xa2>xb1 And xa1<xb2 And ya2>yb1 And ya1<yb2 And za2>zb1 And za1<zb2
;Avec xa1,ya1,za1 les coordonnées du coin haut gauche de la box A
;et xa2,ya2,za2 les coordonnées du coin bas droit de la box A
;un petit dessin pour une box 2D
; xa1/ya1 _________xa2/ya1
; | |
; | |
; | |
; | |
; | |
; xa1/ya2|_________|xa2/ya2
;En 3d cette méthode fonctionne dans la mesure où il n'y a pas rotation sur les box.
;Par exemple , Cette méthode peut être utilisée pour un jeu de casse briques 3D ou encore dans un space invaders 3D.
;-Declare
Declare Erreur(Message$)
;-Initialisation
#ScreenWidth = 800 : #ScreenHeight = 600 : #ScreenDepth = 32
If InitEngine3D() = 0
Erreur("Impossible d'initialiser la 3D , vérifiez la présence de engine3D.dll")
ElseIf InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse()=0
Erreur("Impossible d'initialiser DirectX 7 Ou plus")
ElseIf OpenScreen( #ScreenWidth , #ScreenHeight , #ScreenDepth , "" ) = 0
Erreur("Impossible d'ouvrir l'écran ")
EndIf
Structure Zone
x.l
y.l
Largeur.l
Hauteur.l
EndStructure
Global Sprite1.point
Global Sprite2.point
;/Sprite 1
Sprite1\x=400
Sprite1\y=300
CreateSprite(1,128,128)
If StartDrawing(SpriteOutput(1))
Box(0,0,SpriteWidth(1),SpriteHeight(1),RGB(185,155,255))
StopDrawing()
EndIf
;/Sprite 2
Sprite2\x=0 ; utilise les coordonnées de la souris
Sprite2\y=0 ; utilise les coordonnées de la souris
CreateSprite(2,82,82)
If StartDrawing(SpriteOutput(2))
Box(0,0,SpriteWidth(2),SpriteHeight(2),RGB(55,55,255))
StopDrawing()
EndIf
;-Procedures
Procedure Erreur(Message$)
MessageRequester( "Erreur" , Message$ , 0 )
End
EndProcedure
Procedure BoxCollision(NoA,xa1,ya1,NoB,xb1,yb1)
;NoA = No du sprite 1
;xa1,ya1 = coordonnées du sprite 1
;NoB = No du sprite 2
;xb1,yb1 = coordonnées du sprite 2
;C'est la même chose que la fonction purebasic SpriteCollision() ,
;ça pourrait être ImageCollision() d'ailleurs , il suffit de remplacer sprite par image dans le code qui suit.
;Si on a besoin de connaître l'étendue de la zone touchée , il faut utiliser la procédure ZoneBoxCollision()
Collision=#False
xa2=xa1+SpriteWidth(NoA)
ya2=ya1+SpriteHeight(NoA)
xb2=xb1+SpriteWidth(NoB)
yb2=yb1+SpriteHeight(NoB)
;En 3D il faut ajouter And za2>zb1 And za1<zb2
If xa2>xb1 And xa1<xb2 And ya2>yb1 And ya1<yb2
Collision=#True
EndIf
ProcedureReturn Collision
EndProcedure
Procedure ZoneBoxCollision(*Zone.Zone,NoA,xa1,ya1,NoB,xb1,yb1)
;C'est la même chose que la procédure BoxCollision ,
;sauf qu'en plus on récupère dans "Zone" les valeurs de la zone en collision
Collision=#False
xa2=xa1+SpriteWidth(NoA)
ya2=ya1+SpriteHeight(NoA)
xb2=xb1+SpriteWidth(NoB)
yb2=yb1+SpriteHeight(NoB)
;En 3D il faut ajouter And za2>zb1 And za1<zb2
If xa2>xb1 And xa1<xb2 And ya2>yb1 And ya1<yb2
Collision=#True
;/Zone en collision
MinX=xa1 : MaxX=xa2
If xa1<xb1: MinX=xb1 : EndIf
If xa2>xb2 : MaxX=xb2 : EndIf
MinY=ya1 : MaxY=ya2
If ya1<yb1 : MinY=yb1 : EndIf
If ya2>yb2 : MaxY=yb2 : EndIf
*Zone\x=MinX : *Zone\y=MinY
*Zone\Largeur=MaxX-MinX
*Zone\Hauteur=MaxY-MinY
EndIf
ProcedureReturn Collision
EndProcedure
Procedure AfficheInfos()
If StartDrawing(ScreenOutput())
FrontColor(255,255,0)
BackColor(0,0,0)
;Si on a pas besoin de connaitre l"étendue de la zone en collision , BoxCollision(xa1,ya1,2,xb1,yb1) suffit
If ZoneBoxCollision(@i.Zone,1,Sprite1\x,Sprite1\y,2,Sprite2\x,Sprite2\y)
T$="Collision"
;/Affiche la zone en collision
Box(i\x,i\y,i\Largeur,i\Hauteur,RGB(255,0,0))
Else
T$="Pas de collision"
EndIf
Locate(0,0)
DrawText(T$)
StopDrawing()
EndIf
EndProcedure
;- Boucle principale
Repeat
ClearScreen(0,0,0)
ExamineKeyboard()
ExamineMouse()
;/Affiche le sprite 1
DisplaySprite(1,Sprite1\x,Sprite1\y)
;/Affiche le sprite 2 à la position de la souris
Sprite2\x=MouseX()
Sprite2\y=MouseY()
DisplayTransparentSprite(2,Sprite2\x,Sprite2\y)
;/Test la collision
AfficheInfos()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)

