Hugh !
J'ai rajouté une liste chaînée pour sauvegarder les actions effectuées.
Barre d'espace pour "remonter le temps"
Return pour recommencer le niveau
J'ai mis un 3ème niveau (23ème niveau du jeu original).
Pour la version sonore, il faudra trouver une troisième musique !
Planche de sprites à charger et à mettre dans le même dossier que le code :
Version sans le son (celle que tout le monde préfère

)
Code : Tout sélectionner
;sokoban avec annulation des actions et reset
;auteur Huitbit
;amélioration des déplacements par Le Soldat Inconnu
;pb v4.41
;une partie des sprites est tirée du site ci-dessous
;http://www.brothersoft.com/games/soukoban.html
;*********************************
;-___________________________________
;-déclaration des variables et des constantes
;-___________________________________
;-L'énumération permet de travailler avec des noms plutôt qu'avec des chiffres
Enumeration
#spr_planche
#mur
#sol
#but
#caisse
#caisse_rouge
#soko1
#soko2
#eau
#spr_decor
#action_caisse_vers_sol
#action_caisse_vers_but
#action_caisserouge_vers_sol
#action_caisserouge_vers_but
EndEnumeration
;-déclaration des variables
niveau.b;numéro du niveau
musique.b
largeur_niveau.b
hauteur_niveau.b
y.b;variable utilisée pour les lignes du tableau
x.b;variable utilisée pour les colonnes du tableau
type_tuile.b;variable utilisée pour le contenu de la case du tableau
nbre_caisses.b
compteur.b;permet de vérifier si les caisses sont rangées
x_soko.b;colonne où se trouve le personnage
y_soko.b;ligne où se trouve le personnage
soko.b;sprite choisi pour le personnage, soit #soko1, soit #soko2
chrono_soko.i; variable utilisée pour temporiser l'animation du personnage
chrono_keyboard.i;variable utilisée pour temporiser la fonction KeyboardPushed()
largeur_ecran.i
hauteur_ecran.i
x_clip_eau.i;variable utilisée pour découper le sprite "planche" pixel par pixel au niveau de l'eau
chrono_eau.i; variable utilisée pour temporiser l'animation de l'eau
;-_____________________________________________
;-structure utilisée pour la liste chaînée
Structure infos_action
varx.b
vary.b
action.i
EndStructure
;- Cette macro "clavier", permet en une seule fois de gérer les quatre directions,
;-il suffit de l'appeler en changeant les valeurs des paramètres direction, dx et dy.
Macro clavier(dx,dy)
;-si la place est libre devant, on avance dans la direction choisie
If carte(x_soko+dx,y_soko+dy)=#sol Or carte(x_soko+dx,y_soko+dy)=#but
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=0
;-s'il y a une caisse
ElseIf carte(x_soko+dx,y_soko+dy)=#caisse
;-si la place est libre devant la caisse, on peut la pousser
If carte(x_soko+2*dx,y_soko+2*dy)=#sol
carte(x_soko+dx,y_soko+dy)=#sol
carte(x_soko+2*dx,y_soko+2*dy)=#caisse
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=#action_caisse_vers_sol
;-si la place libre devant la caisse est un point d'arrivée, on bouge la caisse et on l'affiche en rouge
ElseIf carte(x_soko+2*dx,y_soko+2*dy)=#but
carte(x_soko+dx,y_soko+dy)=#sol
carte(x_soko+2*dx,y_soko+2*dy)=#caisse_rouge
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=#action_caisse_vers_but
EndIf
;-si la caisse poussée est rouge
ElseIf carte(x_soko+dx,y_soko+dy)=#caisse_rouge
;-si on la déplace, on fera apparaître une case arrivée et elle redeviendra de couleur normale
If carte(x_soko+2*dx,y_soko+2*dy)=#sol
carte(x_soko+dx,y_soko+dy)=#but
carte(x_soko+2*dx,y_soko+2*dy)=#caisse
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=#action_caisserouge_vers_sol
;-si on la déplace on fera apparaître une case arrivée et elle restera rouge
ElseIf carte(x_soko+2*dx,y_soko+2*dy)=#but
carte(x_soko+dx,y_soko+dy)=#but
carte(x_soko+2*dx,y_soko+2*dy)=#caisse_rouge
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=#action_caisserouge_vers_but
EndIf
EndIf
EndMacro
;-on prévient le compilateur que l'on va utiliser les sprites et le clavier
InitSprite()
InitKeyboard()
InitSound()
;-on choisit le niveau de départ
niveau=1
MessageRequester("Infos !", ">Barre d'espace : annuler une action."+Chr(13)+">Return : réinitialiser le niveau"+Chr(13)+Chr(13)+"Attention, le niveau 3 ça devient sérieux !")
;-"jeu:" s'appelle un label, c'est une adresse, un numéro de ligne où l'on peut renvoyer le programme
jeu:
;-création d'une liste chaînée sauvegarde_actions() pour pouvoir revenir en arrière dans le jeu
NewList sauvegarde_actions.infos_action()
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=0
sauvegarde_actions()\vary=0
sauvegarde_actions()\action=0
;-en fonction du niveau, on se place au bon endroit pour lire les informations correspondantes
Select niveau
Case 1
Restore niveau1
Case 2
Restore niveau2
Case 3
Restore niveau3
EndSelect
;-lecture des dimensions (en nombre de cases) de la zone de jeu
Read.b largeur_niveau
Read.b hauteur_niveau
;-transformation des dimensions en nombre de pixels, sachant que chaque image fait 32 pixels
largeur_ecran=(largeur_niveau+1)*32
hauteur_ecran=(hauteur_niveau+1)*32
;-lecture du nombre de caisses
Read.b nbre_caisses
;-création du tableau pour y ranger toutes les informations
Dim carte.b(largeur_niveau,hauteur_niveau)
;-utilisation de deux boucles pour remplir le tableau
For y=0 To hauteur_niveau
For x=0 To largeur_niveau
;-lecture des data
Read.b type_tuile
carte(x,y)=type_tuile
;-récupération des coordonnées de départ du personnage
If type_tuile=#soko1
x_soko=x
y_soko=y
carte(x,y)=#sol
EndIf
Next x
Next y
;-______________________
;-PROGRAMME PRINCIPAL
;-______________________
OpenWindow(0,0,0,largeur_ecran,hauteur_ecran,"Sokoban niveau "+Str(niveau),#PB_Window_ScreenCentered|#PB_Window_SystemMenu )
OpenWindowedScreen(WindowID(0),0,0,largeur_ecran,hauteur_ecran,0,0,0)
;-on précise le type d'image utilisée
UsePNGImageDecoder()
;-on charge l'image de taille 352*32 pixels
;-Remarque : j'ai choisi une image où tous les sprites sont présents, dans la suite du programme, je la "découpe" avec clipsprite() en fonction de mes besoins.
;-j'aurais pu charger plusieurs images pour ne pas avoir à utiliser ClipSprite() !
LoadSprite(#spr_planche,"planche.png")
;-on dessine le décor (c'est dire, tout ce qui est immobile) en utilisant les sprites et les informations du tableau carte(x,y)
ClearScreen(RGB(0,0,0))
For y=0 To hauteur_niveau
For x=0 To largeur_niveau
If carte(x,y)>0;quand carte(x,y)=0, on affiche rien
If carte(x,y)<4;affichage des murs et du sol, caisses, soko,eau non affichés
ClipSprite(#spr_planche,(carte(x,y)-1)*32,0,32,32)
DisplaySprite(#spr_planche,x*32,y*32)
Else;si carte(x,y) supérieur ou égal à 4 on affiche le sol à la place
If carte(x,y)=5;caisse rouge, on affiche donc une case arrivée à la place
ClipSprite(#spr_planche,(#but-1)*32,0,32,32)
DisplaySprite(#spr_planche,x*32,y*32)
Else
ClipSprite(#spr_planche,(#sol-1)*32,0,32,32)
DisplaySprite(#spr_planche,x*32,y*32)
EndIf
EndIf
EndIf
Next x
Next y
;-on prend une "photo" du sprite crée et on l'appelle #spr_decor
GrabSprite(#spr_decor,0,0,largeur_ecran,hauteur_ecran)
;-choix de l'image de départ du personnage "soko"
soko=#soko1
;-choix de l'abscisse de départ de l'image "eau"
x_clip_eau=(#eau-1)*32
;-_________________________________
;-BOUCLE PRINCIPALE
;-_________________________________
Repeat
FlipBuffers() ;voir l'aide pour cette fonction
;-on affiche le décor
DisplaySprite(#spr_decor,0,0)
;-on affiche les éléments restants
For y=0 To hauteur_niveau
For x=0 To largeur_niveau
;-affichage des caisses
If carte(x,y)=#caisse Or carte(x,y)=#caisse_rouge
ClipSprite(#spr_planche,(carte(x,y)-1)*32,0,32,32)
DisplaySprite(#spr_planche,x*32,y*32)
EndIf
;-cas de l'eau
If carte(x,y)=#eau
;-animation de l'eau
If ElapsedMilliseconds()-chrono_eau>60
chrono_eau=ElapsedMilliseconds()
x_clip_eau=x_clip_eau+1
If x_clip_eau>(#eau-1+3)*32
x_clip_eau=(#eau-1)*32
EndIf
EndIf
;-affichage de l'eau
ClipSprite(#spr_planche,x_clip_eau,0,32,32)
DisplayTranslucentSprite(#spr_planche,x*32,y*32,128)
EndIf
;-enlevez les points virgules et vous verrez !
; StartDrawing(ScreenOutput())
; DrawText(x*32,y*32,Str(carte(x,y)))
; StopDrawing()
Next x
Next y
;-animation du personnage
If ElapsedMilliseconds()-chrono_soko>500
chrono_soko=ElapsedMilliseconds()
soko=soko+1
;-test pour revenir à la première image
If soko>#soko2
soko=#soko1
EndIf
EndIf
;-affichage du personnage
ClipSprite(#spr_planche,(soko-1)*32,0,32,32)
DisplaySprite(#spr_planche,x_soko*32,y_soko*32)
;-vérification du nombre de caisses placées
compteur=0
For y=0 To hauteur_niveau
For x=0 To largeur_niveau
If carte(x,y)=#caisse_rouge
compteur=compteur+1
If compteur=nbre_caisses
Flipbuffers()
MessageRequester("Victoire !",Str(nbre_caisses)+" caisses rangées")
;-passage au niiveau suivant
niveau=niveau+1
If niveau=4
niveau=1
EndIf
;-retour au label "jeu:"
Goto jeu
EndIf
EndIf
Next x
Next y
;-gestion du clavier
If ElapsedMilliseconds()-chrono_keyboard>200
ExamineKeyboard()
;-appel de la macro clavier
If KeyboardPushed(#PB_Key_Right)
clavier(1, 0)
chrono_keyboard=ElapsedMilliseconds()
EndIf
If KeyboardPushed(#PB_Key_Left)
clavier(-1, 0)
chrono_keyboard=ElapsedMilliseconds()
EndIf
If KeyboardPushed(#PB_Key_Down)
clavier(0, 1)
chrono_keyboard=ElapsedMilliseconds()
EndIf
If KeyboardPushed(#PB_Key_Up)
clavier(0, -1)
chrono_keyboard=ElapsedMilliseconds()
EndIf
EndIf
If KeyboardReleased(#PB_Key_Space)
If ListIndex(sauvegarde_actions())<>0
x_soko=x_soko-sauvegarde_actions()\varx
y_soko=y_soko-sauvegarde_actions()\vary
Select sauvegarde_actions()\action
Case 0
DeleteElement(sauvegarde_actions())
Case #action_caisse_vers_sol
carte(x_soko+sauvegarde_actions()\varx,y_soko+sauvegarde_actions()\vary)=#caisse
carte(x_soko+2*sauvegarde_actions()\varx,y_soko+2*sauvegarde_actions()\vary)=#sol
DeleteElement(sauvegarde_actions())
Case #action_caisse_vers_but
carte(x_soko+sauvegarde_actions()\varx,y_soko+sauvegarde_actions()\vary)=#caisse
carte(x_soko+2*sauvegarde_actions()\varx,y_soko+2*sauvegarde_actions()\vary)=#but
DeleteElement(sauvegarde_actions())
Case #action_caisserouge_vers_sol
carte(x_soko+sauvegarde_actions()\varx,y_soko+sauvegarde_actions()\vary)=#caisse_rouge
carte(x_soko+2*sauvegarde_actions()\varx,y_soko+2*sauvegarde_actions()\vary)=#sol
DeleteElement(sauvegarde_actions())
Case #action_caisserouge_vers_but
carte(x_soko+sauvegarde_actions()\varx,y_soko+sauvegarde_actions()\vary)=#caisse_rouge
carte(x_soko+2*sauvegarde_actions()\varx,y_soko+2*sauvegarde_actions()\vary)=#but
DeleteElement(sauvegarde_actions())
EndSelect
EndIf
EndIf
If KeyboardReleased(#PB_Key_Return)
Goto jeu
EndIf
Delay(10)
Until WindowEvent() = #PB_Event_CloseWindow
End
;-____________________________
;-FIN DU PROGRAMME PRINCIPAL
;-____________________________
;-____________________________
;-DONNEES SUR LES NIVEAUX
;-____________________________
DataSection
;mur=1;sol=2;but=3;caisse=4;caisse_rouge=5;soko1=6;soko2=7;eau=8
niveau1:
Data.b 9,7,3;dimensions 10*8; 3 caisses
Data.b 1,1,1,1,1,0,0,0,0,0
Data.b 1,2,2,6,1,0,0,0,0,0
Data.b 1,2,2,2,1,1,0,0,0,0
Data.b 1,2,4,2,2,1,1,1,1,1
Data.b 1,2,4,2,4,2,2,8,8,1
Data.b 1,1,1,2,2,2,2,3,8,1
Data.b 8,8,1,2,2,2,3,3,2,1
Data.b 8,8,1,1,1,1,1,1,1,1
;mur=1;sol=2;but=3;caisse=4;caisse_rouge=5;soko1=6;soko2=7;eau=8
niveau2:
Data.b 11,5,4 ;dimensions 12*6; 4 caisses
Data.b 1,1,1,1,1,1,1,1,1,1,1,1
Data.b 1,8,1,8,1,8,8,2,8,2,8,1
Data.b 1,6,2,2,2,2,8,2,2,2,8,1
Data.b 1,2,4,4,2,2,4,2,4,2,2,1
Data.b 1,2,3,2,3,2,3,2,3,2,2,1
Data.b 1,1,1,1,1,1,1,1,1,1,1,1
;mur=1;sol=2;but=3;caisse=4;caisse_rouge=5;soko1=6;soko2=7;eau=8
niveau3:
Data.b 8,6,6; dimensions 9*7; 6 caisses
Data.b 8,1,1,1,1,1,8,8,8
Data.b 8,1,2,2,2,1,1,1,1
Data.b 1,1,2,1,4,2,2,2,1
Data.b 1,2,4,2,2,4,4,2,1
Data.b 1,2,1,4,1,3,5,3,1
Data.b 1,2,2,2,6,3,3,3,1
Data.b 1,1,1,1,1,1,1,1,1
EndDataSection
Version avec le son :
Code : Tout sélectionner
;sokoban avec son, annulation des actions et reset
;auteur Huitbit
;amélioration des déplacements par Le Soldat Inconnu
;pb v4.41
;une partie des sprites est tirée du site ci-dessous
;http://www.brothersoft.com/games/soukoban.html
;*********************************
;-___________________________________
;-déclaration des variables et des constantes
;-___________________________________
;-L'énumération permet de travailler avec des noms plutôt qu'avec des chiffres
Enumeration
#spr_planche
#mur
#sol
#but
#caisse
#caisse_rouge
#soko1
#soko2
#eau
#spr_decor
#son_caisse_poussee
#action_caisse_vers_sol
#action_caisse_vers_but
#action_caisserouge_vers_sol
#action_caisserouge_vers_but
EndEnumeration
;-déclaration des variables
niveau.b;numéro du niveau
musique.b
largeur_niveau.b
hauteur_niveau.b
y.b;variable utilisée pour les lignes du tableau
x.b;variable utilisée pour les colonnes du tableau
type_tuile.b;variable utilisée pour le contenu de la case du tableau
nbre_caisses.b
compteur.b;permet de vérifier si les caisses sont rangées
x_soko.b;colonne où se trouve le personnage
y_soko.b;ligne où se trouve le personnage
soko.b;sprite choisi pour le personnage, soit #soko1, soit #soko2
chrono_soko.i; variable utilisée pour temporiser l'animation du personnage
chrono_keyboard.i;variable utilisée pour temporiser la fonction KeyboardPushed()
largeur_ecran.i
hauteur_ecran.i
x_clip_eau.i;variable utilisée pour découper le sprite "planche" pixel par pixel au niveau de l'eau
chrono_eau.i; variable utilisée pour temporiser l'animation de l'eau
;-_____________________________________________
;-structure utilisée pour la liste chaînée
Structure infos_action
varx.b
vary.b
action.i
EndStructure
;- Cette macro "clavier", permet en une seule fois de gérer les quatre directions,
;-il suffit de l'appeler en changeant les valeurs des paramètres direction, dx et dy.
Macro clavier(dx,dy)
;-si la place est libre devant, on avance dans la direction choisie
If carte(x_soko+dx,y_soko+dy)=#sol Or carte(x_soko+dx,y_soko+dy)=#but
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=0
;-s'il y a une caisse
ElseIf carte(x_soko+dx,y_soko+dy)=#caisse
;-si la place est libre devant la caisse, on peut la pousser
If carte(x_soko+2*dx,y_soko+2*dy)=#sol
carte(x_soko+dx,y_soko+dy)=#sol
carte(x_soko+2*dx,y_soko+2*dy)=#caisse
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=#action_caisse_vers_sol
PlaySound(#son_caisse_poussee)
;-si la place libre devant la caisse est un point d'arrivée, on bouge la caisse et on l'affiche en rouge
ElseIf carte(x_soko+2*dx,y_soko+2*dy)=#but
carte(x_soko+dx,y_soko+dy)=#sol
carte(x_soko+2*dx,y_soko+2*dy)=#caisse_rouge
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=#action_caisse_vers_but
PlaySound(#son_caisse_poussee)
EndIf
;-si la caisse poussée est rouge
ElseIf carte(x_soko+dx,y_soko+dy)=#caisse_rouge
;-si on la déplace, on fera apparaître une case arrivée et elle redeviendra de couleur normale
If carte(x_soko+2*dx,y_soko+2*dy)=#sol
carte(x_soko+dx,y_soko+dy)=#but
carte(x_soko+2*dx,y_soko+2*dy)=#caisse
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=#action_caisserouge_vers_sol
PlaySound(#son_caisse_poussee)
;-si on la déplace on fera apparaître une case arrivée et elle restera rouge
ElseIf carte(x_soko+2*dx,y_soko+2*dy)=#but
carte(x_soko+dx,y_soko+dy)=#but
carte(x_soko+2*dx,y_soko+2*dy)=#caisse_rouge
x_soko=x_soko+dx
y_soko=y_soko+dy
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=dx
sauvegarde_actions()\vary=dy
sauvegarde_actions()\action=#action_caisserouge_vers_but
PlaySound(#son_caisse_poussee)
EndIf
EndIf
EndMacro
;-on prévient le compilateur que l'on va utiliser les sprites et le clavier
InitSprite()
InitKeyboard()
InitSound()
;-on charge le son et les musiques
LoadSound(#son_caisse_poussee,"son_caisse_poussee.wav")
LoadSound(1,"musique1.wav")
LoadSound(2,"musique2.wav")
LoadSound(3,"musique3.wav")
;-on choisit le niveau de départ
niveau=1
MessageRequester("Infos !", ">Barre d'espace : annuler une action."+Chr(13)+">Return : réinitialiser le niveau"+Chr(13)+Chr(13)+"Attention, le niveau 3 ça devient sérieux !")
;-"jeu:" s'appelle un label, c'est une adresse, un numéro de ligne où l'on peut renvoyer le programme
jeu:
;-création d'une liste chaînée sauvegarde_actions() pour pouvoir revenir en arrière dans le jeu
NewList sauvegarde_actions.infos_action()
AddElement(sauvegarde_actions())
sauvegarde_actions()\varx=0
sauvegarde_actions()\vary=0
sauvegarde_actions()\action=0
;-en fonction du niveau, on se place au bon endroit pour lire les informations correspondantes
Select niveau
Case 1
Restore niveau1
Case 2
Restore niveau2
Case 3
Restore niveau3
EndSelect
;-lecture et lancement de la musique de fond
Read.b musique
PlaySound(musique,#PB_Sound_Loop)
SoundVolume(musique,70)
;-lecture des dimensions (en nombre de cases) de la zone de jeu
Read.b largeur_niveau
Read.b hauteur_niveau
;-transformation des dimensions en nombre de pixels, sachant que chaque image fait 32 pixels
largeur_ecran=(largeur_niveau+1)*32
hauteur_ecran=(hauteur_niveau+1)*32
;-lecture du nombre de caisses
Read.b nbre_caisses
;-création du tableau pour y ranger toutes les informations
Dim carte.b(largeur_niveau,hauteur_niveau)
;-utilisation de deux boucles pour remplir le tableau
For y=0 To hauteur_niveau
For x=0 To largeur_niveau
;-lecture des data
Read.b type_tuile
carte(x,y)=type_tuile
;-récupération des coordonnées de départ du personnage
If type_tuile=#soko1
x_soko=x
y_soko=y
carte(x,y)=#sol
EndIf
Next x
Next y
;-______________________
;-PROGRAMME PRINCIPAL
;-______________________
OpenWindow(0,0,0,largeur_ecran,hauteur_ecran,"Sokoban niveau "+Str(niveau),#PB_Window_ScreenCentered|#PB_Window_SystemMenu )
OpenWindowedScreen(WindowID(0),0,0,largeur_ecran,hauteur_ecran,0,0,0)
;-on précise le type d'image utilisée
UsePNGImageDecoder()
;-on charge l'image de taille 352*32 pixels
;-Remarque : j'ai choisi une image où tous les sprites sont présents, dans la suite du programme, je la "découpe" avec clipsprite() en fonction de mes besoins.
;-j'aurais pu charger plusieurs images pour ne pas avoir à utiliser ClipSprite() !
LoadSprite(#spr_planche,"planche.png")
;-on dessine le décor (c'est dire, tout ce qui est immobile) en utilisant les sprites et les informations du tableau carte(x,y)
ClearScreen(RGB(0,0,0))
For y=0 To hauteur_niveau
For x=0 To largeur_niveau
If carte(x,y)>0;quand carte(x,y)=0, on affiche rien
If carte(x,y)<4;affichage des murs et du sol, caisses, soko,eau non affichés
ClipSprite(#spr_planche,(carte(x,y)-1)*32,0,32,32)
DisplaySprite(#spr_planche,x*32,y*32)
Else;si carte(x,y) supérieur ou égal à 4 on affiche le sol à la place
If carte(x,y)=5;caisse rouge, on affiche donc une case arrivée à la place
ClipSprite(#spr_planche,(#but-1)*32,0,32,32)
DisplaySprite(#spr_planche,x*32,y*32)
Else
ClipSprite(#spr_planche,(#sol-1)*32,0,32,32)
DisplaySprite(#spr_planche,x*32,y*32)
EndIf
EndIf
EndIf
Next x
Next y
;-on prend une "photo" du sprite crée et on l'appelle #spr_decor
GrabSprite(#spr_decor,0,0,largeur_ecran,hauteur_ecran)
;-choix de l'image de départ du personnage "soko"
soko=#soko1
;-choix de l'abscisse de départ de l'image "eau"
x_clip_eau=(#eau-1)*32
;-_________________________________
;-BOUCLE PRINCIPALE
;-_________________________________
Repeat
FlipBuffers() ;voir l'aide pour cette fonction
;-on affiche le décor
DisplaySprite(#spr_decor,0,0)
;-on affiche les éléments restants
For y=0 To hauteur_niveau
For x=0 To largeur_niveau
;-affichage des caisses
If carte(x,y)=#caisse Or carte(x,y)=#caisse_rouge
ClipSprite(#spr_planche,(carte(x,y)-1)*32,0,32,32)
DisplaySprite(#spr_planche,x*32,y*32)
EndIf
;-cas de l'eau
If carte(x,y)=#eau
;-animation de l'eau
If ElapsedMilliseconds()-chrono_eau>60
chrono_eau=ElapsedMilliseconds()
x_clip_eau=x_clip_eau+1
If x_clip_eau>(#eau-1+3)*32
x_clip_eau=(#eau-1)*32
EndIf
EndIf
;-affichage de l'eau
ClipSprite(#spr_planche,x_clip_eau,0,32,32)
DisplayTranslucentSprite(#spr_planche,x*32,y*32,128)
EndIf
;-enlevez les points virgules et vous verrez !
; StartDrawing(ScreenOutput())
; DrawText(x*32,y*32,Str(carte(x,y)))
; StopDrawing()
Next x
Next y
;-animation du personnage
If ElapsedMilliseconds()-chrono_soko>500
chrono_soko=ElapsedMilliseconds()
soko=soko+1
;-test pour revenir à la première image
If soko>#soko2
soko=#soko1
EndIf
EndIf
;-affichage du personnage
ClipSprite(#spr_planche,(soko-1)*32,0,32,32)
DisplaySprite(#spr_planche,x_soko*32,y_soko*32)
;-vérification du nombre de caisses placées
compteur=0
For y=0 To hauteur_niveau
For x=0 To largeur_niveau
If carte(x,y)=#caisse_rouge
compteur=compteur+1
If compteur=nbre_caisses
Flipbuffers()
MessageRequester("Victoire !",Str(nbre_caisses)+" caisses rangées")
;-passage au niiveau suivant
niveau=niveau+1
StopSound(musique)
If niveau=4
niveau=1
EndIf
;-retour au label "jeu:"
Goto jeu
EndIf
EndIf
Next x
Next y
;-gestion du clavier
If ElapsedMilliseconds()-chrono_keyboard>200
ExamineKeyboard()
;-appel de la macro clavier
If KeyboardPushed(#PB_Key_Right)
clavier(1, 0)
chrono_keyboard=ElapsedMilliseconds()
EndIf
If KeyboardPushed(#PB_Key_Left)
clavier(-1, 0)
chrono_keyboard=ElapsedMilliseconds()
EndIf
If KeyboardPushed(#PB_Key_Down)
clavier(0, 1)
chrono_keyboard=ElapsedMilliseconds()
EndIf
If KeyboardPushed(#PB_Key_Up)
clavier(0, -1)
chrono_keyboard=ElapsedMilliseconds()
EndIf
EndIf
If KeyboardReleased(#PB_Key_Space)
If ListIndex(sauvegarde_actions())<>0
x_soko=x_soko-sauvegarde_actions()\varx
y_soko=y_soko-sauvegarde_actions()\vary
Select sauvegarde_actions()\action
Case 0
DeleteElement(sauvegarde_actions())
Case #action_caisse_vers_sol
carte(x_soko+sauvegarde_actions()\varx,y_soko+sauvegarde_actions()\vary)=#caisse
carte(x_soko+2*sauvegarde_actions()\varx,y_soko+2*sauvegarde_actions()\vary)=#sol
DeleteElement(sauvegarde_actions())
Case #action_caisse_vers_but
carte(x_soko+sauvegarde_actions()\varx,y_soko+sauvegarde_actions()\vary)=#caisse
carte(x_soko+2*sauvegarde_actions()\varx,y_soko+2*sauvegarde_actions()\vary)=#but
DeleteElement(sauvegarde_actions())
Case #action_caisserouge_vers_sol
carte(x_soko+sauvegarde_actions()\varx,y_soko+sauvegarde_actions()\vary)=#caisse_rouge
carte(x_soko+2*sauvegarde_actions()\varx,y_soko+2*sauvegarde_actions()\vary)=#sol
DeleteElement(sauvegarde_actions())
Case #action_caisserouge_vers_but
carte(x_soko+sauvegarde_actions()\varx,y_soko+sauvegarde_actions()\vary)=#caisse_rouge
carte(x_soko+2*sauvegarde_actions()\varx,y_soko+2*sauvegarde_actions()\vary)=#but
DeleteElement(sauvegarde_actions())
EndSelect
EndIf
EndIf
If KeyboardReleased(#PB_Key_Return)
StopSound(musique)
Goto jeu
EndIf
Delay(10)
Until WindowEvent() = #PB_Event_CloseWindow
End
;-____________________________
;-FIN DU PROGRAMME PRINCIPAL
;-____________________________
;-____________________________
;-DONNEES SUR LES NIVEAUX
;-____________________________
DataSection
;mur=1;sol=2;but=3;caisse=4;caisse_rouge=5;soko1=6;soko2=7;eau=8
niveau1:
Data.b 1,9,7,3; musique n°1,dimensions 10*8; 3 caisses
Data.b 1,1,1,1,1,0,0,0,0,0
Data.b 1,2,2,6,1,0,0,0,0,0
Data.b 1,2,2,2,1,1,0,0,0,0
Data.b 1,2,4,2,2,1,1,1,1,1
Data.b 1,2,4,2,4,2,2,8,8,1
Data.b 1,1,1,2,2,2,2,3,8,1
Data.b 8,8,1,2,2,2,3,3,2,1
Data.b 8,8,1,1,1,1,1,1,1,1
;mur=1;sol=2;but=3;caisse=4;caisse_rouge=5;soko1=6;soko2=7;eau=8
niveau2:
Data.b 2,11,5,4; musique n°2, dimensions 12*6; 4 caisses
Data.b 1,1,1,1,1,1,1,1,1,1,1,1
Data.b 1,8,1,8,1,8,8,2,8,2,8,1
Data.b 1,6,2,2,2,2,8,2,2,2,8,1
Data.b 1,2,4,4,2,2,4,2,4,2,2,1
Data.b 1,2,3,2,3,2,3,2,3,2,2,1
Data.b 1,1,1,1,1,1,1,1,1,1,1,1
;mur=1;sol=2;but=3;caisse=4;caisse_rouge=5;soko1=6;soko2=7;eau=8
niveau3:
Data.b 3,8,6,6; musique n°3, dimensions 9*7; 6 caisses
Data.b 8,1,1,1,1,1,8,8,8
Data.b 8,1,2,2,2,1,1,1,1
Data.b 1,1,2,1,4,2,2,2,1
Data.b 1,2,4,2,2,4,4,2,1
Data.b 1,2,1,4,1,3,5,3,1
Data.b 1,2,2,2,6,3,3,3,1
Data.b 1,1,1,1,1,1,1,1,1
EndDataSection
Hasta la vista !