
Petit problême qui me prends la tête...
Petit problême qui me prends la tête...
Est-ce que quelqu'un saurait comment determiner quel côté d'un sprite est touché lors d'une collision avec un autre? ( droite ou gauche, haut ou bas )... je galère là... 

ben oui c'est ça la solution !!!
tu compare le x du bateau avec le x du continent
si le x du bateau est plus grand que le x du continent au moment de l'impact
ça veux obligatoirement dire que le bateau se situe a droite de la rive !!
donc que le bateau est touché du coté gauche !!
pareil avec les autres coordonées !!
tu compare le x du bateau avec le x du continent
si le x du bateau est plus grand que le x du continent au moment de l'impact
ça veux obligatoirement dire que le bateau se situe a droite de la rive !!
donc que le bateau est touché du coté gauche !!
pareil avec les autres coordonées !!

Voilà à peu près tout ce que je sais faire dans ce domaine.
C'est pas très au point, mais ça doit pouvoir s'améliorer
Chris 
C'est pas très au point, mais ça doit pouvoir s'améliorer

Code : Tout sélectionner
#Window = 0
#Width = 300
#Height = 300
Enumeration
#balle1
#balle2
EndEnumeration
Global SprFix_X,SprFix_Y,SprMob_X,SprMob_Y
Procedure Affichage()
PosMobX$ = LSet(Str(SprMob_X),3,"_")+" x "
PosMobY$ = LSet(Str(SprMob_Y),3,"_")
PosFixX$ = LSet(Str(SprFix_X),3," ")+" x "
PosFixY$ = LSet(Str(SprFix_Y),3," ")
StartDrawing(ScreenOutput())
DrawingMode(1) : FrontColor($C0,$C0,$C0)
Locate(10,10)
DrawText("Mobile = "+PosMobX$+PosMobY$+" ["+LSet(Str(SprMob_X+24),3,"_")+" - "+Str(SprMob_Y+24)+"]")
Locate(10,30)
DrawText("Fixe = "+PosFixX$+PosFixY$+" ["+Str(SprFix_X+24)+" - "+Str(SprFix_Y+24)+"]")
StopDrawing()
EndProcedure
Procedure Sprites()
If CreateSprite(#balle1,24,24,0) ; Sprite Fixe
StartDrawing(SpriteOutput(#balle1))
Box(0,0,24,24,RGB($FF,$0,$0))
StopDrawing()
EndIf
If CreateSprite(#balle2,24,24,0) ; Sprite Mobile
StartDrawing(SpriteOutput(#balle2))
Box(0,0,24,24,RGB($0,$0,$FF))
StopDrawing()
EndIf
EndProcedure
Procedure Between(Value.l,Mini.l,Maxi.l)
If Value >= Mini And Value <= Maxi
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;- Initialisation de DirectX
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
End
EndIf
hwnd = OpenWindow(#Window, 0, 0, #Width, #Height, #PB_Window_TitleBar | #PB_Window_ScreenCentered, "")
OpenWindowedScreen(hwnd, 0, 0, #Width, #Height, 0, 0, 0)
Sprites()
Repeat
ClearScreen(0, 0, 0) : ExamineKeyboard() :ExamineMouse()
SprFix_X = 138 : SprFix_Y = 138
SprMob_X = MouseX() : SprMob_Y = MouseY()
DisplayTransparentSprite(#balle1,SprFix_X,SprFix_Y)
DisplayTransparentSprite(#balle2,SprMob_X, SprMob_Y)
Affichage()
FlipBuffers()
If SpriteCollision(#balle1,SprFix_X,SprFix_Y,#balle2,SprMob_X,SprMob_Y)
If SprMob_X < SprFix_X-2 And Between(SprMob_Y,SprFix_Y-20,SprFix_Y+20)
SetWindowTitle(#Window,"Collision à gauche")
EndIf
If SprMob_X > SprFix_X And Between(SprMob_Y,SprFix_Y-20,SprFix_Y+20)
SetWindowTitle(#Window,"Collision à droite")
EndIf
If SprMob_Y < SprFix_Y And Between(SprMob_X,SprFix_X-20,SprFix_X+20)
SetWindowTitle(#Window,"Collision en haut")
EndIf
If SprMob_Y > SprFix_Y And Between(SprMob_X,SprFix_X-20,SprFix_X+20)
SetWindowTitle(#Window,"Collision en bas")
EndIf
Else
SetWindowTitle(#Window,"")
EndIf
Delay(2)
If KeyboardPushed(#PB_Key_Escape) : quit = 1 : EndIf
While WindowEvent() : Wend
Until quit = 1

Imagine un perso qui court , et devant il y a un mur .
Ton mur n'est pas épais ( inférieur à la vitesse de déplacement du perso )
Premier tour de programme , tu testes la collision entre le perso et le mur , pas de contact ,le perso est devant .
le perso se déplace et se retrouve derrière le mur car son déplacement est supérieur à l'épaisseur du mur
au tour de programme suivant ,tu testes à nouveau la collision, et toujours pas de collision , le perso est derrière .
ça signifie , qu'il faut tenir compte du temps , pour contrôler la trajectoire du perso , ou alors mémoriser la position précédente ,et si le perso traverse un obstacle , il faut le replacer au contact et inverser son sens de déplacement .
En clair ,tu ne peux pas te contenter de la fonction Collision() de Pure , c'est à toi de faire le test .
Ton mur n'est pas épais ( inférieur à la vitesse de déplacement du perso )
Premier tour de programme , tu testes la collision entre le perso et le mur , pas de contact ,le perso est devant .
le perso se déplace et se retrouve derrière le mur car son déplacement est supérieur à l'épaisseur du mur
au tour de programme suivant ,tu testes à nouveau la collision, et toujours pas de collision , le perso est derrière .
ça signifie , qu'il faut tenir compte du temps , pour contrôler la trajectoire du perso , ou alors mémoriser la position précédente ,et si le perso traverse un obstacle , il faut le replacer au contact et inverser son sens de déplacement .
En clair ,tu ne peux pas te contenter de la fonction Collision() de Pure , c'est à toi de faire le test .
J'y comprends toujours rien...
j'ai essayé d'utiliser ta routine between chris.. marche toujours pas comme je veux... cette fois, la balle ne semble plus traverser mais son mouvement est obligatoirement toujours inversé à chaque collision... Grrrr
Code : Tout sélectionner
DisplaySprite(brique()\style+1, brique()\x, brique()\y)
If SpriteCollision(0,x,y,brique()\type+1,brique()\x, brique()\y)
If between(x,brique()\x,brique()\x+32) And Between(y,brique()\y,brique()\y+32)
a=-a
EndIf
b=-b
If brique()\type=1
DeleteElement(brique())
EndIf
If brique()\type=2
EndIf
EndIf
Wend
Ben tu sais, je suis pas un spécialiste
La petite routine se contente de regarder si la position du sprite 1 se situe entre le début et la fin du sprite 2.
(En fait, c'est une procédure que je fais pour vérifier qu'une valeur est comprise entre deux autres valeurs).
Ensuite, c'est à toi de gérer le rebond et la direction de ta balle.
Chris

La petite routine se contente de regarder si la position du sprite 1 se situe entre le début et la fin du sprite 2.
(En fait, c'est une procédure que je fais pour vérifier qu'une valeur est comprise entre deux autres valeurs).
Ensuite, c'est à toi de gérer le rebond et la direction de ta balle.
Chris


n'oublie surtout pas que le calcul de collision est fait a partir
du coin superieur gauche des sprites !!!
donc pour le rebond droite c'est
si xball est en collision avec xbrique+largeur de brique alors rebond !!
pareil pour la collision de la balle avec le dessous de la brique(+hauteur de brique)
bref une petite fonction offset_sprite serai bienvenue pour decaler le point chaud !!

Et ne pas oublier, non plus, que si la balle est au dessus ou au dessous de la brique, il faut inverser Y et pas X, et que si la balle est à gauche ou à droite de la brique, il faut inverser X et pas Y. (Au moment de la collision, évidemment).
Mais bon... Je parle un peu dans le vide, là, parce que j'imagine que ça, tu le sais déjà!
(Et puis, faut bien que je poste un peu, de temps en temps
)
Chris

Mais bon... Je parle un peu dans le vide, là, parce que j'imagine que ça, tu le sais déjà!
(Et puis, faut bien que je poste un peu, de temps en temps

Chris

Petite modif du bout de code précédent.
J'ai viré le SpriteCollision(), le gros sprite rouge se déplace avec les touches fléchées, la balle se déplace toute seule, comme une grande.
Chris 
J'ai viré le SpriteCollision(), le gros sprite rouge se déplace avec les touches fléchées, la balle se déplace toute seule, comme une grande.
Code : Tout sélectionner
#Window = 0
#Width = 300
#Height = 300
Enumeration
#Spr_Fix
#Spr_Mob
EndEnumeration
Global SprFix_X,SprFix_Y,SprMob_X,SprMob_Y
dep = 1
Procedure Affichage()
; Cette procedure affiche les coordonnées des sprites
PosMobX$ = LSet(Str(SprMob_X),3,"_")+" x "
PosMobY$ = LSet(Str(SprMob_Y),3,"_")
PosFixX$ = LSet(Str(SprFix_X),3," ")+" x "
PosFixY$ = LSet(Str(SprFix_Y),3," ")
StartDrawing(ScreenOutput())
DrawingMode(1) : FrontColor($C0,$C0,$C0)
Locate(10,10)
DrawText("Mobile = "+PosMobX$+PosMobY$+" ["+LSet(Str(SprMob_X+24),3,"_")+" - "+Str(SprMob_Y+24)+"]")
Locate(10,30)
DrawText("Fixe = "+PosFixX$+PosFixY$+" ["+Str(SprFix_X+12)+" - "+Str(SprFix_Y+12)+"]")
StopDrawing()
EndProcedure
Procedure Sprites()
; Procedure de création des sprites
If CreateSprite(#Spr_Fix,128,24,0) ; Sprite Fixe
StartDrawing(SpriteOutput(#Spr_Fix))
Box(0,0,128,24,RGB($FF,$0,$0))
StopDrawing()
EndIf
If CreateSprite(#Spr_Mob,24,24,0) ; Sprite Mobile
StartDrawing(SpriteOutput(#Spr_Mob))
Box(0,0,24,24,RGB($0,$0,$FF))
StopDrawing()
EndIf
EndProcedure
Procedure Between(Value.l,Mini.l,Maxi.l)
; Cette procédure vérifie que la valeur "Value" se situe entre
; "Mini" et "Maxi"
If Value >= Mini And Value <= Maxi
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;- Initialisation de DirectX
If InitSprite() = 0 Or InitKeyboard() = 0
End
EndIf
;- Ouverture de la fenêtre et de l'écran
hwnd = OpenWindow(#Window, 0, 0, #Width, #Height, #PB_Window_TitleBar | #PB_Window_ScreenCentered, "")
OpenWindowedScreen(hwnd, 0, 0, #Width, #Height, 0, 0, 0)
Sprites()
;- Initialisation des sprites
SprFix_X = 86 : SprFix_Y = 138
SprMob_X = 0 : SprMob_Y = 0
SensX = 1 : SensY = 1
;- Boucle des évènements
Repeat
ClearScreen(0, 0, 0) : ExamineKeyboard()
; Affichage des sprites
DisplayTransparentSprite(#Spr_Fix, SprFix_X, SprFix_Y)
DisplayTransparentSprite(#Spr_Mob, SprMob_X, SprMob_Y)
; Dessin des lignes du sprite mobile
StartDrawing(ScreenOutput())
Line(SprMob_X,0,0,300,RGB($C0,$C0,$C0))
Line(SprMob_X+24,0,0,300,RGB($C0,$C0,$C0))
Line(0,SprMob_Y,300,0,RGB($C0,$C0,$C0))
Line(0,SprMob_Y+24,300,0,RGB($C0,$C0,$C0))
StopDrawing()
Affichage()
FlipBuffers()
SprMob_X + SensX : SprMob_Y + SensY
; Collision à gauche
If SprMob_X + SpriteWidth(#Spr_Mob) = SprFix_X
If Between(SprMob_Y,SprFix_Y - SpriteWidth(#Spr_Mob), SprFix_Y + SpriteWidth(#Spr_Mob))
SetWindowTitle(#Window,"Collision à gauche")
SensX = -SensX
EndIf
; Collision à droite
ElseIf SprMob_X = SprFix_X + 128
If Between(SprMob_Y,SprFix_Y - SpriteWidth(#Spr_Mob),SprFix_Y + SpriteWidth(#Spr_Mob))
SetWindowTitle(#Window,"Collision à droite")
SensX = -SensX
EndIf
; Collision en haut
ElseIf SprMob_Y + SpriteHeight(#Spr_Mob) = SprFix_Y
If Between(SprMob_X,SprFix_X - SpriteWidth(#Spr_Mob) ,SprFix_X + SpriteWidth(#Spr_Fix))
SetWindowTitle(#Window,"Collision en haut")
SensY = -SensY
EndIf
; Collision en bas
ElseIf SprMob_Y = SprFix_Y + SpriteHeight(#Spr_Mob)
If Between(SprMob_X,SprFix_X - SpriteWidth(#Spr_Mob),SprFix_X +SpriteWidth(#Spr_Fix))
SetWindowTitle(#Window,"Collision en bas")
SensY = -SensY
EndIf
EndIf
Delay(2)
If KeyboardPushed(#PB_Key_Escape) : quit = 1 : EndIf
If KeyboardPushed(#PB_Key_Left) : SprFix_X - dep : EndIf
If KeyboardPushed(#PB_Key_Right) : SprFix_X + dep : EndIf
If KeyboardPushed(#PB_Key_Up) : SprFix_Y - dep : EndIf
If KeyboardPushed(#PB_Key_Down) : SprFix_Y + dep : EndIf
If SprMob_X <=0 : SensX= -SensX : EndIf
If SprMob_Y <=0 : SensY= -SensY : EndIf
If SprMob_X >=276 : SensX= -SensX : EndIf
If SprMob_Y >=276 : SensY= -SensY : EndIf
While WindowEvent() : Wend
Until quit = 1

bah moi aussi j'ai fait un truc pour toi mais j'ai garde sprite collision tiens :

Code : Tout sélectionner
#dobro=1
#Police=1
#brique=1
#ball=2
; ***********************************
Resultat = InitSprite()
FontID = LoadFont(#Police, "arial", 18, #PB_Font_Bold )
EcranX = GetSystemMetrics_(#SM_CXSCREEN):;=largeur de l'ecran
EcranY = GetSystemMetrics_(#SM_CYSCREEN):;=hauteur de l'ecran
WindowID = OpenWindow(1, 0, 0, EcranX, EcranY, #PB_Window_SystemMenu|#PB_Window_BorderLess |#PB_Window_ScreenCentered , "hello")
WindowID = WindowID(1)
Result = OpenWindowedScreen(WindowID,0,0, EcranX, EcranY, 1, 0,0)
; creation d'un Sprite
CreateSprite(#brique, 350, 150) ; cree un sprite brique
StartDrawing(SpriteOutput(#brique) ) ; on dessine dedans
Box(0, 0, 350, 150,RGB(255,0,255) ) ; un carre violet
StopDrawing()
CreateSprite(#ball, 32, 32) ; cree un sprite ball
StartDrawing(SpriteOutput(#ball) ) ; on dessine dedans
Circle(16,16, 16 ,RGB(255,255,255) )
StopDrawing()
Resultat = InitMouse()
xpas=20
ypas=10
xb=100
yb=450
xbrique=EcranX/2-150
ybrique=EcranY/2-50
Repeat
ExamineMouse()
event=WindowEvent()
Delay(1)
If MouseButton(2)
End
EndIf
xb=xb+xpas
yb=yb+ypas
DisplaySprite(#ball, xb,yb); affiche la balle
DisplaySprite(#brique, xbrique,ybrique); affiche la brique
If xb>EcranX-20 :xpas=-xpas:EndIf
If xb<20 :xpas=-xpas:EndIf
If yb>EcranY-20 :ypas=-ypas:EndIf
If yb<20 :ypas=-ypas:EndIf
If SpriteCollision(#ball, xb, yb, #brique, xbrique, ybrique)<>0 And xb<xbrique
StartDrawing(SpriteOutput(#brique) ) ; on dessine dedans
DrawText("touche a gauche ")
StopDrawing()
xpas=Random(5)+2
xpas=-xpas
Goto su ; sort du test !!!
EndIf
If SpriteCollision(#ball, xb, yb, #brique, xbrique, ybrique)<>0 And xb>xbrique+330
StartDrawing(SpriteOutput(#brique) ) ; on dessine dedans
DrawText("touche a droite ")
StopDrawing()
xpas=Random(5)+2
Goto su ; sort du test !!!
EndIf
If SpriteCollision(#ball, xb, yb, #brique, xbrique, ybrique)<>0 And yb<ybrique
StartDrawing(SpriteOutput(#brique) ) ; on dessine dedans
DrawText("touche au dessus ")
StopDrawing()
ypas=-ypas
Goto su ; sort du test !!!
EndIf
If SpriteCollision(#ball, xb, yb, #brique, xbrique, ybrique)<>0 And yb>ybrique+130
StartDrawing(SpriteOutput(#brique) ) ; on dessine dedans
DrawText("touche au dessous ")
StopDrawing()
ypas=-ypas
Goto su ; sort du test !!!
EndIf
su:
FlipBuffers():; affiche l'ecran
ClearScreen(0, 0, 0) :;efface l'ecran
Until event=#PB_Event_CloseWindow