Faire un snake

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Kayne
Messages : 157
Inscription : sam. 06/oct./2007 18:33
Contact :

Faire un snake

Message par Kayne »

J'y crois pas j'arrive pas a faire un snake c pourtant un des trucs les plus faciles a faire il parait. Comment on fait pour que le corps suive la tete ? J'ai essayé ça mais ça marche pas bien:

Code : Tout sélectionner

;snake créé par Kayne - http://tripamort.free.fr

;constantes
Enumeration
#tete
#corps
#queue
#serpent
EndEnumeration

;initialisation des composants
InitSprite()
InitKeyboard()
InitSound()
InitSprite3D()

Structure donnees_serpent
  x.w
  y.w
  dx.b
  dy.b
  spr_colonne.w
  spr_ligne.w
EndStructure

Structure decision_serpent
  x.w
  y.w
  dx.b
  dy.b
EndStructure

Dim serpent.donnees_serpent(40)
NewList decision.decision_serpent()

;variable (par defaut au debut)
tete.donnees_serpent
;tête
tete_dl=4
tete\x=320
tete\y=320
tete\dx=4
tete\dy=0
tete_spr_colonne=0
tete_spr_ligne=0


;corps
taille_serpent=10
For i=0 To taille_serpent
  serpent(i)\x=tete\x-16*taille_serpent+16*i+corps_decalage_x
  serpent(i)\y=320+corps_decalage_y
  serpent(i)\dx=tete_dl
  serpent(i)\dy=0
  serpent(i)\spr_colonne=0
  serpent(i)\spr_ligne=32
Next i

corps_decalage_x=-32
corps_decalage_y=0

sens.s="droite"



Macro affiche_serpent()
 For i=0 To taille_serpent
    ClipSprite(#serpent,serpent(i)\spr_colonne,serpent(i)\spr_ligne,32,32)
    DisplayTransparentSprite(#serpent,serpent(i)\x+corps_decalage_x,serpent(i)\y+corps_decalage_y)
  Next i
 
  ClipSprite(#serpent,tete_spr_colonne,tete_spr_ligne,32,32)
  DisplayTransparentSprite(#serpent,tete\x,tete\y)

EndMacro 




Macro gestion_deplacement()
;déplacement 
  If tete\x<>0  And tete\y<>0
   
    ;prise de décision pour aller à droite
    ;{
    If sens="droite"
      If tete\dx<>tete_dl
        tete\dx=tete_dl
        tete\dy=0
        tete_spr_colonne=0
        tete_spr_ligne=0
        corps_decalage_x=-32
        corps_decalage_y=0
        AddElement(decision())
        decision()\x=tete\x
        decision()\y=tete\y
        decision()\dx=tete\dx
        decision()\dy=tete\dy
      EndIf
     
    EndIf
    ;}
   
    ;prise de décision pour aller à gauche
    ;{
    If sens="gauche"
      If tete\dx<>-tete_dl
        tete\dx=-tete_dl
        tete\dy=0
        tete_spr_colonne=64
        tete_spr_ligne=0
        corps_decalage_x=32
        corps_decalage_y=0
        AddElement(decision())
        decision()\x=tete\x
        decision()\y=tete\y
        decision()\dx=tete\dx
        decision()\dy=tete\dy
      EndIf
     
    EndIf
    ;}
   
    ;prise de décision pour aller en bas
    ;{
    If sens="bas"
      If tete\dy<>tete_dl
        tete\dx=0
        tete\dy=tete_dl
        tete_spr_colonne=32
        tete_spr_ligne=0
        corps_decalage_x=0
        corps_decalage_y=-32
        AddElement(decision())
        decision()\x=tete\x
        decision()\y=tete\y
        decision()\dx=tete\dx
        decision()\dy=tete\dy
      EndIf
    EndIf
    ;}
    
   
    ;prise de décision pour aller en haut
    ;{
    If sens="haut"
      If tete\dy<>-tete_dl
        tete\dx=0
        tete\dy=-tete_dl
        tete_spr_colonne=96
        tete_spr_ligne=0
        corps_decalage_x=0
        corps_decalage_y=0
        AddElement(decision())
        decision()\x=tete\x
        decision()\y=tete\y
        decision()\dx=tete\dx
        decision()\dy=tete\dy
      EndIf
     
    EndIf
    ;}
    
 EndIf
EndMacro 

Macro controle_serpent()
If KeyboardReleased(#PB_Key_Up )
sens="haut"
EndIf

If KeyboardReleased(#PB_Key_Down )
sens="bas"
EndIf

If KeyboardReleased(#PB_Key_Left )
sens="gauche"
EndIf

If KeyboardReleased(#PB_Key_Right )
sens="droite"
EndIf
EndMacro


 

;ouverture de l'ecran on commence le jeu
OpenScreen(1024,768,32,"Snake - Kayne - http://tripamort.free.fr")

;chargement des sprites // creation des sprites 3D
;planche d'images
LoadSprite(#serpent,"sprites/serpent.bmp")


Repeat 
FlipBuffers()
ClearScreen(RGB(0,0,0))
ExamineKeyboard()
controle_serpent()
gestion_deplacement()

;deplacement du corps
For i=0 To taille_serpent
   
    ForEach decision()
     
      If serpent(i)\x=decision()\x And serpent(i)\y=decision()\y
        serpent(i)\dx=decision()\dx
        serpent(i)\dy=decision()\dy
      EndIf
     
    Next
   
  Next i

;mise en mouvemennt  
If ElapsedMilliseconds()-chrono>50
    chrono=ElapsedMilliseconds()
    tete\x=tete\x+tete\dx
    tete\y=tete\y+tete\dy
    If cible_atteinte=0
      For i=0 To taille_serpent
        serpent(i)\x=serpent(i)\x+serpent(i)\dx
        serpent(i)\y=serpent(i)\y+serpent(i)\dy
      Next i
    EndIf
EndIf
  
affiche_serpent()
Until KeyboardPushed(#PB_Key_Escape )
Image pour les sprites.
__________________________________________

Débutant les tutoriels de mon site sont la pour vous n'hésitez pas à aller les voir: http://tripamort.free.fr/
__________________________________________
Kayne - Webmaster de http://tripamort.free.fr/
Anonyme

Message par Anonyme »

Tu fait une rotation du corps en fonction de la direction ? 8O
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Faire un snake

Message par Backup »

[quote="Kayne"]J'y crois pas j'arrive pas a faire un snake c pourtant un des trucs les plus faciles a faire il parait. Comment on fait pour que le corps suive la tete ? J'ai essayé ça mais ça marche pas bien:


deja presenté par Huitbit ici :

http://www.purebasic.fr/french/viewtopi ... ght=dragon
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

Encore mieux
Le code de base d'un snake(méthode différente, plus classique je pense) (code ancien posté quelques mois après mes histoires de dragon!)
http://www.purebasic.fr/french/viewtopic.php?t=6950


Posté par Oliv (je crois :roll: )

Flèches gauche et droite pour se déplacer

Code : Tout sélectionner

 If InitSprite() = 0 Or InitKeyboard() = 0 
        MessageRequester("Error", "Can't open DirectX 7 or later", 0) 
        End 
    EndIf 

    If OpenScreen(1024, 768, 32, "Sprite") 

    CreateSprite(0, 16, 16) 
  
    If StartDrawing(SpriteOutput(0)) 
        ;Box(0, 0, 16, 16, #White) 
        Circle(8, 8, 8, #White) 
    StopDrawing() 
  EndIf 

Structure SERP 
    X.L 
    Y.L 
    A.F 
    R.L 
EndStructure 
  
  NewList Serp.SERP() 
  For i = 0 To 31 
      AddElement(Serp() ) 
      Serp()\X = i << 4 
      Serp()\Y = 3 << 7 
      Serp()\A = 0.0 
      Serp()\R = 1 << 4 
  Next 

  Queue.L = 0 
  Tete.L = 31 
  A.F = 0 
  Repeat 
    
    
    FlipBuffers() 
    
    ClearScreen(RGB(0,0,0)) 
    
    ForEach(Serp() ) 
        DisplaySprite(0, Serp()\X, Serp()\Y) 
    Next 
    SelectElement(Serp(), Tete) 
    X = Serp()\X 
    Y = Serp()\Y    
    R = Serp()\R 
    SelectElement(Serp(), Queue) 
    Serp()\X = X + Cos(A) * R 
    Serp()\Y = Y - Sin(A) * R 
    If ElapsedMilliseconds() > Delai 
        Delai = ElapsedMilliseconds() + 100 
        Sature = 0 
        Tete = Queue 
        Queue + 1 
        If Queue > 31: Queue = 0: EndIf    
    EndIf 
    ExamineKeyboard() 
    If KeyboardPushed(#PB_Key_Left) 
        If Sature = 0 
            A + (#PI / 8) 
            Sature = 1 
        EndIf 
    EndIf 
    If KeyboardPushed(#PB_Key_Right)          
        If Sature = 0 
            A - (#PI / 8) 
            Sature = 1 
        EndIf 
    EndIf 
  Until KeyboardPushed(#PB_Key_Escape) 
  
EndIf 

End   
Hasta la vista !
Kayne
Messages : 157
Inscription : sam. 06/oct./2007 18:33
Contact :

Message par Kayne »

Kayne a écrit :J'y crois pas j'arrive pas a faire un snake c pourtant un des trucs les plus faciles a faire il parait. Comment on fait pour que le corps suive la tete ? J'ai essayé ça mais ça marche pas bien:


deja presenté par Huitbit ici :

http://www.purebasic.fr/french/viewtopi ... ght=dragon
Je me suis inspiré de son code mais il y a des bugs quand on va a droite alors que le serpent allait a gauche. De plus je galère un peu a comprendre le code de huitbit.
__________________________________________

Débutant les tutoriels de mon site sont la pour vous n'hésitez pas à aller les voir: http://tripamort.free.fr/
__________________________________________
Kayne - Webmaster de http://tripamort.free.fr/
Kayne
Messages : 157
Inscription : sam. 06/oct./2007 18:33
Contact :

Message par Kayne »

Pour la direction du serpent c bon j'ai trouvé mais maintenant c quand je change la taille du serpent ou quand je modifie la vitesse (tete_dl) que ca foire.

Code : Tout sélectionner


;snake créé par Kayne - http://tripamort.free.fr

;constantes
Enumeration
#tete
#corps
#serpent

#mur1
#mur2
#mur3
#mur4

#boule
EndEnumeration

Structure donnees_serpent
  x.w
  y.w
  dx.b
  dy.b
  spr_colonne.w
  spr_ligne.w
EndStructure

Structure decision_serpent
  x.w
  y.w
  dx.b
  dy.b
EndStructure


;initialisation des composants
InitSprite()
InitKeyboard()
InitSound()
InitSprite3D()

;variable (par defaut au debut)
Dim serpent.donnees_serpent(40)
NewList decision.decision_serpent()

tete.donnees_serpent
;tête
tete_dl=1 ; vitesse de deplacement du serpent
tete\x=320 ;coordonnée de la tete
tete\y=320


;corps
taille_serpent=5 ;taille du corps
For i=0 To taille_serpent
  serpent(i)\x=tete\x-32*taille_serpent+32*i ;positionnement du corps
  serpent(i)\y=320
  serpent(i)\dx=tete_dl ;vitesse du corps
  serpent(i)\dy=0
  serpent(i)\spr_colonne=0
  serpent(i)\spr_ligne=32
Next i

corps_decalage_x=32
corps_decalage_y=0

sens.s="droite"

bouleX = Random(1000)+10
bouleY = Random(700) + 10


Macro controle_serpent()
If KeyboardReleased(#PB_Key_Up ) And sens <> "bas"
sens="haut"
EndIf

If KeyboardReleased(#PB_Key_Down ) And sens <> "haut"
sens="bas"
EndIf

If KeyboardReleased(#PB_Key_Left ) And sens <> "droite"
sens="gauche"
EndIf

If KeyboardReleased(#PB_Key_Right ) And sens <> "gauche"
sens="droite"
EndIf
EndMacro



Macro gestion_deplacement()
;déplacement 
  If tete\x<>0  And tete\y<>0
   
    ;prise de décision pour aller à droite
    ;{
    If sens="droite"
      If tete\dx<>tete_dl
        tete\dx=tete_dl
        tete\dy=0
        tete_spr_colonne=0
        tete_spr_ligne=0
        corps_decalage_x=32
        corps_decalage_y=0
        AddElement(decision())
        decision()\x=tete\x
        decision()\y=tete\y
        decision()\dx=tete\dx
        decision()\dy=tete\dy
      EndIf
     
    EndIf
    ;}
   
    ;prise de décision pour aller à gauche
    ;{
    If sens="gauche"
      If tete\dx<>-tete_dl
        tete\dx=-tete_dl
        tete\dy=0
        tete_spr_colonne=64
        tete_spr_ligne=0
        corps_decalage_x=-32
        corps_decalage_y=0
        AddElement(decision())
        decision()\x=tete\x
        decision()\y=tete\y
        decision()\dx=tete\dx
        decision()\dy=tete\dy
      EndIf
     
    EndIf
    ;}
   
    ;prise de décision pour aller en bas
    ;{
    If sens="bas"
      If tete\dy<>tete_dl
        tete\dx=0
        tete\dy=tete_dl
        tete_spr_colonne=32
        tete_spr_ligne=0
        corps_decalage_x=0
        corps_decalage_y=32
        AddElement(decision())
        decision()\x=tete\x
        decision()\y=tete\y
        decision()\dx=tete\dx
        decision()\dy=tete\dy
      EndIf
    EndIf
    ;}
    
   
    ;prise de décision pour aller en haut
    ;{
    If sens="haut"
      If tete\dy<>-tete_dl
        tete\dx=0
        tete\dy=-tete_dl
        tete_spr_colonne=96
        tete_spr_ligne=0
        corps_decalage_x=0
        corps_decalage_y=-32
        AddElement(decision())
        decision()\x=tete\x
        decision()\y=tete\y
        decision()\dx=tete\dx
        decision()\dy=tete\dy
      EndIf
     
    EndIf
    ;}
    
 EndIf
EndMacro 

;deplacement du corps et rotation
Macro rotation()
For i=0 To taille_serpent
    
    ResetList(decision())
    While NextElement(decision())
     
      If serpent(i)\x=decision()\x And serpent(i)\y=decision()\y
        serpent(i)\dx=decision()\dx
        serpent(i)\dy=decision()\dy
        If sens = "haut" Or sens = "bas"
        serpent(i)\spr_colonne = 64
        serpent(i)\spr_ligne = 32
        Else
        serpent(i)\spr_colonne = 0
        serpent(i)\spr_ligne = 32
        EndIf
      EndIf
     
    Wend 
   
 Next i
 
 EndMacro
 


;mise en mouvemennt  
Macro mouvement()
tete\x=tete\x+tete\dx
tete\y=tete\y+tete\dy
For i=0 To taille_serpent
   serpent(i)\x=serpent(i)\x+serpent(i)\dx
   serpent(i)\y=serpent(i)\y+serpent(i)\dy
Next i
EndMacro

Macro affiche_serpent()
 For i=0 To taille_serpent
    ClipSprite(#serpent,serpent(i)\spr_colonne,serpent(i)\spr_ligne,32,32)
    DisplayTransparentSprite(#serpent,serpent(i)\x,serpent(i)\y)
  Next i
 
  ClipSprite(#serpent,tete_spr_colonne,tete_spr_ligne,32,32)
  DisplayTransparentSprite(#serpent,tete\x+corps_decalage_x,tete\y+corps_decalage_y)

EndMacro 

  Macro fin_partie()
  ; on affiche partie terminée
  
  For text_hauteur = 20 To 400 Step 2
    FlipBuffers()
    ClearScreen(RGB(0,0,0))
    StartDrawing(ScreenOutput())
    DrawingMode(1)
    DrawText(1024/2-TextWidth("Partie Terminée ... ")/2,text_hauteur,"Partie Terminée ... ",RGB(255,0,0))
    DrawText(0,0,"Kayne - Snake",RGB(255,255,255))
    DrawText(1024/2-TextWidth("Votre Score: "+Str(score))/2,30+text_hauteur,"Votre Score: "+Str(score),RGB(200,0,0))
    StopDrawing()
  Next text_hauteur

  
  ;on remet les valeurs par defaut du début
  ;tableaux et liste chainée
  Dim serpent.donnees_serpent(40)
  ClearList(decision())
  
  ;tete
  tete_dl=1 ; vitesse de deplacement du serpent
  tete\x=320 ;coordonnée de la tete
  tete\y=320
  ;corps
  taille_serpent = 5
  For i=0 To taille_serpent
    serpent(i)\x=tete\x-32*taille_serpent+32*i ;positionnement du corps
    serpent(i)\y=320
    serpent(i)\dx=tete_dl ;vitesse du corps
    serpent(i)\dy=0
    serpent(i)\spr_colonne=0
    serpent(i)\spr_ligne=32
  Next i
  corps_decalage_x=32
  corps_decalage_y=0
  ;sens
  sens="droite"
  
    score = 0 ; on remet le score a zero
    
  bouleX = Random(1000)+10
  bouleY = Random(700) + 10

  EndMacro   
  
  

 

;ouverture de l'ecran on commence le jeu
OpenScreen(1024,768,32,"Snake - Kayne - http://tripamort.free.fr")

;chargement des sprites
;planche d'images
LoadSprite(#serpent,"sprites/serpent.bmp")
LoadSprite(#tete,"sprites/tete.bmp")
LoadSprite(#corps,"sprites/corps.bmp")
LoadSprite(#boule,"sprites/boule.bmp")

Repeat 
FlipBuffers()
ClearScreen(RGB(0,0,0))
ExamineKeyboard()

;deplacement du serpent
controle_serpent()
gestion_deplacement() 
rotation()
mouvement()
affiche_serpent()

;creation et affichage des murs
CreateSprite(#mur1,10,758)
CreateSprite(#mur2,1014,10)
CreateSprite(#mur3,10,758)
CreateSprite(#mur4,1014,10)

StartDrawing(SpriteOutput(#mur1))
  For mur = 0 To 10
  Line(mur,0,0,768,RGB(100+mur*5,50+mur*5,mur*5))
  Next mur 
StopDrawing()

StartDrawing(SpriteOutput(#mur2))
  For mur = 0 To 10
  Line(0,mur,1024,0,RGB(100+mur*5,50+mur*5,mur*5))
  Next mur 
StopDrawing()

StartDrawing(SpriteOutput(#mur3))
  For mur = 0 To 10
  Line(mur,0,0,768,RGB(100+mur*5,50+mur*5,mur*5))
  Next mur 
StopDrawing()

StartDrawing(SpriteOutput(#mur4))
  For mur = 0 To 10
  Line(0,mur,1024,0,RGB(100+mur*5,50+mur*5,mur*5))
  Next mur 
StopDrawing()

DisplaySprite(#mur1,0,0)
DisplaySprite(#mur2,10,0)
DisplaySprite(#mur3,1014,10)
DisplaySprite(#mur4,0,758)


;affichage du score
StartDrawing(ScreenOutput())
  DrawingMode(1)
  DrawText(1024/2-TextWidth("Score: "+Str(score)+"        Vitesse du serpent: "+Str(tete_dl)+"        Longueur du corps: "+Str(taille_serpent))/2,10,"Score: "+Str(score)+"        Vitesse du serpent: "+Str(tete_dl)+"        Longueur du corps: "+Str(taille_serpent),RGB(255,255,255))
StopDrawing()  

;regle du jeu

;si le serpent se touche lui même la partie est perdue
For i=0 To taille_serpent-2 ; on ne compte les "deux premiers" corps juste a coté de la tete.
  If SpriteCollision(#tete,tete\x,tete\y,#corps,serpent(i)\x,serpent(i)\y)
     fin_partie()
  EndIf 
Next i

;collision avec les murs = partie perdue
If SpriteCollision(#tete,tete\x+corps_decalage_x,tete\y+corps_decalage_y,#mur1,0,0) Or SpriteCollision(#tete,tete\x+corps_decalage_x,tete\y+corps_decalage_y,#mur2,10,0) Or SpriteCollision(#tete,tete\x+corps_decalage_x,tete\y+corps_decalage_y,#mur3,1014,10) Or SpriteCollision(#tete,tete\x+corps_decalage_x,tete\y+corps_decalage_y,#mur4,0,758)
  fin_partie()
EndIf

;affichage de la boule a prendre
DisplaySprite(#boule, bouleX,bouleY)

If SpriteCollision(#tete,tete\x+corps_decalage_x,tete\y+corps_decalage_y,#boule, bouleX,bouleY)
score+10
bouleX = Random(1000)+10
bouleY = Random(700) + 10
taille_serpent+1
EndIf

;augmentation progressive de la vitesse

;For i = 1 To 10
;If score >= 10 * i
;   tete_dl = i*2
;EndIf
;Next i

Until KeyboardPushed(#PB_Key_Escape )
__________________________________________

Débutant les tutoriels de mon site sont la pour vous n'hésitez pas à aller les voir: http://tripamort.free.fr/
__________________________________________
Kayne - Webmaster de http://tripamort.free.fr/
Kayne
Messages : 157
Inscription : sam. 06/oct./2007 18:33
Contact :

Message par Kayne »

Aucune solution ???
__________________________________________

Débutant les tutoriels de mon site sont la pour vous n'hésitez pas à aller les voir: http://tripamort.free.fr/
__________________________________________
Kayne - Webmaster de http://tripamort.free.fr/
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Message par Cls »

Où sont les sprites (j'ai bien le serpent mais pas le reste) ?
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Message par beauregard »

Cls a écrit :Où sont les sprites (j'ai bien le serpent mais pas le reste) ?
en lisant le code:

Code : Tout sélectionner

;chargement des sprites
;planche d'images
LoadSprite(#serpent,"sprites/serpent.bmp")
LoadSprite(#tete,"sprites/tete.bmp")
LoadSprite(#corps,"sprites/corps.bmp")
LoadSprite(#boule,"sprites/boule.bmp")
si l'auteur n'a pas mis ses images, c'est sûrement pour une bonne raison. Une conversion en .png ne serait pas mal venu.
Cls
Messages : 620
Inscription : mer. 22/juin/2005 8:51
Localisation : Nantes

Message par Cls »

Perso je pense que c'est un oubli, mais c'est embêtant car on ne peut pas tester :(

Edit : +1 pour le PNG (même si le serpent.bmp n'est pas très gros : 20k je crois)
Répondre