Petit problême qui me prends la tête...

Programmation avancée de jeux en PureBasic
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message par Good07 »

Bonjour à tous !
Je rentre de congé et je prends le train en marche. J'ai lu avec attention les messages et j'ai testé les deux programmes. Je constate que la fonction spritecollision réagit assez bizarement quelquefois. J'ai donc fais une compilation des deux listing en espérant que Dobro et Christ ne m'en tiendront pas rigueur et je vous livre mes résultats. Pour la fonction de Chris apparement elle n'est jamais prise en défaut. Pour le listing de Dobro avec une brique énorme et une petite balle cela semble fonctionner normalement mais en la laissant tourné un petit moment on constate certaines anomalies.
Pour la mienne qui est en fait celle de Dobro dans la fenêtre de Chris, laissez la tourner un moment et vous verrez que tout n'est pas rose. Mais le plus bizarre c'est que cela ne se produit pas tout le temps.

Code : Tout sélectionner

#Window = 0 
#Width = 300 
#Height = 300 

Enumeration 
  #brique 
  #balle 
EndEnumeration 

Global xbrique,ybrique,xpas,ypas,xb,yb,flag
dep = 1 


Procedure Sprites() 
  ; Procedure de création des sprites 
  If CreateSprite(#brique,128,24,0)           ; Sprite Fixe 
    StartDrawing(SpriteOutput(#brique)) 
    Box(0,0,128,24,RGB($FF,$0,$0)) 
    StopDrawing() 
  EndIf 
  
  If CreateSprite(#balle,20,20,0)           ; Sprite Mobile 
    StartDrawing(SpriteOutput(#balle)) 
    Circle(10,10,10,RGB($0,$0,$FF)) 
    StopDrawing() 
  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 
xbrique = 86 : ybrique = 138 
xb= 0 : yb= 0 
xpas = 3 : ypas = 3

;- Boucle des évènements 
Repeat 
  ClearScreen(0, 0, 0) : ExamineKeyboard() 
  
  ; Affichage des sprites 
  DisplayTransparentSprite(#brique, xbrique, ybrique) 
  DisplayTransparentSprite(#balle, xb, yb) 
  
  

  FlipBuffers()
   
    xb=xb + xpas
    yb=yb + ypas
  
  
  
  If SpritePixelCollision(#balle, xb, yb, #brique, xbrique, ybrique)<>0 And xb<xbrique And flag=0
     flag=1
     SetWindowTitle(#Window,"Collision à gauche")
     xpas=-xpas 
     Goto su ; sort du test !!! 
  EndIf
  If SpritePixelCollision(#balle, xb, yb, #brique, xbrique, ybrique)<>0 And xb>xbrique+118 And flag=0
      flag=1
      SetWindowTitle(#Window,"Collision à droite") 
      xpas=-xpas
      Goto su ; sort du test !!! 
    EndIf  
  If SpritePixelCollision(#balle, xb, yb, #brique, xbrique, ybrique)<>0 And yb<ybrique And flag=0
      flag=1
      SetWindowTitle(#Window,"Collision au dessus")
      ypas=-ypas 
      Goto su ; sort du test !!!  
  EndIf 
  If SpritePixelCollision(#balle, xb, yb, #brique, xbrique, ybrique)<>0 And yb>ybrique+14 And flag=0
      flag=1
      SetWindowTitle(#Window,"Collision au dessous")
      ypas=-ypas 
      Goto su ; sort du test !!!         
  EndIf 

su:
  If flag=1
    attente+1
  EndIf
  If attente>4
    attente=0
    flag=0
  EndIf 

  
  ;Delay(2) 
  If KeyboardPushed(#PB_Key_Escape) : quit = 1    : EndIf 
  
  If KeyboardPushed(#PB_Key_Left)   : xbrique - dep : EndIf 
  If KeyboardPushed(#PB_Key_Right)  : xbrique + dep : EndIf 
  If KeyboardPushed(#PB_Key_Up)     : ybrique - dep : EndIf 
  If KeyboardPushed(#PB_Key_Down)   : ybrique + dep : EndIf 
  
  If xb <=0   : xpas= -xpas  : EndIf 
  If yb <=0   : ypas= -ypas  : EndIf 
  If xb >=280 : xpas= -xpas  : EndIf 
  If yb >=280 : ypas= -ypas  : EndIf 
  
  While WindowEvent() : Wend 
Until quit = 1 
c'est pas cool ! :(
Mais je m'en était déja apercu quand j'avais posté mon petit casse-brique.

Peut-être qu'en apportant quelques correction ? 8O

A plus
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

:lol:

je m'attendais a ce que quelqu'un reagisse mais pas pour ça !!

:D

plutot pour mon code !!
dont voici l'extrait qui aurai du faire reaction !!

Code : Tout sélectionner

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  <============= la j'inverse les coordonées
        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
                          <=================== PAS ICI ??????
        Goto su ; sort du test !!!
    EndIf 


dans un test j'inverse les coordonnées xpas=-xpas

pas dans l'autre !!! ??? etonnant non ?
(d'autant plus que si on inverse les coordonées , ça met le bazard !!)

et pourtant ça marche !!! voir le listing que j'ai poste plus haut
(pour ceux qu'aurai pas suivi .... )


:D
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message par Good07 »

Bonjour Dobro.

Effectivement je m'étais aperçu du manque d'inversion des coordonnées de X dans la détection de la collision à droite. Mais je pensais que c'était moi qui l'avais effacé en bidouillant les listings. C'est pour cette raison que je l'ai rajoutée au mien.
Donc je l'ai effectivement enlevée mais le problème n'est pas résolu pour autant. La balle dans certaines circontances rentre directement dans la brique et effectue des rebonds à l'intérieur de celle-ci. :?:
Tu as du remarquer que j'ai utiliser pour mon listing la fonction SpritePixelCollision et non pas SpriteCollision. L'aide nous dit qu'elle est plus précise mais plus lente. Moi je n'ai vu aucune différence dans les deux. Le problème est toujours là. J'ai même utilisé ton idée (très bonne :D ) du flag pour stopper la détection collision et permettre à la balle de se déplacer, mais le problème persiste. :(

Je ne vois pas comment le résoudre mais je vais faire tourner le tien pour essayer de trouver une explication à ce phénomène :!:

André qui est de plus en plus perplexe 8O
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

La solution !!!

avec sprite Pixel collision il faut simuler une zone de detection legerement plus grand que la brique !! ici j'ai consideré la valeur 5 c'est a dire
que je force la detection a 5 pixel de tout les bord de la brique !!
faut dire que 5 est la valeur de mes pas de deplacement !

car je pense que la fonction spritepixelcollision est plus lente que spritecollision
du coup le sprite a le temp de continuer a avancer de quelque pixel avant que l'information de detection se fasse !!

j'ai repris ton listing auquel j'ai fait les modifs !!!
maintenant ça marche :)




Code : Tout sélectionner

#Window = 0
#Width = 300
#Height = 300

Enumeration
    #brique
    #balle
EndEnumeration

Global xbrique,ybrique,xpas,ypas,xb,yb,flag
dep = 1


Procedure Sprites()
    ; Procedure de création des sprites
    If CreateSprite(#brique,128,24,0)           ; Sprite Fixe
        StartDrawing(SpriteOutput(#brique))
        Box(0,0,128,24,RGB($FF,$0,$0))
        StopDrawing()
    EndIf
    
    If CreateSprite(#balle,20,20,0)           ; Sprite Mobile
        StartDrawing(SpriteOutput(#balle))
        Circle(10,10,10,RGB($0,$0,$FF))
        StopDrawing()
    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
xbrique = 86 : ybrique = 138
xb= 0 : yb= 0
xpas = 5 : ypas = 5

;- Boucle des évènements
Repeat
    ClearScreen(0, 0, 0) : ExamineKeyboard()
    
    ; Affichage des sprites
    DisplayTransparentSprite(#brique, xbrique, ybrique)
    DisplayTransparentSprite(#balle, xb, yb)
    
    
    
    FlipBuffers()
    
    xb=xb + xpas
    yb=yb + ypas
    
    
    
    If SpritePixelCollision(#balle, xb, yb, #brique, xbrique-5, ybrique)<>0 And flag=0
        flag=1
        SetWindowTitle(#Window,"Collision à gauche")
        xpas=-xpas
        Goto su ; sort du test !!!
    EndIf
    If SpritePixelCollision(#balle, xb, yb, #brique, xbrique+5, ybrique)<>0 And flag=0
        flag=1
        SetWindowTitle(#Window,"Collision à droite")
        xpas=-xpas
        Goto su ; sort du test !!!
    EndIf 
    If SpritePixelCollision(#balle, xb, yb, #brique, xbrique, ybrique-5)<>0  And flag=0
        flag=1
        SetWindowTitle(#Window,"Collision au dessus")
        ypas=-ypas
        Goto su ; sort du test !!! 
    EndIf
    If SpritePixelCollision(#balle, xb, yb, #brique, xbrique, ybrique+5)<>0  And flag=0
        flag=1
        SetWindowTitle(#Window,"Collision au dessous")
        ypas=-ypas
        Goto su ; sort du test !!!         
    EndIf
    
    su:
    If flag=1
        attente+1
    EndIf
    If attente>4
        attente=0
        flag=0
    EndIf
    
    
    ;Delay(2)
    If KeyboardPushed(#PB_Key_Escape) : quit = 1    : EndIf
    
    If KeyboardPushed(#PB_Key_Left)   : xbrique - dep : EndIf
    If KeyboardPushed(#PB_Key_Right)  : xbrique + dep : EndIf
    If KeyboardPushed(#PB_Key_Up)     : ybrique - dep : EndIf
    If KeyboardPushed(#PB_Key_Down)   : ybrique + dep : EndIf
    
    If xb <=0   : xpas= -xpas  : EndIf
    If yb <=0   : ypas= -ypas  : EndIf
    If xb >=280 : xpas= -xpas  : EndIf
    If yb >=280 : ypas= -ypas  : EndIf
    
    While WindowEvent() : Wend
Until quit = 1 
:)
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message par Good07 »

Ca marche Nickel ! :D

Y'a pas à dire, Dobro tu est le meilleur! Je te remercie au nom de tous les petits bidouilleurs comme moi. :lol:

J' étais en train de faire des essais et je n'avais pas encore trouvé d'astuce valable.

Merci encore .

André qui va faire brûler un cierge au dieu de l'informatique :wink:
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

content pour toi ! et Merci :D

Mais j'ai appris la leçon "tout flateur vit au depend de celui qui l'écoute
cette leçon vaut bien un fromage sans doute"

et ben NON !! t'aura pas mon Fromage !!
:lol: :lol:
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message par Good07 »

Toute flaterie mise à part non vraiment c'est super. :D

Pour le fromage même pas un pti morceau ?

E t ben moi j'ai un bon fromage de chèvre de notre Ardèche profonde et bien je le mangerai tout seul. Voilà ! :lol:

A plus en espérant toujours autan d'humour sur ce forum :wink:

André
Marcus
Messages : 187
Inscription : jeu. 22/janv./2004 19:08
Contact :

Message par Marcus »

si le perso traverse un obstacle , il faut le replacer au contact et inverser son sens de déplacement .
c'est également mon procédé , et sa buge jamais
Répondre