Page 1 sur 1

................

Publié : jeu. 09/juin/2005 22:57
par Backup
.............

Publié : ven. 10/juin/2005 18:06
par Backup
...............

Publié : ven. 10/juin/2005 19:44
par Dr. Dri
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...

Code : Tout sélectionner

Enumeration
  #SuperCollision_Haut   = %0001
  #SuperCollision_Droite = %0010
  #SuperCollision_Bas    = %0100
  #SuperCollision_Gauche = %1000
EndEnumeration
Dri

Publié : ven. 10/juin/2005 21:55
par Backup
au lieu d'utiliser une chaîne de caractères...
en quoi c'est plus clair les constantes ? :D

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 !
:lol:

sympa pour des briques ^^
pas seulement ! pour toute utilisation de sprite !

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 !
:D

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 ! :D

Publié : ven. 10/juin/2005 22:13
par Dr. Dri
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 ?)

Code : Tout sélectionner

collision = super_collision(...)

if collision = (#SuperCollision_Haut|#SuperCollision_Droite)
  debug "collision en haut à droite"
endif
Dri ;)

Publié : ven. 10/juin/2005 22:25
par Le Soldat Inconnu
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 :wink:
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
entre ecrire "haut" ou #haut, ça ne fait aucune difference de souplesse
sauf que les string sont plus lent à utiliser

Publié : ven. 10/juin/2005 22:37
par Oliv
ça peut être utile :)

Publié : sam. 11/juin/2005 13:31
par Dr. Dri
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 !

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
En bleu, la localisation de la collision... ca me donne presque envie de me lancer dans un jeu de combat 2D ^^

Dri

Publié : sam. 11/juin/2005 16:32
par Backup
je supose que c'est un principe ; car chez moi ça rame grave ton exemple ! :?

mais bon effectivement ya de l'idée ! :D



@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 :D


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 ...










:D

Publié : dim. 12/juin/2005 14:29
par Dr. Dri
Oué ca rame à mort à cause des point() à répétition... Sinon l'idée du point moyen est relativement fiable ^^

j'ai plus qu'à m'amuser avec les drawingbuffer() et companie pour avoir une fonction moins gourmande

Dri ;)

Publié : ven. 26/août/2005 12:52
par morukutsu
Sa marche avec la fonction SpritePixelCollision() ?

Publié : ven. 26/août/2005 12:57
par Dr. Dri
Disons que le but de ce topic était de localiser (x, y) la collision s'il y en a une... Ce que SpritePixelCollision ne dit pas...

Dri ;)

Publié : ven. 26/août/2005 17:41
par morukutsu
Ok merci !

Publié : lun. 19/sept./2005 16:05
par netmaestro
Si le forum anglais ne s'était pas cassé, je n'aurais jamais vu cet excellent bout. Grand travail !

Publié : ven. 04/nov./2005 10:21
par Dr. Dri
j'ai réussi à optimiser le code :D
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
Dri