................
................
.............
Dernière modification par Backup le ven. 07/oct./2011 12:32, modifié 4 fois.
sympa pour des briques ^^
sinon tu devrais faire un jeu de constantes pour désigner le "lieu" de la collision... au lieu d'utiliser une chaîne de caractères...
Dri
sinon tu devrais faire un jeu de constantes pour désigner le "lieu" de la collision... au lieu d'utiliser une chaîne de caractères...
Code : Tout sélectionner
Enumeration
#SuperCollision_Haut = %0001
#SuperCollision_Droite = %0010
#SuperCollision_Bas = %0100
#SuperCollision_Gauche = %1000
EndEnumeration
en quoi c'est plus clair les constantes ?au lieu d'utiliser une chaîne de caractères...

le problem des constantes dans les jeux c'est que c'est figé !!
y a plein de truc que les constante empeche !
perso je les utilise tres peu , je prefere les variables
qui offre la possibilité d'etre modifié ! , dans le creation de jeux c'est primordiale !
les constantes c'est bien dans certain cas , mais rigide !
pour une info rendu par une fonction , le fait d'avoir une chaine de charactere permet une plus grande clarté !
bref ! je suis pas fan des constantes !

pas seulement ! pour toute utilisation de sprite !sympa pour des briques ^^
par exemple : un perso recoit un missile , si tu peut situer le point d'impact du missile sur le perso
tu peut facilement deduire d'ou il vient (le missile) et elaborer un system de mise a l'abris du sprite touché , ou une contre attaque !

tu peut rendre autonome la replique a une attaque , comme u tank par exemple , il sait qu'il viens d'etre touché par l'ariere a gauche ,
du coup il va effectuer un demi tour pour riposter !

personellement, pour un jeu du genre "combat" je pense que ca ne convient pas... la localisation de la collision est sommaire... Une fonction qui renverai une liste des pixels en collisions (dans le sprite 1 ou l'autre) permetrait plus de précision par exemple... Ou alors une fonction qui renverrai le point "moyen" (en gros le plus au milieu).
sinon pour les constantes je ne vois pas le problème... à utiliser avec des variables (c'est le but nan ?)
Dri 
sinon pour les constantes je ne vois pas le problème... à utiliser avec des variables (c'est le but nan ?)
Code : Tout sélectionner
collision = super_collision(...)
if collision = (#SuperCollision_Haut|#SuperCollision_Droite)
debug "collision en haut à droite"
endif

-
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
euh, tu connais dans quel sens se déplace la balle, non ?
tu connais la position des objets également, non ?
donc tu sais ou la balle à taper.
exemple :
ta balle va vers le haut à gauche
elle peut donc taper une brique :
- sur le bas
- sur la droite
avec les positions du centre de la balle et des coté de la brique, tu sais ou elle a tapé
cela permet de garder la fonction de pb qui est surement plus rapide
voir d'utiliser la fonction spritepixelcollision qui garantit que la balle est bien en contact avec la brique (car avaec ta méthode, on considere la balle carre)
un autre point au sujet de tes variables texte, c'est nettement plus lent qu'une valeur
il aurrait été plus simple de faire comme Dri te la dis, d'utiliser une constante long ayant pour nom le texte que tu utilises
entre ecrire "haut" ou #haut, ça ne fait aucune difference de souplesse
sauf que les string sont plus lent à utiliser
tu connais la position des objets également, non ?
donc tu sais ou la balle à taper.
exemple :
ta balle va vers le haut à gauche
elle peut donc taper une brique :
- sur le bas
- sur la droite
avec les positions du centre de la balle et des coté de la brique, tu sais ou elle a tapé
cela permet de garder la fonction de pb qui est surement plus rapide

voir d'utiliser la fonction spritepixelcollision qui garantit que la balle est bien en contact avec la brique (car avaec ta méthode, on considere la balle carre)
un autre point au sujet de tes variables texte, c'est nettement plus lent qu'une valeur
il aurrait été plus simple de faire comme Dri te la dis, d'utiliser une constante long ayant pour nom le texte que tu utilises
Code : Tout sélectionner
If y_sprite2<y_sprite1 And x_sprite2>=x_sprite1 And x_sprite2+largeur_spr2<=x_sprite1+largeur_spr1
bord.l=#haut
EndIf
sauf que les string sont plus lent à utiliser
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Voila à quoi je pensais Dobro (ca m'a coûté 4h de sommeil en moins ^^)
Le pricipe est là, mais pas l'optimisation... de plus je ne gère pas la couleur transparente, c'est d'office le noir !
En bleu, la localisation de la collision... ca me donne presque envie de me lancer dans un jeu de combat 2D ^^
Dri
Le pricipe est là, mais pas l'optimisation... de plus je ne gère pas la couleur transparente, c'est d'office le noir !
Code : Tout sélectionner
Procedure.l MakeLong(Low.w, High.w)
ProcedureReturn (Low & $FFFF) | ((High << 16) & $FFFF0000)
EndProcedure
Procedure.w LowWord(Long.l)
ProcedureReturn Long & $FFFF
EndProcedure
Procedure.w HighWord(Long.l)
ProcedureReturn (Long >> 16) & $FFFF
EndProcedure
Procedure SpriteCollisionLocation(Sprite1.l, x1.l, y1.l, Sprite2.l, x2.l, y2.l)
Protected w1.l, h1.l, w2.l, h2.l
Protected xl.l, xr.l, yu.l, yd.l
Protected ax.l, ay.l, collision.l
Protected i.l, j.l, cx.l, cy.l, nb.l
Protected x.l, y.l, u.l, v.l, yy.l, vv.l
w1 = SpriteWidth (Sprite1)
h1 = SpriteHeight(Sprite1)
w2 = SpriteWidth (Sprite2)
h2 = SpriteHeight(Sprite2)
collision = #True
If x1 < x2
If (x1 + w1) > x2
xl = x2
u = 0
x = xl - x1
Else
collision = #False
EndIf
Else
If (x2 + w2) > x1
xl = x1
x = 0
u = xl - x2
Else
collision = #False
EndIf
EndIf
If y1 < y2
If (y1 + h1) > y2
yu = y2
v = 0
y = yu - y1
Else
collision = #False
EndIf
Else
If (y2 + h2) > y1
yu = y1
y = 0
v = yu - y2
Else
collision = #False
EndIf
EndIf
If collision = #True
If (x1 + w1) < (x2 + w2)
xr = x1 + w1
Else
xr = x2 + w2
EndIf
If (y1 + h1) < (y2 + h2)
yd = y1 + h1
Else
yd = y2 + h2
EndIf
EndIf
If collision = #True
Dim pt1.l(w1, h1)
If StartDrawing( SpriteOutput(Sprite1) )
For i = 0 To w1 - 1
For j = 0 To h1 - 1
pt1(i, j) = Point(i, j)
Next j
Next i
StopDrawing()
Else
collision = #False
EndIf
EndIf
If collision = #True
Dim pt2.l(w2, h2)
If StartDrawing( SpriteOutput(Sprite2) )
For i = 0 To w2 - 1
For j = 0 To h2 - 1
pt2(i, j) = Point(i, j)
Next j
Next i
StopDrawing()
Else
collision = #False
EndIf
EndIf
If collision = #True
nb = 0
yy = y
vv = v
For i = xl To xr
y = yy
v = vv
For j = yu To yd
If pt1(x, y) And pt2(u, v)
cx + i
cy + j
nb + 1
EndIf
y + 1
v + 1
Next j
x + 1
u + 1
Next i
If nb > 0
cx / nb
cy / nb
collision = MakeLong(cx, cy)
Else
collision = #False
EndIf
EndIf
ProcedureReturn collision
EndProcedure
InitSprite()
InitMouse()
InitKeyboard()
x = 500
y = 500
If OpenScreen(1024, 768, 16, "")
TransparentSpriteColor(#PB_Default, 0, 0, 0)
CreateSprite(0, 320, 240)
CreateSprite(1, 60, 60)
CreateSprite(2, 3, 3)
If StartDrawing( SpriteOutput(0) )
Ellipse(160, 120, 160, 120, $0000FF)
Ellipse(160, 120, 80, 60, $000000)
StopDrawing()
EndIf
If StartDrawing( SpriteOutput(1) )
Circle(0, 0, 60, $00FF00)
StopDrawing()
EndIf
If StartDrawing( SpriteOutput(2) )
Box(0, 0, 3, 3, $FF0000)
StopDrawing()
EndIf
Repeat
ExamineMouse()
ExamineKeyboard()
ClearScreen(0, 0, 0)
x + MouseDeltaX()
y + MouseDeltaY()
DisplayTransparentSprite(0, 80, 80)
DisplayTransparentSprite(1, x, y)
collision = SpriteCollisionLocation(0, 80, 80, 1, x, y)
If collision
cx = LowWord (collision)
cy = HighWord(collision)
DisplaySprite(2, cx-1, cy-1)
EndIf
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
EndIf
Dri
je supose que c'est un principe ; car chez moi ça rame grave ton exemple !
mais bon effectivement ya de l'idée !
@Soldat : ok bien sur, tu peut te passer de ma fonction ; d'ailleurs j'oblige personne ...
simplement une procedure qui te renvoie ou a lieu le contact c'est mieux
que rien du tout !!
et pas "Carre" car je tien compte de 8 cotés !! chez moi c'est un octogone ! en matiere de sprite (petitesse) c'est pas carre , on peut meme appeler ça rond !! (sur 64x64 pixel ) en moyenne
pour la critique sur vitesse , ya pas vraimen de lenteur , puisque j'utilise sprite_collision du pure , simplement je mache le travail pour connaitre avec une relative precision le point d'impact !! , je pense pas que ma serie de if-endif ralentisse de beaucoup , car de toute facon , si tu n'utilise pas ma fonction, tu vas faire des tests dans ton listing pour savoir le sens de la balle ect .. ce qui en matiere de temps devrai rebvenir au meme ..
la ç'est centralisé dans ma fonction !!
Mais bon je suis quand mem content de ma fonction , je la partage
si vous la trouvez bien ; coool sinon , ben temps-pis , ne l'utilisez pas ...


mais bon effectivement ya de l'idée !

@Soldat : ok bien sur, tu peut te passer de ma fonction ; d'ailleurs j'oblige personne ...
simplement une procedure qui te renvoie ou a lieu le contact c'est mieux
que rien du tout !!
et pas "Carre" car je tien compte de 8 cotés !! chez moi c'est un octogone ! en matiere de sprite (petitesse) c'est pas carre , on peut meme appeler ça rond !! (sur 64x64 pixel ) en moyenne

pour la critique sur vitesse , ya pas vraimen de lenteur , puisque j'utilise sprite_collision du pure , simplement je mache le travail pour connaitre avec une relative precision le point d'impact !! , je pense pas que ma serie de if-endif ralentisse de beaucoup , car de toute facon , si tu n'utilise pas ma fonction, tu vas faire des tests dans ton listing pour savoir le sens de la balle ect .. ce qui en matiere de temps devrai rebvenir au meme ..
la ç'est centralisé dans ma fonction !!
Mais bon je suis quand mem content de ma fonction , je la partage
si vous la trouvez bien ; coool sinon , ben temps-pis , ne l'utilisez pas ...

-
- Messages : 6
- Inscription : lun. 19/sept./2005 15:46
j'ai réussi à optimiser le code 
y reste plus comme optimisation qu'à passer par des drawingbuffers directement ^^
Dri

y reste plus comme optimisation qu'à passer par des drawingbuffers directement ^^
Code : Tout sélectionner
Procedure SpriteCollisionLocation(Sprite1.l, x1.l, y1.l, Sprite2.l, x2.l, y2.l, *location.POINTS)
Protected w1.l, h1.l, w2.l, h2.l
Protected xl.l, xr.l, yt.l, yb.l
Protected x.l, y.l, u.l, v.l, yy.l, vv.l
Protected i.l, j.l, cx.l, cy.l, nb.l, collision.l
w1 = SpriteWidth (Sprite1)
h1 = SpriteHeight(Sprite1)
w2 = SpriteWidth (Sprite2)
h2 = SpriteHeight(Sprite2)
collision = #True
If x1 < x2
If (x1 + w1) > x2
xl = x2
u = 0
x = xl - x1
Else
collision = #False
EndIf
Else
If (x2 + w2) > x1
xl = x1
x = 0
u = xl - x2
Else
collision = #False
EndIf
EndIf
If y1 < y2
If (y1 + h1) > y2
yt = y2
v = 0
y = yt - y1
Else
collision = #False
EndIf
Else
If (y2 + h2) > y1
yt = y1
y = 0
v = yt - y2
Else
collision = #False
EndIf
EndIf
If collision = #True
If (x1 + w1) < (x2 + w2)
xr = x1 + w1
Else
xr = x2 + w2
EndIf
If (y1 + h1) < (y2 + h2)
yb = y1 + h1
Else
yb = y2 + h2
EndIf
xr - 1
yb - 1
w1 - 1
h1 - 1
w2 - 1
h2 - 1
EndIf
If collision = #True
Dim pt1.l(w1, h1)
If StartDrawing( SpriteOutput(Sprite1) )
For i = xl To xr
For j = yt To yb
pt1(i-xl+x, j-yt+y) = Point(i-xl+x, j-yt+y)
Next j
Next i
StopDrawing()
Else
collision = #False
EndIf
EndIf
If collision = #True
Dim pt2.l(w2, h2)
If StartDrawing( SpriteOutput(Sprite2) )
For i = xl To xr
For j = yt To yb
pt2(i-xl+u, j-yt+v) = Point(i-xl+u, j-yt+v)
Next j
Next i
StopDrawing()
Else
collision = #False
EndIf
EndIf
If collision = #True
yy = y
vv = v
For i = xl To xr
y = yy
v = vv
For j = yt To yb
If pt1(x, y) And pt2(u, v)
cx + i
cy + j
nb + 1
EndIf
y + 1
v + 1
Next j
x + 1
u + 1
Next i
If nb > 0 And *location
*location\x = cx / nb
*location\y = cy / nb
EndIf
EndIf
ProcedureReturn nb
EndProcedure
InitSprite()
InitMouse()
InitKeyboard()
x = 500
y = 500
If OpenScreen(1024, 768, 16, "")
TransparentSpriteColor(#PB_Default, 0, 0, 0)
CreateSprite(0, 320, 240)
CreateSprite(1, 60, 60)
CreateSprite(2, 3, 3)
If StartDrawing( SpriteOutput(0) )
Ellipse(160, 120, 160, 120, $0000FF)
Ellipse(160, 120, 80, 60, $000000)
StopDrawing()
EndIf
If StartDrawing( SpriteOutput(1) )
Circle( 0, 30, 30, $00FF00)
Circle(60, 30, 30, $00FF00)
Circle(30, 30, 20, $000000)
StopDrawing()
EndIf
If StartDrawing( SpriteOutput(2) )
Box(0, 0, 3, 3, $FF0000)
StopDrawing()
EndIf
Repeat
ExamineMouse()
ExamineKeyboard()
ClearScreen(0, 0, 0)
x + MouseDeltaX()
y + MouseDeltaY()
DisplayTransparentSprite(0, 80, 80)
DisplayTransparentSprite(1, x, y)
If SpriteCollisionLocation(0, 80, 80, 1, x, y, @Location.POINTS)
DisplaySprite(2, Location\x-1, Location\y-1)
EndIf
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
EndIf