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

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
et (Cpl Bator'style)

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
Si un testeur mange 1000 boules, c'est louche

Merci d'avance
Hasta la vista!