Sokoban ultracommenté (MAJ annulation+reset+STATS)

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

Re: Sokoban ultracommenté (MAJ stats)

Message par Huitbit »

Hello,

Petite mise à jour :
-Nombre de mouvements
-Nombre de poussées
-Chronomètre

Aucune complication dans le code mais ça ajoute un peu de confort 8) !
Toute amélioration ou correction (il y a du boulot vu que je n'ai pas fait dans la finesse :lol: ) est bienvenue !

Rappel : ce code fonctionne également avec la version démo 4.41 !


Planche de sprites à charger (clic droit puis Enregistrer l'image sous...) et à mettre dans le même dossier que le code :
Image

Version sans le son

Code : Tout sélectionner

;sokoban avec annulation des actions,reset et statistiques
;auteur Huitbit
;amélioration des déplacements par Le Soldat Inconnu 
;pb v4.41 et pb v4.50
;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
nombre_de_mouvements.i;variable utilisée pour comptabiliser le nombre de mouvements effectués par le joueur
nombre_de_poussees.i;variable utilisée pour comptabiliser le nombre le nombre de fois qu'une caisse a été poussée
chrono_niveau.i;variable utilisée pour mesurer les secondes qui s'écoulent
duree_niveau.i;variable utilisée compter le temps passé sur un niveau

;-_____________________________________________
;-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
  nombre_de_mouvements=nombre_de_mouvements+1
  SetWindowTitle(0,"Niveau "+Str(niveau)+"|M="+Str(nombre_de_mouvements)+"|P="+Str(nombre_de_poussees)+"|t="+Str(duree_niveau)+" s")
  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
    nombre_de_mouvements=nombre_de_mouvements+1
    nombre_de_poussees=nombre_de_poussees+1
    SetWindowTitle(0,"Niveau "+Str(niveau)+"|M="+Str(nombre_de_mouvements)+"|P="+Str(nombre_de_poussees)+"|t="+Str(duree_niveau)+" s")
    
    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
    nombre_de_mouvements=nombre_de_mouvements+1
    nombre_de_poussees=nombre_de_poussees+1
    SetWindowTitle(0,"Niveau "+Str(niveau)+"|M="+Str(nombre_de_mouvements)+"|P="+Str(nombre_de_poussees)+"|t="+Str(duree_niveau)+" s")
    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
    nombre_de_mouvements=nombre_de_mouvements+1
    nombre_de_poussees=nombre_de_poussees+1
    SetWindowTitle(0,"Niveau "+Str(niveau)+"|M="+Str(nombre_de_mouvements)+"|P="+Str(nombre_de_poussees)+"|t="+Str(duree_niveau)+" s")
    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
    nombre_de_mouvements=nombre_de_mouvements+1
    nombre_de_poussees=nombre_de_poussees+1
    SetWindowTitle(0,"Niveau "+Str(niveau)+"|M="+Str(nombre_de_mouvements)+"|P="+Str(nombre_de_poussees)+"|t="+Str(duree_niveau)+" s")
    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()

;-on choisit le niveau de départ
niveau=1
MessageRequester("Infos !", ">Barre d'espace : annuler une  action."+Chr(13)+">Return : réinitialiser le niveau")

;-"jeu:" s'appelle un label, c'est une adresse, un numéro de ligne où l'on peut renvoyer le programme
jeu:
nombre_de_mouvements=0
nombre_de_poussees=0
duree_niveau=0
;-création d'une liste chaînée nommé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
  Case 4
    Restore niveau4
    
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*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 "planche" 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)
  
  ;-comptage des secondes passées sur le niveau
  If nombre_de_mouvements<>0
    If ElapsedMilliseconds()-chrono_niveau>1000
      chrono_niveau=ElapsedMilliseconds()
      duree_niveau=duree_niveau+1
      SetWindowTitle(0,"Niveau "+Str(niveau)+"|M="+Str(nombre_de_mouvements)+"|P="+Str(nombre_de_poussees)+"|t="+Str(duree_niveau)+" s")
    EndIf
  Else
    duree_niveau=0 
    SetWindowTitle(0,"Sokoban niveau "+Str(niveau))
  EndIf
  
  ;-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
          
          ; le niveau va changer avant de repasser par le Flipbuffers() présent en début de boucle
          ; il faut donc faire un dernier rendu "à la main"
          FlipBuffers()
          
          MessageRequester("Victoire !",Str(nbre_caisses)+" caisses rangées")
          ;-passage au niveau suivant
          niveau=niveau+1
          If niveau=5
            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
  ;-annulation des actions effectuées
  If KeyboardReleased(#PB_Key_Space)
    If ListIndex(sauvegarde_actions())<>0
      x_soko=x_soko-sauvegarde_actions()\varx
      y_soko=y_soko-sauvegarde_actions()\vary
      nombre_de_mouvements=nombre_de_mouvements-1
      
      Select sauvegarde_actions()\action
        
        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
          nombre_de_poussees=nombre_de_poussees-1
        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
          nombre_de_poussees=nombre_de_poussees-1
        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
          nombre_de_poussees=nombre_de_poussees-1
        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
          nombre_de_poussees=nombre_de_poussees-1
          
      EndSelect 
      
      SetWindowTitle(0,"Niveau "+Str(niveau)+"|M="+Str(nombre_de_mouvements)+"|P="+Str(nombre_de_poussees)+"|t="+Str(duree_niveau)+" s")
      DeleteElement(sauvegarde_actions())
      
    EndIf
  EndIf
  
  ;-recommencer le niveau
  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 8,7,7; dimensions 10*8; 3 caisses
Data.b 8,8,8,1,1,1,1,1,8
Data.b 1,1,1,1,3,2,2,1,1
Data.b 1,2,4,3,4,3,2,2,1
Data.b 1,6,4,1,2,1,4,2,1
Data.b 1,2,4,3,2,3,2,2,1
Data.b 1,1,1,1,4,1,4,2,1 
Data.b 8,8,1,3,2,3,2,2,1
Data.b 8,8,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

;mur=1;sol=2;but=3;caisse=4;caisse_rouge=5;soko1=6;soko2=7;eau=8
niveau4:
Data.b 8,7,6;  dimensions 9*8; 6 caisses
Data.b 8,8,8,1,1,1,1,1,8
Data.b 1,1,1,1,2,2,2,1,1
Data.b 1,2,4,2,4,2,2,2,1
Data.b 1,6,1,3,5,3,1,2,1
Data.b 1,2,1,3,5,3,1,2,1
Data.b 1,2,2,2,4,2,4,2,1
Data.b 1,1,2,2,2,1,1,1,1
Data.b 8,1,1,1,1,1,8,8,8

EndDataSection
Hasta la vista !
Dernière modification par Huitbit le dim. 11/juil./2010 5:15, modifié 4 fois.
Elevé au MSX !
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par flaith »

Bon ya pas à dire, j'adore :mrgreen:

petit, mais tout petit bémol, quand tu indiques que les caisses sont rangées, justement la dernière caisse n'est pas affichée comme étant rangée :wink:

Sinon, après avoir lu le code, il aurait bien sa place dans la zone TUTO Image
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Huitbit »

Hello,

Merci flaith,
petit, mais tout petit bémol, quand tu indiques que les caisses sont rangées, justement la dernière caisse n'est pas affichée comme étant rangée
Je vais arranger ça, le problème c'est que, depuis l'amélioration de LSI, je n'arrive pas à reproduire cette situation !

Geo trouvepatou l'avait signalé :
Hormis le fait que comme ce que j'avais déjà dit, le messageRequester de victoire arrive trop tôt. Il devrait s'activer lorsque la dernière caisse est réellement recouverte.
Hasta la vista !
Elevé au MSX !
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par flaith »

argh, c'est mon pb, je lis pas toujours tout le thread :D
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Le Soldat Inconnu »

il suffit de déplacer le message "Niveau terminé" pour le mettre après le rafraichirent de l'affichage (donc après le flipbuffers)

donc il faut faire un mot "NiveauTermine" au niveau du déplacement (gestion clavier) et regarder si ce mot est à 1 après le flipbuffers()

:D au travail
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Huitbit »

Hugh !

Est-ce qu'un Flipbuffers() juste avant le MessageRequester() ne suffit pas ?
Normalement, le tableau a été modifié à la boucle précédente et la boucle d'affichage des tiles effectuée un peu plus haut.
Le MessageRequester() "courtcircuite" le programme et empêche le Flipbuffers() qui suit en début de prochaine boucle principale.

J'ai fait quelques tests, sur mon PC, tout se passe comme si un "flipbuffers() automatique" :roll: se faisait juste avant le MessageRequester(). C'est pour ça que je n'ai jamais vu le bug !


Zone de code où il faut rajouter le Flipbuffers()

Code : Tout sélectionner

 ;-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 niveau suivant
          niveau=niveau+1
          If niveau=5
            niveau=1
          EndIf
          ;-retour au label "jeu:"
          Goto jeu
        EndIf
      EndIf
    Next x
  Next y
Flaith, peux-tu tester ?


Hasta la vista !
Elevé au MSX !
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par flaith »

A y-est testé, ca marche nickel :D
Merci m'sieur :mrgreen:
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Huitbit »

Ouf !

Merci pour le test, LSI voulait me donner du travail :roll: !
J'ai corrigé le code ci-dessus.

C'est quand même bizarre le comportement de mon PC, il me cache les bugs :?
Y a-t-il une IA autonome dans windows XP sp3 8O ?

Hasta la vista !
Elevé au MSX !
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Le Soldat Inconnu »

j'avais le même soucis que flaith :)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par comtois »

le jeu est dispo en téléchargement sur dvp

http://purebasic.developpez.com/sources ... ux#sokoban
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Huitbit »

Hugh !

@Comtois
Bonne idée l'ajout des exécutables !

A la date où j'ai fait le code, je voulais également montrer aux élèves que la version démo était suffisante pour faire un projet plus que correct (autrement dit : "N'allez pas chercher une "version gratuite" de PureBasic sur internet :mrgreen: ).
Cette année, il y a encore un groupe qui m'a pondu un truc avec des API et qui n'a pas pu répondre aux questions posées par la classe sur le fonctionnement du programme (bizarrement leur code ne fonctionnait pas avec le PC utilisé pour l'exposé où il y avait la version démo 4.41 :mrgreen: ).
Bizarrement, ils ont eu la plus mauvaise note :twisted: (sachant qu'une partie de la note était donnée par le reste de la classe).

A part ça ...
Sur l'original, j'en suis au niveau 34.
Mon PC est à côté du téléphone, quand un coup de fil devient trop long, je "sokobanne" :mrgreen:

Hasta la vista !
Elevé au MSX !
Avatar de l’utilisateur
Ar-S
Messages : 9478
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Ar-S »

comtois a écrit :le jeu est dispo en téléchargement sur dvp
http://purebasic.developpez.com/sources ... ux#sokoban

Le lien FTP sur DVP semble out..

Huitbit pourrais tu mettre les derniers codes à jour sur le 1er fil de discutions du topic ? Je suis perdu dans tous ces codes.
Merci ;)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Huitbit »

Hello,

J'essaye de te faire ça ce week-end !

Hasta la vista !
Elevé au MSX !
Avatar de l’utilisateur
Ar-S
Messages : 9478
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Ar-S »

Merci mon gars :P
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: Sokoban ultracommenté (MAJ annulation+reset+STATS)

Message par Huitbit »

Et hop !!!!

Il n'y avait qu'une ligne à changer, j'en ai profité pour mettre la musique.

Toute l'archive :
https://www.dropbox.com/s/t889d7ijetss8 ... 4.rar?dl=0

Le fichier fait environ 6Mo car j'ai mis les musiques d'origine !

Attention, le premier niveau est beaucoup plus gentil que les autres !

Rappel, ce code était destiné à un public qui partait de loin (=> pas de structures, le goto pour boucler le jeu,...)

Code : Tout sélectionner

; sokoban avec annulation des actions,reset et statistiques
; auteur Huitbit
; amélioration des déplacements par Le Soldat Inconnu
; pb v4.41 démo et pbv 4.50
; une partie des sprites est tirée du site ci-dessous
; http://www.brothersoft.com/games/soukoban.html
;MAJ octobre 2014
; *********************************
;- ___________________________________
;- 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
nombre_de_mouvements.i ; variable utilisée pour comptabiliser le nombre de mouvements effectués par le joueur
nombre_de_poussees.i ; variable utilisée pour comptabiliser le nombre de fois qu'une caisse a été poussée
chrono_niveau.i ; variable utilisée pour mesurer les secondes qui s'écoulent
duree_niveau.i ; variable utilisée compter le temps passé sur un niveau

;- _____________________________________________
;- 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
        nombre_de_mouvements = nombre_de_mouvements + 1
        SetWindowTitle(0, "Niveau " + Str(niveau) + "|M=" + Str(nombre_de_mouvements) + "|P=" + Str(nombre_de_poussees) + "|t=" + Str(duree_niveau) + " s")
        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
            nombre_de_mouvements = nombre_de_mouvements + 1
            nombre_de_poussees = nombre_de_poussees + 1
            SetWindowTitle(0, "Niveau " + Str(niveau) + "|M=" + Str(nombre_de_mouvements) + "|P=" + Str(nombre_de_poussees) + "|t=" + Str(duree_niveau) + " s")
            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
            nombre_de_mouvements = nombre_de_mouvements + 1
            nombre_de_poussees = nombre_de_poussees + 1
            SetWindowTitle(0, "Niveau " + Str(niveau) + "|M=" + Str(nombre_de_mouvements) + "|P=" + Str(nombre_de_poussees) + "|t=" + Str(duree_niveau) + " s")
            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
            nombre_de_mouvements = nombre_de_mouvements + 1
            nombre_de_poussees = nombre_de_poussees + 1
            SetWindowTitle(0, "Niveau " + Str(niveau) + "|M=" + Str(nombre_de_mouvements) + "|P=" + Str(nombre_de_poussees) + "|t=" + Str(duree_niveau) + " s")
            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
            nombre_de_mouvements = nombre_de_mouvements + 1
            nombre_de_poussees = nombre_de_poussees + 1
            SetWindowTitle(0, "Niveau " + Str(niveau) + "|M=" + Str(nombre_de_mouvements) + "|P=" + Str(nombre_de_poussees) + "|t=" + Str(duree_niveau) + " s")
            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()

UseOGGSoundDecoder()
;- on charge le son et les musiques
LoadSound(#son_caisse_poussee, "son_caisse_poussee.wav")
LoadSound(1, "musique1.ogg")
LoadSound(2, "musique2.ogg")
LoadSound(3, "musique3.ogg")
LoadSound(4, "musique4.ogg")


;- on choisit le niveau de départ
niveau = 1
MessageRequester("Infos !", ">Barre d'espace : annuler une  action." + Chr(13) + ">Return : réinitialiser le niveau")

;- "jeu:" s'appelle un label, c'est une adresse, un numéro de ligne où l'on peut renvoyer le programme
jeu:
nombre_de_mouvements = 0
nombre_de_poussees = 0
duree_niveau = 0
;- création d'une liste chaînée nommé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
    Case 4
        Restore niveau4
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*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 "planche" 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)
                ;- !!!!!!!!!!!
                ;-(source : Historique) Supprimé: DisplayTranslucentSprite() -> remplacé par le paramètre 'Alpha' avec DisplayTransparentSprite()
                DisplayTransparentSprite(#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)
    
    ;- comptage des secondes passées sur le niveau
    If nombre_de_mouvements <> 0
        If ElapsedMilliseconds() - chrono_niveau > 1000
            chrono_niveau = ElapsedMilliseconds()
            duree_niveau = duree_niveau + 1
            SetWindowTitle(0, "Niveau " + Str(niveau) + "|M=" + Str(nombre_de_mouvements) + "|P=" + Str(nombre_de_poussees) + "|t=" + Str(duree_niveau) + " s")
        EndIf
    Else
        duree_niveau = 0
        SetWindowTitle(0, "Sokoban niveau " + Str(niveau))
    EndIf
    
    ;- 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
                    
                    ; le niveau va changer avant de repasser par le Flipbuffers() présent en début de boucle
                    ; il faut donc faire un dernier rendu "à la main"
                    FlipBuffers()
                    
                    MessageRequester("Victoire !", Str(nbre_caisses) + " caisses rangées")
                    ;- passage au niveau suivant
                    niveau = niveau + 1
                    StopSound(musique)
                    If niveau = 5
                        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
    ;- annulation des actions effectuées
    If KeyboardReleased(#PB_Key_Space)
        If ListIndex(sauvegarde_actions()) <> 0
            x_soko = x_soko - sauvegarde_actions()\varx
            y_soko = y_soko - sauvegarde_actions()\vary
            nombre_de_mouvements = nombre_de_mouvements - 1
            
            Select sauvegarde_actions()\action
                    
                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
                    nombre_de_poussees = nombre_de_poussees - 1
                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
                    nombre_de_poussees = nombre_de_poussees - 1
                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
                    nombre_de_poussees = nombre_de_poussees - 1
                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
                    nombre_de_poussees = nombre_de_poussees - 1
                    
            EndSelect
            
            SetWindowTitle(0, "Niveau " + Str(niveau) + "|M=" + Str(nombre_de_mouvements) + "|P=" + Str(nombre_de_poussees) + "|t=" + Str(duree_niveau) + " s")
            DeleteElement(sauvegarde_actions())
            
        EndIf
    EndIf
    
    ;- recommencer le niveau
    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, 8, 7, 7 ; musique n°2, dimensions 10*8; 3 caisses
        Data.b 8, 8, 8, 1, 1, 1, 1, 1, 8
        Data.b 1, 1, 1, 1, 3, 2, 2, 1, 1
        Data.b 1, 2, 4, 3, 4, 3, 2, 2, 1
        Data.b 1, 6, 4, 1, 2, 1, 4, 2, 1
        Data.b 1, 2, 4, 3, 2, 3, 2, 2, 1
        Data.b 1, 1, 1, 1, 4, 1, 4, 2, 1
        Data.b 8, 8, 1, 3, 2, 3, 2, 2, 1
        Data.b 8, 8, 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
    
    ; mur=1;sol=2;but=3;caisse=4;caisse_rouge=5;soko1=6;soko2=7;eau=8
    niveau4:
        Data.b 4, 8, 7, 6 ; musique n°4  dimensions 9*8; 6 caisses
        Data.b 8, 8, 8, 1, 1, 1, 1, 1, 8
        Data.b 1, 1, 1, 1, 2, 2, 2, 1, 1
        Data.b 1, 2, 4, 2, 4, 2, 2, 2, 1
        Data.b 1, 6, 1, 3, 5, 3, 1, 2, 1
        Data.b 1, 2, 1, 3, 5, 3, 1, 2, 1
        Data.b 1, 2, 2, 2, 4, 2, 4, 2, 1
        Data.b 1, 1, 2, 2, 2, 1, 1, 1, 1
        Data.b 8, 1, 1, 1, 1, 1, 8, 8, 8
    
EndDataSection
Elevé au MSX !
Répondre