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

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

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

Message par Backup »

.............
Dernière modification par Backup le ven. 07/oct./2011 12:32, modifié 4 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

...............
Dernière modification par Backup le ven. 07/oct./2011 12:32, modifié 1 fois.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message 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
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 ;)
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message 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
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)]
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

ça peut être utile :)
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message 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
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 ;)
morukutsu
Messages : 65
Inscription : sam. 29/janv./2005 15:01
Contact :

Message par morukutsu »

Sa marche avec la fonction SpritePixelCollision() ?
The life is a game...
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 ;)
morukutsu
Messages : 65
Inscription : sam. 29/janv./2005 15:01
Contact :

Message par morukutsu »

Ok merci !
The life is a game...
netmaestro
Messages : 6
Inscription : lun. 19/sept./2005 15:46

Message par netmaestro »

Si le forum anglais ne s'était pas cassé, je n'aurais jamais vu cet excellent bout. Grand travail !
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Répondre