Dragon's fury(fallait pas l'énerver!):MAJ6 chgt de planches

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Dragon's fury(fallait pas l'énerver!):MAJ6 chgt de planches

Message par Huitbit »

Pure_Dragon (snake avec listes chaînées)+MAJ1+MAJ2+1correction+mise en forme du code+MAJ3 tir de boules de feu+MAJ4 6 fonds d'écran(Beauregard+Dobro+combinaisons) et nouvelle macro (gain de 150 lignes!)
MAJ5 dragon à vapeur belliqueux + affichage score en temps réel+MAJ6 changement de planche de sprites+correction du problème de tir

Yé souis dé rétour !!!
Après quelques jours de repos (bien mérités ?), j’ai voulu me mettre aux listes chaînées.
J’ai refais (c’est pas encore fini, mais c’est jouable !) le premier jeu auquel j’ai joué sur mon
MSX : Super Snake (donné lors de l’achat, une Super escroquerie quand on connaît le potentiel de la bête !).
Image
En résumé :


Dragon__________________________:<<queue du dragon <<corps du dragon<<tête du dragon>>
Index de l’élément de la liste chaînée :<<0<<...n-5<<n-4.. <<nième élément>>

Les grosses difficultés (pour moi!) : je ne voulais pas un "serpent de boules" et une animation bloc par bloc

( à droite, les différents fonds d'écran Dobro's et Beauregard's)
Image

Le dragon se déplace de 32 pixels en 32 pixels
Seules la tête et la queue sont animées pixels par pixels
L’animation est court-circuitée quand un changement de direction est demandé.

Pour la gestion du temps, j’ai utilisé la méthode vue chez Maître Comtois

Je rajouterai des options (voir macros "manger" et extraboule"), puis des ennemis...


OPTIONS ACTUELLES:
boule de feu : vitesse*2
boule ying-yang:
-vitesse normale ou double
-purge complète du dragon
-purge sélective (eau, feu,...)(MAJ1)
-éclatement des roches MAJ2
-tir de boules de feu (MAJ3)
-choix du fond d'écran (MAJ4)
-dragon à vapeur belliqueux + affichage score en temps réel(MAJ5)
-changement de planche de sprites avec F2 (MAJ6)

OPTIONS PREVUES:
-....etc
-vos options :wink:

Ca s'appelle mémoire de dragon car avant de manger une boule, il faut savoir depuis combien de temps elle est là !

Désolé pour les sprites, c'est du paint (16 couleurs, 1heure), si un artiste a du temps...

Sprites à télécharger(planche_mdd.png et planche_mdd1.png)
et à mettre dans le même dossier que le programme


Image


et (Cpl Bator'style)
Image

Code : Tout sélectionner

;auteur Huitbit 
  ;mémoire de dragon (snake et listes chaînées) 
  ;pb v4.02 
  ;*************************************************** 
  ;-déclarations 
  ;{ 
  Enumeration 
    #spr_planche : #spr_ecran 
    #roche : #eau : #air :  #terre : #feu : #ying_yang 
    #liste_open : #liste_closed : #liste_mur 
  EndEnumeration 
  
  Structure donnees_dragon 
    x.w : y.w : dx.b : dy.b 
    spr_colonne.w : spr_ligne.w 
    coude.b 
    queue.b 
    type.b 
    numero_decision.b 
  EndStructure 
  
  Structure decision_dragon_fer 
    x.w :  y.w 
    dx.b : dy.b 
  EndStructure 
  
  Structure infos_carte 
    decor.b 
    id.w : parent.w : f.w : g.w : liste.b 
  EndStructure 
  
  Structure liste 
    id.w : f.w 
  EndStructure 
  
  Structure donnees_boule 
    x.w : y.w : dx.b : dy.b 
    projectile.b 
    spr_colonne.w : spr_ligne.w 
    type.b 
    date_de_creation.l 
  EndStructure 
  
  Structure fond_etoile 
    x.w : y.w  
  EndStructure 
  ;} 
  ;{ 
  ;dragon 
  taille_dragon.b 
  delai_animation.b 
  vitesse_dragon.b 
  dragon_queue_dx.b : dragon_queue_dy.b 
  coude.b 
  dragon_estomac.b 
  previous_dragon_dx.b : previous_dragon_dy.b 
  delai_changement_direction.w 
  dragon_tete_x_anim.w : dragon_tete_y_anim.w 
  dragon_queue_x_anim.w : dragon_queue_y_anim.w 
  dragon_tete_fin_x_anim.w : dragon_tete_fin_y_anim.w 
  direction.w 
  previous_dragon_colonne.w 
  previous_dragon_x_tete.w : previous_dragon_y_tete.w 
  NewList dragon.donnees_dragon() 
  NewList dragon_fixe.w() 
  
  
  ;boules 
  boule_speciale.b 
  tirage.b 
  manger_boule.b 
  boule_a_eliminer.w 
  x_boule.w : y_boule.w 
  x_roche.w : y_roche.w 
  nombre_de_boules.w 
  boules_mangees.w 
  date_creation_boule.l 
  duree_formation_boule.l 
  duree_vie_boule.l 
  couleur.l 
  date_du_tir.l=ElapsedMilliseconds() 
  delai_animation_tir.w 
  NewList boule.donnees_boule() 
  
  ;dragon_fer 
  date_declenchement_pathfinding.l 
  delai_entre_deux_pathfinding.w=300 
  delai_animation_dragon_fer.b=20 
  fer_corps_decalage_x.b :fer_corps_decalage_y.b 
  fer_dx_decision.b : fer_dy_decision.b 
  fer_temps_en_cours.l 
  ID_case.w 
  taille_dragon_fer.b 
  tete_fer_dl.b 
  tete_fer_spr_colonne.w : tete_fer_spr_ligne.w 
  Global fer_position_premier_element.w , x_cible.b, y_cible.b,*fer_memoryID_x.l,*fer_memoryID_y.l, fer_position_sauvegarde.w ,animation_dragon_fer.b, dragon_fer_action.b 
  Dim dragon_fer.donnees_dragon(20) 
  NewList decision.decision_dragon_fer() 
  Global Dim liste_ouverte.liste(767) 
  tete_fer.donnees_dragon 
  ;adresses pour la mémorisation des coordonnées du dragon_fer 
  *fer_memoryID_x=AllocateMemory(1000) 
  *fer_memoryID_y=AllocateMemory(1000) 
  
  ;divers 
  planche.b=0
  fond_d_ecran.b =0
  i.w : j.w 
  Second.l :Event.l : fps.l : Frame_Counter.l 
  Global Dim fond_etoile.fond_etoile(1512) 
  Global nbspritefond=512 ; nombre d'etoiles 
  Global Dim carte.infos_carte(31, 23) 
  
  ;ID des cases 
  For i=0 To 31 
    For j=0 To 23 
      carte(i,j)\id=ID_case    
      ID_case+1      
    Next j 
  Next i 
  
  ;} 
  ;-MACROS et PROCEDURE 
  Macro initialisation 
  ;-planches de sprites
If planche=0
    LoadSprite(#spr_planche,"planche_mdd.png")
    ElseIf planche=1
      LoadSprite(#spr_planche,"planche_mdd1.png") 
      EndIf

  ;-fonds d'écran 
  ;{ 
  CreateSprite(#spr_ecran,1024,768) 
  If fond_d_ecran=1 Or fond_d_ecran=4 
    ;-damier pour effectuer les tests 
    StartDrawing(SpriteOutput(#spr_ecran));dessin d'un damier pour les tests 
    Box(32,32,992,736,RGB(255,255,255));fond blanc 
    For i=1 To 30 
      For j=1 To 22 
        If (i+j)%2=0 
          Box(i*32,j*32,32,32,RGB(128,128,128));cases grises 
        EndIf 
      Next j 
    Next i 
    StopDrawing() 
  EndIf 
  
  ;-damier beauregard 
  If fond_d_ecran=2 Or fond_d_ecran=5 
    StartDrawing(SpriteOutput(#spr_ecran));dessin d'un damier pour les tests 
    Box(32,32,992,736,RGB(126,16,16));fond blanc 
    
    For i=1 To 30 
      For j=1 To 22 
        If (i+j)%2=0 
          regard=(i*4) 
          Xregard=i*32:Yregard=j*32 
          Box(Xregard,Yregard,32,32,RGB(regard+25 , regard , regard)) 
          Box(Xregard+2,Yregard+2,28,28,RGB(regard+25+25 , regard , regard))    
        EndIf 
      Next j 
    Next i 
    
    StopDrawing() 
  EndIf 
  
  UseBuffer(#spr_ecran);sprite rocher comme bordure 
  boules_mangees=0 
  nombre_de_boules=0 
  For i=0 To 31 
    For j=0 To 23 
      If i=0 Or i=31 Or j=0 Or j=23 
        carte(i,j)\liste=#liste_mur 
        ClipSprite(#spr_planche,32,160,32,32) 
        DisplaySprite(#spr_planche,i*32,j*32) 
        
      Else;création du "champ de roches" initial 
        If Random(30)=1 And j<>2 ; j<>2 couloir libre pour les dragons 
          AddElement(boule()) 
          boule()\x=i*32 
          boule()\y=j*32 
          boule()\spr_colonne=32 
          boule()\spr_ligne=160 
          boule()\type=#roche 
          carte(i,j)\decor=#roche 
          carte(i,j)\liste=#liste_mur 
          nombre_de_boules=nombre_de_boules+1 
        Else 
          carte(i,j)\decor=0 
          carte(i,j)\liste=0 
        EndIf 
        
      EndIf 
    Next j 
  Next i 
  UseBuffer(-1) 
  StartDrawing(SpriteOutput(#spr_ecran)) 
  DrawingMode(#PB_2DDrawing_Transparent) 
  DrawingFont(FontID(0)) 
  DrawText(0,4,"FPS :                        Nombre de boule(s) mangée(s) : ",RGB(255,255,180)) 
  StopDrawing() 
  
  ;} 
  ;-dragon initial 
  ;{ 
  taille_dragon=2 
  delai_animation=10 
  vitesse_dragon=4 
  delai_changement_direction=80 
  duree_formation_boule=1000 
  duree_vie_boule=20000 
  delai_animation_tir=200 
  For i=0 To taille_dragon 
    AddElement(dragon()) 
    dragon()\x=(i+2)*32 
    dragon()\y=64 
    dragon()\dx=1 
    dragon()\dy=0 
    dragon()\spr_colonne=0 
    dragon()\spr_ligne=0 
    AddElement(dragon_fixe()) 
    dragon_fixe()=99 
  Next i 
  dragon_tete_x_anim=(taille_dragon+2)*32 
  dragon_tete_y_anim=2*32 
  dragon_queue_x_anim=2*32 
  dragon_queue_y_anim=2*32 
  direction=#PB_Key_Right 
  ;} 
  EndMacro 
  
  Macro initialisation_dragon_fer 
  ;-initalisation 
  ;dragon_fer initial 
  ;tête 
  tete_fer_dl=4 
  tete_fer\x=64 
  tete_fer\y=64 
  tete_fer\dx=0 
  tete_fer\dy=0 
  tete_fer_spr_colonne=0 
  tete_fer_spr_ligne=192 
  ;corps 
  taille_dragon_fer=20 
  For i=0 To taille_dragon_fer 
    dragon_fer(i)\x=tete_fer\x-16*taille_dragon_fer+16*i 
    dragon_fer(i)\y=tete_fer\y 
    dragon_fer(i)\numero_decision=0 
    dragon_fer(i)\dx=tete_fer_dl 
    dragon_fer(i)\dy=0 
    dragon_fer(i)\spr_colonne=64 
    dragon_fer(i)\spr_ligne=160 
  Next i 
  fer_corps_decalage_x=0 
  fer_corps_decalage_y=8 
  date_declenchement_pathfinding=ElapsedMilliseconds() 
  dragon_fer_action=0 
  animation_dragon_fer=0 
  ClearList(decision()) 
  EndMacro 
  
  Macro changement_direction_clavier(choix_direction,valeur_last_dragon_dx,valeur_last_dragon_dy,valeur_last_dragon_spr_colonne,test1_pdx,test1_dx,test1_pdy,test1_dy,test2_pdx,test2_dx,test2_pdy,test2_dy,pdx,pdy,pq,pc,psprl,p1sprc,p2sprc) 
  
  If ElapsedMilliseconds()-temps_en_cours>delai_changement_direction;gestion du temps d'appui sur la touche de direction 
    temps_en_cours=ElapsedMilliseconds() 
    date_du_tir=ElapsedMilliseconds() 
    
    direction=choix_direction 
    LastElement(dragon()) 
    previous_dragon_x_tete=dragon()\x 
    previous_dragon_y_tete=dragon()\y 
    previous_dragon_dx=dragon()\dx 
    previous_dragon_dy=dragon()\dy 
    AddElement(dragon())    
    dragon()\dx=valeur_last_dragon_dx 
    dragon()\dy=valeur_last_dragon_dy 
    dragon()\x=previous_dragon_x_tete+32*dragon()\dx 
    dragon()\y=previous_dragon_y_tete+32*dragon()\dy 
    
    manger 
    
    dragon_tete_x_anim=dragon()\x 
    dragon_tete_y_anim=dragon()\y 
    dragon()\spr_colonne=valeur_last_dragon_spr_colonne 
    
    If  ((previous_dragon_dx=test1_pdx And dragon()\dx=test1_dx) And (previous_dragon_dy=test1_pdy And dragon()\dy=test1_dy)) 
      PreviousElement(dragon()) 
      dragon()\dx=pdx 
      dragon()\dy=pdy 
      dragon()\queue=pq 
      dragon()\coude=pc 
      dragon()\spr_ligne=psprl 
      dragon()\spr_colonne=p1sprc 
    ElseIf  ((previous_dragon_dx=test2_pdx And dragon()\dx=test2_dx) And (previous_dragon_dy=test2_pdy And dragon()\dy=test2_dy)) 
      PreviousElement(dragon()) 
      dragon()\dx=pdx 
      dragon()\dy=pdy 
      dragon()\queue=pq 
      dragon()\coude=pc 
      dragon()\spr_ligne=psprl 
      dragon()\spr_colonne=p2sprc 
    EndIf 
    If manger_boule=0 
      FirstElement(dragon()) 
      NextElement(dragon());affectation des coordonnées à l'avant-dernier bout de queue car le dernier sera supprimé 
      dragon_queue_x_anim=dragon()\x 
      dragon_queue_y_anim=dragon()\y 
      FirstElement(dragon()) 
      DeleteElement(dragon())  
    Else 
      manger_boule=0 
    EndIf 
    
    EndMacro 
    
    Macro extraboule(boule_speciale) 
    ;vitesse aléatoire 4 ou 8 
    If boule_speciale=0 
      vitesse_dragon=4+4*Random(1) 
      
      ;purge du dragon          
    ElseIf boule_speciale=1 
      dragon_estomac=0 
      ForEach dragon_fixe() 
        If  dragon_fixe()<>99 
          dragon_estomac=dragon_estomac+1 
        EndIf 
      Next 
      ForEach   dragon_fixe()      
        If  dragon_fixe()<>99 
          DeleteElement(dragon_fixe()) 
        EndIf 
      Next 
      For i=1 To dragon_estomac 
        FirstElement(dragon()) 
        NextElement(dragon());affectation des coordonnées à l'avant-dernier bout de queue car le dernier sera supprimé 
        dragon_queue_x_anim=dragon()\x 
        dragon_queue_y_anim=dragon()\y 
        FirstElement(dragon()) 
        DeleteElement(dragon())  
      Next i 
      StartDrawing(ScreenOutput()) 
      DrawingMode(#PB_2DDrawing_Outlined)  
      For i=1 To 48 Step 3 
        Circle(dragon_tete_x_anim+16,dragon_tete_y_anim+16,i,RGB(10*Random(25),10*Random(25),10*Random(25))) 
      Next i 
      StopDrawing() 
      FlipBuffers() 
      Delay(80) 
      
      ;purge par type de boule 
    ElseIf boule_speciale=2 
      dragon_estomac=0 
      boule_a_eliminer=#eau+Random(3) 
      ForEach dragon_fixe() 
        If  dragon_fixe()=boule_a_eliminer 
          dragon_estomac=dragon_estomac+1 
        EndIf 
      Next 
      ForEach   dragon_fixe()      
        If  dragon_fixe()=boule_a_eliminer 
          DeleteElement(dragon_fixe()) 
        EndIf 
      Next 
      For i=1 To dragon_estomac 
        FirstElement(dragon()) 
        NextElement(dragon());affectation des coordonnées à l'avant-dernier bout de queue car le dernier sera supprimé 
        dragon_queue_x_anim=dragon()\x 
        dragon_queue_y_anim=dragon()\y 
        FirstElement(dragon()) 
        DeleteElement(dragon())  
      Next i 
      Select boule_a_eliminer 
        Case #eau 
          couleur=RGB(16, 147, 239) 
        Case #air 
          couleur=RGB(237, 247, 254) 
        Case #terre 
          couleur=RGB(157, 91, 22) 
        Case #feu 
          couleur=RGB(255, 229, 0) 
      EndSelect 
      StartDrawing(ScreenOutput()) 
      DrawingMode(#PB_2DDrawing_Outlined)    
      For i=1 To 32 Step 2 
        Circle(dragon_tete_x_anim+16,dragon_tete_y_anim+16,i,couleur) 
      Next i 
      StopDrawing() 
      FlipBuffers() 
      Delay(80) 
      
      ;élimination des roches 
    ElseIf boule_speciale=3 
      ForEach boule() 
        If  boule()\type=#roche 
          carte(boule()\x/32,boule()\y/32)\decor=0 
          carte(boule()\x/32,boule()\y/32)\liste=0 
          DeleteElement(boule())  
          nombre_de_boules=nombre_de_boules-1 
        EndIf 
      Next 
      StartDrawing(ScreenOutput()) 
      For i=1 To 200 
        Plot(dragon_tete_x_anim+Random(32),dragon_tete_y_anim+Random(32),RGB(157, 91, 22)) 
      Next i 
      StopDrawing() 
      FlipBuffers() 
      Delay(80) 
      
      ;apparition du dragon de fer 
    ElseIf boule_speciale=4 Or boule_speciale=5 
      If dragon_fer_action=0 
        ;nettoyage de  la  2ème ligne de roches 
        ForEach boule() 
          If  boule()\y=64 
            carte(boule()\x/32,boule()\y/32)\decor=0 
            carte(boule()\x/32,boule()\y/32)\liste=0 
            DeleteElement(boule())  
            nombre_de_boules=nombre_de_boules-1 
          EndIf 
        Next 
        initialisation_dragon_fer 
        dragon_fer_action=1 
      Else 
        dragon_fer_action=0 
      EndIf 
    EndIf 
    LastElement(dragon()) 
    
    EndMacro 
    
    Macro manger 
    
    ForEach boule() 
      If boule()\type<>#roche 
        If dragon()\x=boule()\x And dragon()\y=boule()\y 
          manger_boule=1 
          AddElement(dragon_fixe()) 
          dragon_fixe()=boule()\type 
          
          Select boule()\type 
            Case #eau 
              vitesse_dragon=4 
            Case #air 
              vitesse_dragon=4 
            Case #terre 
              vitesse_dragon=2 
            Case #feu 
              vitesse_dragon=4 
            Case #ying_yang 
              boule_speciale=Random(5) 
              extraboule(boule_speciale) 
          EndSelect 
          
          carte(boule()\x/32,boule()\y/32)\decor=0 
          carte(boule()\x/32,boule()\y/32)\liste=0 
          nombre_de_boules=nombre_de_boules-1 
          boules_mangees=boules_mangees+1 
          DeleteElement(boule()) 
          Break 
        Else 
          manger_boule=0 
        EndIf 
      EndIf 
    Next 
    EndMacro        
    
    Macro tir(touche_tir,previous_dl,valeur_dl ,sens_deplacement,dl) 
    If KeyboardPushed(touche_tir)  And previous_dl=valeur_dl And direction=sens_deplacement 
      If ElapsedMilliseconds()-date_du_tir>delai_animation_tir 
        date_du_tir=ElapsedMilliseconds() 
        ForEach dragon_fixe() 
          If dragon_fixe()=#feu 
            AddElement(boule()) 
            boule()\x=dragon_tete_x_anim 
            boule()\y=dragon_tete_y_anim 
            boule()\projectile=1 
            boule()\dl=valeur_dl*16 
            boule()\type=#feu 
            boule()\spr_colonne=96 
            boule()\spr_ligne=128 
            FirstElement(dragon()) 
            NextElement(dragon());affectation des coordonnées à l'avant-dernier bout de queue car le dernier sera supprimé 
            dragon_queue_x_anim=dragon()\x 
            dragon_queue_y_anim=dragon()\y 
            FirstElement(dragon()) 
            DeleteElement(dragon())  
            Break 
          EndIf 
        Next 
        ForEach dragon_fixe() 
          If dragon_fixe()=#feu 
            DeleteElement(dragon_fixe()) 
            Break 
          EndIf 
        Next 
        
      EndIf 
    EndIf 
    EndMacro 
    
    Macro preparer_pathfinding() 
    For i=0 To 31 
      For j=0 To 23 
        If carte(i,j)\liste<>#liste_mur 
          carte(i,j)\liste=0  
          carte(i,j)\f=0 
          carte(i,j)\g=0 
          carte(i,j)\parent=0 
        EndIf        
      Next j 
    Next i 
    For i=1 To 767 
      liste_ouverte(i)\f=0 
    Next i 
    EndMacro 
    
    ;explorations des quatre cases adjacentes 
    Macro exploration_case_adjacente(i,j) 
    If carte(x_temp+i,y_temp+j)\liste=0 
      carte(x_temp+i,y_temp+j)\parent=carte(x_temp,y_temp)\id 
      carte(x_temp+i,y_temp+j)\g=carte(x_temp,y_temp)\g+1 
      carte(x_temp+i,y_temp+j)\f=manhattan(x_temp+i,y_temp+j)+carte(x_temp+i,y_temp+j)\g 
      carte(x_temp+i,y_temp+j)\liste=#liste_open 
      fer_position=fer_position+1 
      liste_ouverte(fer_position)\f=carte(x_temp+i,y_temp+j)\f 
      liste_ouverte(fer_position)\id=carte(x_temp+i,y_temp+j)\id 
      ajout_dans_liste_ouverte(fer_position) 
    ElseIf carte(x_temp+i,y_temp+j)\liste=#liste_open 
      If carte(x_temp+i,y_temp+j)\g > carte(x_temp,y_temp)\g + 1 
        carte(x_temp+i,y_temp+j)\parent=carte(x_temp,y_temp)\id 
        carte(x_temp+i,y_temp+j)\g=carte(x_temp,y_temp)\g+1 
        carte(x_temp+i,y_temp+j)\f=manhattan(x_temp+i,y_temp+j)+carte(x_temp+i,y_temp+j)\g 
      EndIf  
    EndIf        
    EndMacro 
    
    ;calcul de H************** 
    Macro manhattan(x,y) 
    (Abs(x-x_arrivee)+Abs(y-y_arrivee)) 
    EndMacro 
    
    ;construction du tas**************** 
    Macro ajout_dans_liste_ouverte(p) 
    k.w=p 
    f_a_placer.w =liste_ouverte(p)\f 
    id.w=liste_ouverte(p)\id 
    While k>=(fer_position_premier_element+1)   And f_a_placer< liste_ouverte(Int(k*0.5))\f 
      liste_ouverte(k)\f=liste_ouverte(Int(k*0.5))\f 
      liste_ouverte(k)\id=liste_ouverte(Int(k*0.5))\id  
      k=Int(k*0.5) 
    Wend 
    liste_ouverte(k)\f=f_a_placer 
    liste_ouverte(k)\id=id  
    EndMacro 
    
    ;remaniement du tas après suppression de la racine************************ 
    Macro reformer_tas(p) 
    travail.b=0; 0 : en cours, 1 : effectué 
    k.w=fer_position_premier_element  
    f_a_replacer.w= liste_ouverte(fer_position_premier_element)\f 
    id.w=liste_ouverte(fer_position_premier_element)\id 
    While travail=0 And 2*k<=p 
      If 2*k =p 
        indice_grand.w=p 
      Else 
        If liste_ouverte(2*k)\f<=liste_ouverte(2*k+1)\f 
          indice_grand=2*k 
        Else 
          indice_grand=2*k+1 
        EndIf 
      EndIf    
      If f_a_replacer>liste_ouverte(indice_grand)\f 
        liste_ouverte(k)\f=liste_ouverte(indice_grand)\f    
        liste_ouverte(k)\id=liste_ouverte(indice_grand)\id 
        k=indice_grand 
      Else 
        travail=1 
      EndIf 
    Wend 
    liste_ouverte(k)\f=f_a_replacer 
    liste_ouverte(k)\id=id  
    EndMacro 
    
    
    Macro choix_du_sprite_tete_fer() 
    If tete_fer\dx=tete_fer_dl 
      tete_fer_spr_colonne=0 
      tete_fer_spr_ligne=192 
      fer_corps_decalage_x=0 
      fer_corps_decalage_y=8 
    ElseIf  tete_fer\dx=-tete_fer_dl 
      tete_fer_spr_colonne=64 
      tete_fer_spr_ligne=192 
      fer_corps_decalage_x=16 
      fer_corps_decalage_y=8 
    ElseIf tete_fer\dy=tete_fer_dl 
      tete_fer_spr_colonne=32 
      tete_fer_spr_ligne=192 
      fer_corps_decalage_x=8 
      fer_corps_decalage_y=0 
    ElseIf  tete_fer\dy=-tete_fer_dl 
      tete_fer_spr_colonne=96 
      tete_fer_spr_ligne=192 
      fer_corps_decalage_x=8 
      fer_corps_decalage_y=16 
    EndIf 
    EndMacro 
    
    Procedure pathfinding(x.b,y.b,x_arrivee.b,y_arrivee.b) 
      f_min.w=manhattan(x,y) 
      id_f_min.w=carte(x,y)\id 
      h_min.w=f_min 
      
      ;étape n°1 ajout de la case de départ à la liste ouverte 
      liste_ouverte(1)\id=carte(x,y)\id 
      liste_ouverte(1)\f=manhattan(x,y) 
      carte(x,y)\liste=#liste_open 
      
      ;étape n°2 boucle de recherche 
      fer_position.w=1 
      fer_position_premier_element=1 
      
      Repeat 
        
        ;étape n°2.a choix case en cours    
        x_temp.b=liste_ouverte(fer_position_premier_element)\id/24   ;x=id / y_max 
        y_temp.b=liste_ouverte(fer_position_premier_element)\id%24 ;y=id % y_max 
        
        ;étape n°2.b passage de la case en cours à la liste fermée 
        carte(x_temp,y_temp)\liste=#liste_closed 
        liste_ouverte(fer_position_premier_element)\f=0        
        fer_position_premier_element=fer_position_premier_element+1    
        Swap liste_ouverte(fer_position_premier_element)\f,liste_ouverte(fer_position)\f 
        Swap liste_ouverte(fer_position_premier_element)\id,liste_ouverte(fer_position)\id 
        reformer_tas(fer_position) 
        
        
        ;étape n°2.c  exploration des quatre cases adjacentes      
        exploration_case_adjacente(0,-1) 
        exploration_case_adjacente(1,0) 
        exploration_case_adjacente(0,1) 
        exploration_case_adjacente(-1,0) 
        
        ;sauvegarde du f_min de la carte au cas où il n'y ait pas de chemin possible 
        If  carte(x_temp,y_temp)\f>=f_min   And   h_min>manhattan(x_temp,y_temp) 
          f_min=carte(x_temp,y_temp)\f 
          id_f_min=carte(x_temp,y_temp)\id    
          h_min=manhattan(x_temp,y_temp) 
        EndIf 
        
      Until     carte(x_arrivee,y_arrivee)\liste=#liste_closed Or liste_ouverte(fer_position_premier_element)\f=0  
      
      ;3. enregistrement du chemin sous la forme d'une chaîne de caractères 
      ;3.a. cas où il y a un chemin 
      If x_temp=x_arrivee And y_temp=y_arrivee 
        PokeB( *fer_memoryID_x,carte(x_temp,y_temp)\id/24) 
        PokeB( *fer_memoryID_y,carte(x_temp,y_temp)\id%24) 
        fer_position_sauvegarde=0 
        Repeat  
        
          If fer_position_sauvegarde>200 
          animation_dragon_fer=0 
          dragon_fer_action=0 
            Break 
          EndIf 
          fer_position_sauvegarde=fer_position_sauvegarde+1 
          PokeB( *fer_memoryID_x+fer_position_sauvegarde,carte(x_temp,y_temp)\parent/24) 
          PokeB( *fer_memoryID_y+fer_position_sauvegarde,carte(x_temp,y_temp)\parent%24) 
          x_parent.b=carte(x_temp,y_temp)\parent/24 
          y_parent.b=carte(x_temp,y_temp)\parent%24 
          x_temp=x_parent 
          y_temp=y_parent    
        Until  carte(x_temp,y_temp)\parent=0  
        
        ;3.b. chemin le plus proche 
      Else 
        x_temp=id_f_min/24 
        y_temp=id_f_min%24 
        x_cible=x_temp 
        y_cible=y_temp 
        PokeB( *fer_memoryID_x,carte(x_temp,y_temp)\id/24) 
        PokeB( *fer_memoryID_y,carte(x_temp,y_temp)\id%24) 
        fer_position_sauvegarde=0 
        Repeat  
          If fer_position_sauvegarde>200 
          animation_dragon_fer=0 
          dragon_fer_action=0 
            Break 
          EndIf 
          fer_position_sauvegarde=fer_position_sauvegarde+1 
          PokeB( *fer_memoryID_x+fer_position_sauvegarde,carte(x_temp,y_temp)\parent/24) 
          PokeB( *fer_memoryID_y+fer_position_sauvegarde,carte(x_temp,y_temp)\parent%24) 
          x_parent=carte(x_temp,y_temp)\parent/24 
          y_parent=carte(x_temp,y_temp)\parent %24 
          x_temp=x_parent 
          y_temp=y_parent    
        Until  carte(x_temp,y_temp)\parent=0  
        
        
      EndIf 
      
      
    EndProcedure 
    
    Macro action_dragon_fer 
    If  dragon_fer_action=1 
      If ElapsedMilliseconds()-date_declenchement_pathfinding>delai_entre_deux_pathfinding And (tete_fer\x%32=0 And tete_fer\y%32=0) 
        date_declenchement_pathfinding=ElapsedMilliseconds() 
        animation_dragon_fer=1 
        x_cible=dragon_tete_x_anim/32 
        y_cible=dragon_tete_y_anim/32 
        
        
        preparer_pathfinding() 
        pathfinding(tete_fer\x/32,tete_fer\y/32,x_cible, y_cible) 
        tete_fer\x=PeekB(*fer_memoryID_x+fer_position_sauvegarde)*32 
        tete_fer\y=PeekB(*fer_memoryID_y+fer_position_sauvegarde)*32 
        tete_fer\dx=(PeekB(*fer_memoryID_x+fer_position_sauvegarde-1)-PeekB(*fer_memoryID_x+fer_position_sauvegarde))*tete_fer_dl 
        tete_fer\dy=(PeekB(*fer_memoryID_y+fer_position_sauvegarde-1)-PeekB(*fer_memoryID_y+fer_position_sauvegarde))*tete_fer_dl 
        
        AddElement(decision()) 
        decision()\x=tete_fer\x 
        decision()\y=tete_fer\y 
        decision()\dx=tete_fer\dx 
        decision()\dy=tete_fer\dy 
        
        choix_du_sprite_tete_fer() 
        
      EndIf 
      
      If  animation_dragon_fer=1 
        
        ;-la tête suit le chemin enregistré et laisse les informations pour le reste du corps 
        ;{ 
        If tete_fer\x=PeekB(*fer_memoryID_x+fer_position_sauvegarde)*32 And tete_fer\y=PeekB(*fer_memoryID_y+fer_position_sauvegarde)*32 And fer_position_sauvegarde>0 
          fer_dx_decision=(PeekB(*fer_memoryID_x+fer_position_sauvegarde-1)-PeekB(*fer_memoryID_x+fer_position_sauvegarde))*tete_fer_dl 
          fer_dy_decision=(PeekB(*fer_memoryID_y+fer_position_sauvegarde-1)-PeekB(*fer_memoryID_y+fer_position_sauvegarde))*tete_fer_dl 
          If fer_dx_decision<>tete_fer\dx Or fer_dy_decision<>tete_fer\dy 
            tete_fer\dx=fer_dx_decision 
            tete_fer\dy=fer_dy_decision 
            
            AddElement(decision()) 
            decision()\x=tete_fer\x 
            decision()\y=tete_fer\y 
            decision()\dx=tete_fer\dx 
            decision()\dy=tete_fer\dy 
            
            choix_du_sprite_tete_fer() 
            
          EndIf    
          fer_position_sauvegarde=fer_position_sauvegarde-1 
        EndIf 
        ;} 
        
        
        ;-lecture des informations laissées par la tête par le corps 
        ;{ 
        For i=0 To taille_dragon_fer 
          
          ForEach decision() 
            
            If dragon_fer(i)\x=decision()\x And dragon_fer(i)\y=decision()\y And dragon_fer(i)\numero_decision=ListIndex(decision()) 
              dragon_fer(i)\dx=decision()\dx 
              dragon_fer(i)\dy=decision()\dy 
              dragon_fer(i)\numero_decision=dragon_fer(i)\numero_decision+1 
            EndIf 
            
          Next 
          
        Next i 
        ;} 
        ;-mise à jour du compteur de décision quand la queue est passée 
        ;{ 
        If dragon_fer(0)\numero_decision=1 
          
          FirstElement(decision()) 
          DeleteElement(decision()) 
          For i=0 To taille_dragon_fer 
            dragon_fer(i)\numero_decision=dragon_fer(i)\numero_decision-1 
          Next i 
          
        EndIf 
        ;} 
        ;-animation du dragon_fer 
        ;{ 
        If ElapsedMilliseconds()-fer_temps_en_cours>delai_animation_dragon_fer 
          fer_temps_en_cours=ElapsedMilliseconds() 
          tete_fer\x=tete_fer\x+tete_fer\dx 
          tete_fer\y=tete_fer\y+tete_fer\dy 
          For i=0 To taille_dragon_fer 
            dragon_fer(i)\x=dragon_fer(i)\x+dragon_fer(i)\dx 
            dragon_fer(i)\y=dragon_fer(i)\y+dragon_fer(i)\dy 
          Next i 
        EndIf 
        ;} 
        ;-affichage des sprites 
        ;{ 
        
        For i=0 To taille_dragon_fer 
          ClipSprite(#spr_planche,dragon_fer(i)\spr_colonne,dragon_fer(i)\spr_ligne,16,16) 
          DisplaySprite(#spr_planche,dragon_fer(i)\x+fer_corps_decalage_x,dragon_fer(i)\y+fer_corps_decalage_y) 
        Next i 
        
        ClipSprite(#spr_planche,tete_fer_spr_colonne,tete_fer_spr_ligne,32,32) 
        DisplaySprite(#spr_planche,tete_fer\x,tete_fer\y) 
        
      EndIf 
    EndIf 
    
    EndMacro 
    
    ;-PROGRAMME PRINCIPAL 
    InitSprite() 
    InitKeyboard() 
    OpenWindow(0,0,0,1024,768,"Mémoire de dragon (flêche opposée au mouvement pour cracher les boules de feu déjà mangées ! (F1  fond d'écran | F2 graphismes)",#PB_Window_ScreenCentered|#PB_Window_SystemMenu  ) 
    OpenWindowedScreen(WindowID(0),0,0,1024,768,1,0,0) 
    
    ;variables utilisees pour le fond étoilé 
    ;******************************************* 
    Global x_win=WindowWidth(0) 
    Global y_win=WindowHeight(0) 
    Global EcranY=y_win 
    Global EcranX=x_win 
    ;******************************************** 
     UsePNGImageDecoder() 

    ;-police de caractères 
    LoadFont(0, "arial",  16) 
    LoadFont(1, "arial",  48) 
    ;-creation des etoiles (fond) 
    ;{ ; creation des etoiles (fond) 
    For Spritexx=1000 To 1000+nbspritefond 
      CreateSprite(Spritexx, 2, 2,0) 
      StartDrawing( SpriteOutput(Spritexx) )  
      Box(0, 0, 2, 2,RGB(Random(255)-150,Random(255)-150,Random(255)-150)) 
      StopDrawing() 
      fond_etoile(Spritexx)\x=32+Random(x_win-64) 
      fond_etoile(Spritexx)\Y=32+Random(y_win-64) 
    Next Spritexx 
    ;} 
    
    initialisation 
    
    ;-BOUCLE PRINCIPALE 
    Repeat 
      ;-gestion des évènements de la fenêtre 
      ;{ 
      Repeat 
        Event = WindowEvent()      
        If  Event = #PB_Event_CloseWindow 
          End 
        EndIf 
      Until Event = 0  
      ;} 
      
      ;-gestion du clavier    
      If ExamineKeyboard() 
        
        ;La touche droite du curseur est appuyée 
        ;{ 
        If KeyboardPushed(#PB_Key_Right)  And previous_dragon_dx<>1 And direction<>#PB_Key_Left  ; prise en compte de l'appui prolongé sur la touche et anti-retour 
          changement_direction_clavier(#PB_Key_Right,1,0,0,0,1,1,0,0,1,-1,0,1,0,4,1,2,2,0)          
        EndIf 
        ;} 
        ; La touche droite du curseur est appuyée 
        ;{ 
      ElseIf KeyboardPushed(#PB_Key_Down) And previous_dragon_dy<>1 And direction<>#PB_Key_Up  ; prise en compte de l'appui prolongé sur la touche et anti-retour 
        changement_direction_clavier(#PB_Key_Down,0,1,1,1,0,0,1,-1,0,0,1,0,1,1,1,2,1,0)          
      EndIf 
      ;} 
      ;La touche gauche du curseur est appuyée 
      ;{ 
    ElseIf KeyboardPushed(#PB_Key_Left)  And previous_dragon_dx<>-1 And direction<>#PB_Key_Right  ; prise en compte de l'appui prolongé sur la touche et anti-retour 
      changement_direction_clavier(#PB_Key_Left,-1,0,2,0,-1,1,0,0,-1,-1,0,-1,0,2,1,2,3,1)          
    EndIf 
    ;} 
    ;La touche haut du curseur est appuyée 
    ;{ 
  ElseIf KeyboardPushed(#PB_Key_Up) And previous_dragon_dy<>-1 And direction<>#PB_Key_Down  ; prise en compte de l'appui prolongé sur la touche et anti-retour 
    changement_direction_clavier(#PB_Key_Up,0,-1,3,1,0,0,-1,-1,0,0,-1,0,-1,3,1,2,3,2)          
  EndIf 
  ;} 
  ;sinon avancement automatique 
  ;{ 
  
Else 
  ;-animation de la queue 
  FirstElement(dragon()) 
  
  dragon_queue_dx=dragon()\dx 
  dragon_queue_dy=dragon()\dy 
  NextElement(dragon()) 
  coude=dragon()\coude ; pas d'animation si un coude arrive 
  
  ;-animation de la tête 
  LastElement(dragon()) 
  dragon_tete_fin_x_anim=dragon()\x+32*dragon()\dx 
  dragon_tete_fin_y_anim=dragon()\y+32*dragon()\dy 
  previous_dragon_dx=dragon()\dx 
  previous_dragon_dy=dragon()\dy 
  previous_dragon_colonne=dragon()\spr_colonne 
  
  If dragon_tete_x_anim<>dragon_tete_fin_x_anim Or dragon_tete_y_anim<>dragon_tete_fin_y_anim 
    If ElapsedMilliseconds()-temps_en_cours>delai_animation 
      temps_en_cours=ElapsedMilliseconds() 
      dragon_tete_x_anim=dragon_tete_x_anim+vitesse_dragon*dragon()\dx 
      dragon_tete_y_anim=dragon_tete_y_anim+vitesse_dragon*dragon()\dy 
      If coude=0 
        dragon_queue_x_anim=dragon_queue_x_anim+vitesse_dragon*dragon_queue_dx 
        dragon_queue_y_anim=dragon_queue_y_anim+vitesse_dragon*dragon_queue_dy 
      EndIf 
    EndIf 
    
  Else;-quand l'animation est terminée 
    AddElement(dragon()) 
    dragon()\x=dragon_tete_x_anim 
    dragon()\y=dragon_tete_y_anim 
    dragon()\dx=  previous_dragon_dx 
    dragon()\dy=  previous_dragon_dy 
    dragon()\spr_colonne=previous_dragon_colonne 
    
    manger 
    
    If manger_boule=0 
      FirstElement(dragon()) 
      NextElement(dragon());affectation des coordonnées à l'avant-dernier bout de queue car le dernier sera supprimé 
      dragon_queue_x_anim=dragon()\x 
      dragon_queue_y_anim=dragon()\y 
      FirstElement(dragon()) 
      DeleteElement(dragon())  
    Else 
      manger_boule=0 
    EndIf 
    
  EndIf 
  
EndIf 
      
      
EndIf 
    ;} 
    
        ;-tir de boules de feu 
        ;{ 
        ;tir de boule de feu à droite 
tir(#PB_Key_Left,previous_dragon_dx,1,#PB_Key_Right,dx) 
        ;tir de boule de feu à bas 
tir(#PB_Key_Up,previous_dragon_dy,1,#PB_Key_Down,dy) 
        ;tir de boule de feu à gauche 
tir(#PB_Key_Right,previous_dragon_dx,-1,#PB_Key_Left,dx) 
        ;tir de boule de feu à haut 
tir(#PB_Key_Down,previous_dragon_dy,-1,#PB_Key_Up,dy) 
        ;} 
    
    ;-choix du fond d'écran 
    ;{ 
If KeyboardReleased(#PB_Key_F1)  
  If  fond_d_ecran<5 
    fond_d_ecran=fond_d_ecran+1 
  Else 
    fond_d_ecran=0 
  EndIf 
  ClearList(dragon()) 
  ClearList(boule()) 
  ClearList(dragon_fixe()) 
  initialisation 
  dragon_fer_action=0 
EndIf 
    ;} 
    
      ;-choix de la planche de sprites
    ;{ 
If KeyboardReleased(#PB_Key_F2)  
planche=planche+1
If planche=2
planche=0
EndIf
  ClearList(dragon()) 
  ClearList(boule()) 
  ClearList(dragon_fixe()) 
  initialisation 
  dragon_fer_action=0 
EndIf 
    ;} 
  
    
    ;-affichage du décor 
    ;{ 
DisplaySprite(#spr_ecran,0,0) 
  
If fond_d_ecran=3 Or fond_d_ecran=4 Or fond_d_ecran=5 
  Gosub affiche_sprite_fond    
EndIf 
  
ForEach boule() 
  If boule()\projectile=1 And (boule()\x>16 Or  boule()\x<976 Or boule()\y>16 Or boule()\y<720) 
    boule()\x=boule()\x+boule()\dx 
    boule()\y=boule()\y+boule()\dy 
  EndIf 
  If boule()\projectile=1 And (boule()\x<16 Or  boule()\x>976 Or boule()\y<16 Or boule()\y>720) 
    DeleteElement(boule()) 
  EndIf 
  
  ClipSprite(#spr_planche,boule()\spr_colonne,boule()\spr_ligne,32,32) 
  DisplaySprite(#spr_planche,boule()\x,boule()\y) 
Next 
    ;-affichage périodique des boules et transformation en rocher 
If nombre_de_boules<660 
  If ElapsedMilliseconds()-date_creation_boule>duree_formation_boule 
    date_creation_boule=ElapsedMilliseconds() 
    
    Repeat 
      x_boule=(1+Random(29))*32 
      y_boule=(1+Random(21))*32 
    Until  carte(x_boule/32,y_boule/32)\decor=0 And (tete_fer\x/32<>x_boule/32 And tete_fer\y/32<>y_boule/32) And (dragon_tete_x_anim/32<>x_boule/32 And dragon_tete_y_anim/32<>y_boule/32)    
    AddElement(boule()) 
    boule()\x=x_boule 
    boule()\y=y_boule 
    tirage=Random(4) 
    If tirage=4 
      boule()\spr_colonne=0 
      boule()\spr_ligne=160 
    Else 
      boule()\spr_colonne=tirage*32 
      boule()\spr_ligne=128 
    EndIf 
    
    Select tirage 
      Case 0 
        boule()\type=#eau 
      Case 1 
        boule()\type=#air 
      Case 2 
        boule()\type=#terre 
      Case 3 
        boule()\type=#feu 
      Case 4 
        boule()\type=#ying_yang 
    EndSelect 
    
    boule()\date_de_creation=ElapsedMilliseconds() 
    carte(x_boule/32,y_boule/32)\decor=boule()\type 
    carte(x_boule/32,y_boule/32)\liste=#liste_mur 
    nombre_de_boules=nombre_de_boules+1 
  EndIf 
EndIf 
    
ForEach boule() 
  If boule()\type<>#roche And boule()\projectile=0 
    If ElapsedMilliseconds()-boule()\date_de_creation>duree_vie_boule 
      boule()\type=#roche 
      boule()\spr_colonne=32 
      boule()\spr_ligne=160 
      carte(boule()\x/32,boule()\y/32)\decor=#roche 
      carte(x_boule/32,y_boule/32)\liste=#liste_mur 
    EndIf 
  EndIf 
Next 
    ;} 
  
    ;-affichage du dragon 
    ;-affichage du tronc du dragon 
    ;{ 
ForEach dragon() 
  If dragon()\coude=0;affichage normal du corps si pas de coude 
    dragon()\spr_ligne=1;corps 
  EndIf    
  If ListIndex(dragon())<>0 
    ClipSprite(#spr_planche,dragon()\spr_colonne*32,dragon()\spr_ligne*32,32,32) 
    DisplaySprite(#spr_planche,dragon()\x,dragon()\y) 
  EndIf 
Next 
    ;} 
    ;-affichage de la tête et de la queue animées 
    ;{ 
    
    ;queue 
FirstElement(dragon()) 
dragon()\spr_ligne=3 
If dragon()\queue<>0;prise en compte des coudes car les sprites queues et coudes ne correspondent pas    
  If   dragon()\queue=4 
    dragon()\queue=0 
  EndIf 
  dragon()\spr_colonne=dragon()\queue 
EndIf 
    
ClipSprite(#spr_planche,dragon()\spr_colonne*32,dragon()\spr_ligne*32,32,32) 
DisplaySprite(#spr_planche,dragon_queue_x_anim,dragon_queue_y_anim) 
    
    ;tête 
LastElement(dragon()) 
dragon()\spr_ligne=0 
ClipSprite(#spr_planche,dragon()\spr_colonne*32,dragon()\spr_ligne*32,32,32) 
DisplaySprite(#spr_planche,dragon_tete_x_anim,dragon_tete_y_anim) 
    ;} 
    
action_dragon_fer 
    
    ;-collisions 
    ;{ 
    ;collisions dragon 
    
    ;-collision dragon_bordure 
If dragon_tete_x_anim<16 Or  dragon_tete_x_anim>976 Or dragon_tete_y_anim<16 Or dragon_tete_y_anim>720 
  StartDrawing(ScreenOutput()) 
  DrawingMode(#PB_2DDrawing_Transparent) 
  DrawingFont(FontID(1)) 
  DrawText(240,284,Str(boules_mangees)+" boule(s) mangée(s)",RGB(255,255,0)) 
  For i=1 To 100 
    Plot(dragon_tete_x_anim+Random(31),dragon_tete_y_anim+Random(31),RGB(255,0,0)) 
  Next i 
  StopDrawing() 
  FlipBuffers() 
  Delay(1200) 
  ClearList(dragon()) 
  ClearList(boule()) 
  ClearList(dragon_fixe()) 
  initialisation 
  dragon_fer_action=0 
EndIf 
    
    ;-collision dragon_dragon 
ForEach dragon() 
  If ListIndex(dragon())<>CountList(dragon())-1 
    If   dragon_tete_x_anim=dragon()\x And dragon_tete_y_anim=dragon()\y 
      StartDrawing(ScreenOutput()) 
      DrawingMode(#PB_2DDrawing_Transparent) 
      DrawingFont(FontID(1)) 
      DrawText(240,284,Str(boules_mangees)+" boule(s) mangée(s)",RGB(255,255,0)) 
      For i=1 To 100 
        Plot(dragon_tete_x_anim+Random(32),dragon_tete_y_anim+Random(32),RGB(255,0,0)) 
      Next i 
      StopDrawing() 
      FlipBuffers() 
      Delay(1200) 
      ClearList(dragon()) 
      ClearList(boule()) 
      ClearList(dragon_fixe()) 
      initialisation        
      dragon_fer_action=0 
    EndIf 
  EndIf 
Next 
  
  ;-collision dragon_dragon_fer 
ForEach dragon() 
  If tete_fer\x=dragon()\x And tete_fer\y=dragon()\y 
    StartDrawing(ScreenOutput()) 
    DrawingMode(#PB_2DDrawing_Transparent) 
    DrawingFont(FontID(1)) 
    DrawText(240,284,Str(boules_mangees)+" boule(s) mangée(s)",RGB(255,255,0)) 
    For i=1 To 50 
      Plot(dragon_tete_x_anim+Random(32),dragon_tete_y_anim+Random(32),RGB(255,0,0)) 
      Plot(tete_fer\x+Random(32),tete_fer\y+Random(32),RGB(255,0,0)) 
    Next i 
    StopDrawing() 
    FlipBuffers() 
    Delay(1200) 
    ClearList(dragon()) 
    ClearList(boule()) 
    ClearList(dragon_fixe()) 
    initialisation        
    dragon_fer_action=0 
    tete_fer\x=0 
    tete_fer\y=0 
    
  EndIf 
Next 
    
    ;-collision dragon_roche 
If carte(dragon_tete_x_anim/32,dragon_tete_y_anim/32)\decor=#roche 
  StartDrawing(ScreenOutput()) 
  DrawingMode(#PB_2DDrawing_Transparent) 
  DrawingFont(FontID(1)) 
  DrawText(240,284,Str(boules_mangees)+" boule(s) mangée(s)",RGB(255,255,0)) 
  For i=1 To 100 
    Plot(dragon_tete_x_anim+Random(32),dragon_tete_y_anim+Random(32),RGB(255,0,0)) 
  Next i 
  StopDrawing() 
  FlipBuffers() 
  Delay(1200) 
  ClearList(dragon()) 
  ClearList(boule()) 
  ClearList(dragon_fixe()) 
  initialisation 
  dragon_fer_action=0 
EndIf 
    
    ;-collision boule de feu_roche 
ForEach boule() 
  If boule()\projectile=1 
    If carte(boule()\x/32,boule()\y/32)\decor=#roche 
      carte(boule()\x/32,boule()\y/32)\decor=0 
      carte(boule()\x/32,boule()\y/32)\liste=0 
      x_roche=32*(boule()\x/32) 
      y_roche=32*(boule()\y/32) 
      DeleteElement(boule()) 
      Break 
    EndIf 
  EndIf 
Next 
ForEach boule() 
  If boule()\x=x_roche And  boule()\y=y_roche 
    DeleteElement(boule()) 
    Break 
  EndIf 
Next 
  
  ;-collision boule de feu_tête dragon fer 
ForEach boule() 
  If boule()\projectile=1 
    If boule()\x/32=tete_fer\x/32 And boule()\y/32=tete_fer\y/32 
      DeleteElement(boule()) 
      StartDrawing(ScreenOutput()) 
      For i=1 To 100 
        Plot(tete_fer\x+Random(32),tete_fer\y+Random(32),RGB(255,255,0)) 
      Next i 
      StopDrawing() 
      FlipBuffers() 
      Delay(100) 
      dragon_fer_action=0 
      tete_fer\x=0 
      tete_fer\y=0 
      Break 
    EndIf 
  EndIf 
Next 
    ;} 
    
Delay(10)  
    ;calcul du fps 
    ;{ 
    
If Second < ElapsedMilliseconds() 
  Second = ElapsedMilliseconds()+1000 
  fps = Frame_Counter 
  Frame_Counter = 0 
Else 
  Frame_Counter + 1 
EndIf      
StartDrawing(ScreenOutput()) 
DrawingMode(#PB_2DDrawing_Transparent) 
DrawingFont(FontID(0)) 
DrawText(60,4,Str(fps)+"                                                                        "+Str(boules_mangees),RGB(255,220,255)) 
StopDrawing() 
    ;} 
FlipBuffers() 
ForEver 
  
  ;{ ;********************** affiche_sprite_fond etoile: ******************************************** 
affiche_sprite_fond: 
          ;-affiche Fond etoilé 
For Spritexx1=1000 To 1000+nbspritefond-3 Step 1 
  DisplaySprite(Spritexx1,  fond_etoile(Spritexx1)\x,  fond_etoile(Spritexx1)\Y) 
  fond_etoile(Spritexx1)\Y= fond_etoile(Spritexx1)\Y+1 
  If  fond_etoile(Spritexx1)\Y>=EcranY-32 
    fond_etoile(Spritexx1)\Y=32 
  EndIf  
Next Spritexx1 
For Spritexx2=1002 To 1000+nbspritefond-3 Step 2 
  DisplaySprite(Spritexx2,  fond_etoile(Spritexx2)\x,  fond_etoile(Spritexx2)\Y) 
  fond_etoile(Spritexx2)\Y= fond_etoile(Spritexx2)\Y+2 
  If  fond_etoile(Spritexx2)\Y>=EcranY-32 
    fond_etoile(Spritexx2)\Y=32 
  EndIf 
Next Spritexx2 
For Spritexx3=1003 To 1000+nbspritefond-3 Step 3 
  DisplaySprite(Spritexx3,  fond_etoile(Spritexx3)\x,  fond_etoile(Spritexx3)\Y) 
  fond_etoile(Spritexx3)\Y= fond_etoile(Spritexx3)\Y+3 
  If  fond_etoile(Spritexx3)\Y>=EcranY-32 
    fond_etoile(Spritexx3)\Y=32 
  EndIf 
Next Spritexx3 
  
Return 
  ;} 
   ; IDE Options = PureBasic v4.02 (Windows - x86) 
  ; CursorPosition = 151 
  ; FirstLine = 135 
  ; Folding = HC0
Dites-moi si tout fonctionne correctement chez vous!
Si un testeur mange 1000 boules, c'est louche :roll: !

Merci d'avance

Hasta la vista!
Dernière modification par Huitbit le mar. 28/août/2007 19:37, modifié 36 fois.
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Re: Pure_Dragon (snake avec listes chaînées)

Message par beauregard »

:D

ça marche bien sur mon vieux PC, pas de souci donc. J'ai pris la liberté de modifier légèrement ton code, rendant le jeu moins difficile et peut être légèrement plus joli:

Code : Tout sélectionner

;auteur Huitbit

 Box(32,32,992,736,RGB(126,16,16));fond coloré

 For i=1 To 30
  For j=1 To 22
    If (i+j)%2=0
        regard=(i*4);-(j*5)
        Xregard=i*32:Yregard=j*32
        Box(Xregard,Yregard,32,32,RGB(regard+25 , regard , regard))
        Box(Xregard+2,Yregard+2,28,28,RGB(regard+25+25 , regard , regard))    
    EndIf
  Next j
Next i

 StopDrawing()


temps_formation_boule=1000*2
duree_vie_boule=10000*2
PS le tir fonctionne bien :D
Dernière modification par beauregard le sam. 04/août/2007 8:40, modifié 5 fois.
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Ajout d'une option

Message par Huitbit »

@beauregard
ça marche bien sur mon vieux PC
Ouf! :roll:
J'ai pris la liberté de modifier légèrement ton code, rendant le jeu moins difficile et plus joli:


No problemo, si j'ai mis le code sur le forum, c'est bien pour ça !

Pour diminuer la difficulté tu peux modifier les paramêtres dans la macro "initialisation"
(Attention vitesse_dragon doit être un diviseur de 32!)

Tu peux aussi jouer dans la macro "extraboule" pour rajouter des bonus !
:wink:
[EDIT]
RAJOUT DE LA FONCTION "PURGE SELECTIVE" (voir code du 1er post)
Des cercles colorés apparaissent en fonction de la nature des boules éliminées!
Dernière modification par Huitbit le jeu. 02/août/2007 11:39, modifié 1 fois.
Elevé au MSX !
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

cool j'aime bien les snakes moi :D

tout ce qui est oldschool d'une manière général :)

Cool le code :)
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

MAJ2(voir 1er post)+1 correction de bug

Message par Huitbit »

@Crystal Noir
Merci! (super idée ton Pure_Boulder :wink: Bon courage!)


Nouvelle option(voir 1er post) : supression des roches
Ca deviendra un peu plus facile!

un peu d'archéologie :lol:
[url]http://en.wikipedia.org/wiki/Snake_(video_game)[url]
Ce concept est trentenaire...

Des idées...
Des gentils à libérer, des méchants...
J'y pense :roll:
Question : les images du post ne s'affichent pas chez moi ! J'utilise le site de Heisspiter, depuis hier, ça ne marche plus. Des infos ?

Quels sites utilisez-vous pour poster les images ?
[EDIT] Dans la collision Dragon_bordure
Plot(dragon_tete_x_anim+Random(32),dragon_tete_y_anim+Random(32),RGB(255,0,0))
corrigé par:(voir 1er post)
Plot(dragon_tete_x_anim+Random(31),dragon_tete_y_anim+Random(31),RGB(255,0,0))
(sinon plot outside area dans certaines collisions à droite et en bas)

Merci d'avance!
Dernière modification par Huitbit le ven. 24/août/2007 5:01, modifié 1 fois.
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

MAJ3 tir de boules de feu

Message par Huitbit »

Hug!

Bon, maintenant le p'tit dragon peut casser des cailloux à coups de boules de feu (faut en manger avant bien sûr :wink: )

Comme le code commence à s'allonger, j'ai mis un peu d'ordre (ça facilite les choses).

IMPORTANT, dans le code ;{ et ;} ça permet de plier ou de déplier le code (merci forum :wink: )

Nouvelles structures, nouveaux noms de variables...
J'ai rajouté la macro "tir" (vive les MACROS :D)
(j'ai failli le faire pour les tests de direction mais j'ai manqué de courage vu le nombre de paramètres :oops: )
Pour l'affichage, j'ai tout mis après les tests clavier car des fois la mort sanglante du petit dragon manquait de réalisme (comme les italiens ou les argentins au foot (et même dans tout les sports!))

Pour le tir j'ai choisi la touche opposée au mouvement un peu contre mon gré.
Cette touche était libre car je la bloquais(fonction "anti-retour" car un dragon même très souple ne se mord pas le cou!)
A la base je voulais que ce soit la touche de direction correspondante (tir à droite>>>touche droite) mais ma séparation dans le temps du choix de la direction et du tir n'était pas satisfaisante (on pouvait tirer sans le vouloir!)

Si vous pouvez le tester SVP(tout ce que j'ai fait depuis l'animation du dragon, c'est au feeling(ça veut dire sans papier pour moi, c'est très dur psychologiquement, c'est pas sérieux, j'ai toujours besoin de papier d'habitude :lol: ), c'est pour ça que les tests de collision, le tir c'est un peu du bricolage(c'est la première fois que je fais ça :oops: )!

Au fait, pas de nouvelles de Heisspiter???



Merci d'avance

Hasta la vista!
Dernière modification par Huitbit le ven. 24/août/2007 5:40, modifié 1 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

.......
Dernière modification par Backup le mar. 19/août/2014 13:28, modifié 1 fois.
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Wahou, c'est Las Vegas !

Message par Huitbit »

On dirait un vrai jeu :lol: :lol:
Dès que je peux, je vais mettre un menu qui laisse le choix du fond d'écran ("Beauregard", "Dobro", pas de fond d'écran).

@Dobro
;ceci est un commentaire
;- ceci est un signet cliquable (voir petite fenêtre a cote de l'éditeur)
Super, encore un truc pour s'y retrouver plus facilement dans le programme :P

Pour ton fond étoilé, je laisserai le choix du nombre d'étoiles car chez moi le fps tombe à 28 (normalement, le programme tourne à 60~61 c'est à dire la valeur maximale pour mon ordinateur :oops: quelque soit le code qui contient un delay(1)!(d'aillleurs, c'est pour ça qu'il y a 0 optimisation pour l'instant dans mon code!!))
Avec 500 étoiles, je remonte à 38~40!

Hasta la vista!
Elevé au MSX !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Wahou, c'est Las Vegas !

Message par Backup »

Huitbit a écrit :chez moi le fps tombe à 28 (normalement, le programme tourne à 60~61 c'est à dire la valeur maximale pour mon ordinateur :oops:
t'as un ordi en Carton :lol:
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Re: Wahou, c'est Las Vegas !

Message par beauregard »

Dobro a écrit :
Huitbit a écrit :chez moi le fps tombe à 28 (normalement, le programme tourne à 60~61 c'est à dire la valeur maximale pour mon ordinateur :oops:
t'as un ordi en Carton :lol:
je fais plus fort sur mon PC née en 2002: fps à 22. L'utilisation de sprites3D pourrait être la solution. D'ailleurs, c'est pour cela que j'ai apporté une correction de dernière minute sur Peur Basique, qui était parfaitement fluide sur mon PC récent, mais ralentissait grave sur l'ancien. Et c'est pourquoi j'ai tout mis en sprite3D.
A ce propos Huitbit, dis nous à combien monte le fps à Peur Basique, et nous serons ainsi fixé...
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Message par beauregard »

ajout d'un petit fond etoilé :D (celui de mon casse brique "PureNoide2") :D
Je viens de jouer à PureNoide et PureNoide2 :D ( un casse brique enfin doté d'une belle musique) et j'ai constaté de gros progrès. Si jamais tu développe un 3ème volet, fais le nous savoir, et si tu le souhaite je te ferai des suggestions par l'intermédiaire de message privé.

J'ai remarqué que dans PureNoide2 il n'y a pas de fichiers associés, alors j'ai essayé de faire la même chose pour Mémoire de Dragon:
après la partie enumeration que voilà:

Code : Tout sélectionner

Enumeration
  #spr_planche
  #spr_ecran
  #roche
  #eau
  #air
  #terre
  #feu
  #ying_yang
EndEnumeration
j'ai écrit:

Code : Tout sélectionner

CatchImage(#spr_planche, ?01)
et j'ai cru bon de désactiver le chargement de l'image:

Code : Tout sélectionner

;LoadSprite(#spr_planche,"planche_mdd.png")

Et à la fin du code:

Code : Tout sélectionner

DataSection
01:IncludeBinary "planche_mdd.png"
EndDataSection 
l'exécutable fonctionne, mais les images sont aux abonnées absente, où est donc la fausse note ?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

il faut inclure ton fichier !!

en mode devellopement ton prg doit fonctionner normalement

mais lorsque tu vas creer un executable
tes sprites seront integré au prg !! :D

voir


id_balle_1= CatchImage ( #balle_1 , ?ball1)
   End

   DataSection
  ball1:
        IncludeBinary chemin$+ "balle_1.bmp"
   EndDataSection



ensuite tu as ton image chargé, tu n'as plus qu'a faire un createsprite


CreateSprite ( #balle_1 , 32, 32,0)
         StartDrawing ( SpriteOutput ( #balle_1 ) )
         DrawImage (id_balle_1, 0, 0 )
    StopDrawing ()
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

Hello!

Je savais pô qu'on avait droit au Fps pour Peur basique!
Finalement en regardant le code :"F">>>>fps, élémentaire!
Sur mon pentium VIII à 57 teraHertz fps=59
C'est à dire quasiment le maximum pour moi!

Inclure les fichiers, ça m'intéresse !
Le moment venu, faudra que je me penche sur le problème (j'avais regardé la fonction include dans l'aide mais ça na rien donné et j'ai eu la flemme d'aller chercher des exemples sur le forum :? ).


@Beauregard
un casse brique enfin doté d'une belle musique
Ce n'est que la face cachée de l'iceberg, n'est-ce pas M. Dobro de Lucia :wink:


Vous avez-vu, les images sont revenues!

Un exemple de méchant que je compte faire : un dragon à vapeur, moche et méchant!

Hasta la vista!
Elevé au MSX !
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

me résiste

Message par beauregard »

Dobro a écrit :il faut inclure ton fichier !!
heu, comme j'y arrive toujours pas, j'ai repris un de tes codes, en apportant quelques modifications, mais l'image ne s'affiche toujours pas, et à la place on a droit a un rectangle tristement sombre:

Code : Tout sélectionner

 #dobro  =1
#Police =1

Enumeration
  #spr_planche
  #spr_ecran
  #roche
  #eau
  #air
  #terre
  #feu
  #ying_yang
EndEnumeration
;-catch
id_spr_planche=CatchImage(#spr_planche, ?01) 

InitKeyboard () : ; j'espere qu'il y a un clavier au moins !!


; ***********************************
Resultat = InitSprite ()
FontID = LoadFont ( #Police , "arial" , 18, #PB_Font_Bold )
EcranX = GetSystemMetrics_ ( #SM_CXSCREEN ): ;=largeur de l'ecran
EcranY = GetSystemMetrics_ ( #SM_CYSCREEN ): ;=hauteur de l'ecran
  WindowID = OpenWindow (1, 0, 0,800, 600, "hello" , #PB_Window_SystemMenu|#PB_Window_BorderLess |#PB_Window_ScreenCentered )
  
  Result = OpenWindowedScreen ( WindowID (1),0,0, 800,600, 1, 0,0)
  
  x_sprite=EcranX/2 ; on centre les coordonées du sprite
  y_sprite=EcranY/2-250 ; on centre les coordonées du sprite

  ;- ******* creation d'un sprite ************
If CreateSprite   (  #spr_planche  , 128, 192, 0)
   StartDrawing ( SpriteOutput ( #spr_planche ) )
    DrawImage (id_spr_planche, 0, 0 )
   StopDrawing () 
EndIf
  
  Repeat
    
    Event= WindowEvent ()
    Delay (2)
    ExamineKeyboard ()
    
    If KeyboardPushed ( #PB_Key_Up ) ; press touche haut
      Debug "press touche haut"
      y_sprite= y_sprite-1
    EndIf
    If KeyboardPushed ( #PB_Key_Down ) ; press touche bas
      Debug " press touche bas"
      y_sprite= y_sprite+1
    EndIf
    If KeyboardPushed ( #PB_Key_Left ) ; press touche gauche
      Debug " press touche gauche"
      x_sprite= x_sprite-1
    EndIf
    If KeyboardPushed ( #PB_Key_Right ) ; press touche droit
      Debug " press touche droit"
      x_sprite= x_sprite+1
    EndIf
 
    StartDrawing ( ScreenOutput ()) ; on va ecrire dans le fond de l'ecran
    Resultat = DrawText (50, 50, "appuyez sur les touches flechées" , RGB (255,255,0), RGB (0,0,0) )
    Resultat = DrawText (50, 150, "pour faire bouger le sprite" , RGB (255,255,0), RGB (0,0,0) )
    StopDrawing ()
    
 ;- affiche le sprite au coordonées modifié par les touches
    DisplaySprite (#spr_planche, x_sprite, y_sprite) 
    
    FlipBuffers (): ; affiche l'ecran
    ClearScreen ( RGB (100, 0, 0)) : ;efface l'ecran
    
  Until Event= #PB_Event_CloseWindow Or KeyboardPushed ( #PB_Key_Escape ) ; press touche droit
   ;-includeBinary
  DataSection
  01: IncludeBinary "planche_mdd.png"
  EndDataSection  
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

la puissance n'est rien sans controle

Message par beauregard »

Huitbit a écrit :Hello!
Je savais pô qu'on avait droit au Fps pour Peur basique!
Finalement en regardant le code :"F">>>>fps, élémentaire!
Sur mon pentium VIII à 57 teraHertz fps=59
C'est à dire quasiment le maximum pour moi!
Conclusion: ta modeste machine rame si on programme avec des sprite classique, a tel point que tu songeai peut être économiser pour en changer. Mais en réalité elle est largement sous exploitée, et en utilisant les sprite3D, tu ne la quittera jamais.

Non, jamais !*. ;)

*y peuvent se les garder leur quadricoeur machin, et leur sli-gogo-force9turbo-gtu.
Répondre