PureBasic

Forums PureBasic
Nous sommes le Lun 20/Mai/2013 9:59

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 41 messages ]  Aller à la page 1, 2, 3  Suivante
Auteur Message
 Sujet du message: Sokoban ultracommenté (MAJ annulation+reset+STATS)
MessagePosté: Jeu 29/Avr/2010 4:37 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 08/Déc/2005 5:19
Messages: 728
Localisation: Guadeloupe
Hello,

Voici un petit code que j'ai dû réaliser pour mes élèves.
Je me suis inspiré du jeu gratuit du site http://www.brothersoft.com/games/soukoban.html
J'ai juste rajouté de l'eau qui coule pour faire joli :P !
Il y a juste deux niveaux (j'ai fait le code la veille du cours :oops: )

L'objectif est de réaliser un jeu complet (graphisme, son, jouabilité...etc).
La structure du code est assez intuitive. Pour chaque étape, j'ai gardé la première solution qui venait, cela signifie que le code n'est pas du tout optimisé :mrgreen: .
D'ailleurs, si vous avez des simplifications à faire ou même des points qui vous semblent trop obscurs, n'hésitez pas à le signaler !
Avec quelques améliorations, ça pourrait même faire un tuto non ?

Par contre, j'espère que je ne vais choquer personne avec mon GOTO
:lol: :lol: :lol:
Dans ce genre de cas, je trouve que c'est super efficace.

Le seul hic, c'est que vous devez rajouter un effet sonore pour les caisses poussées et deux musiques pour l'ambiance et tout ça au format .wav:
Code:
LoadSound(#son_caisse_pousse,"son_caisse_poussee.wav")
LoadSound(1,"musique1.wav")
LoadSound(2,"musique2.wav")

Désolé :oops:
D'ailleurs, si une bonne âme a ça sous la main (liens de téléchargement) :D
Si vous avez la flemme, je mets la version sans son à la suite :wink:

Planche de sprites à charger et à mettre dans le même dossier que le code :
Image

Code:
;sokoban avec son
;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
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

;-_____________________________________________
;- 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
  ;-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
    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
    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
    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
    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")

;-on choisit le niveau de départ
niveau=1

;-"jeu:" s'appelle un label, c'est une adresse, un numéro de ligne où l'on peut renvoyer le programme
jeu:
;-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
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
          Delay(100)
          MessageRequester("Victoire !",Str(nbre_caisses)+" caisses rangées")
          ;-passage au niiveau suivant
          niveau=niveau+1
          StopSound(musique)
          If niveau=3
            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
 
  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

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

EndDataSection


Version sans le son
Code:
;sokoban
    ;pb v4.41
    ;Auteur Huitbit
    ;amélioration des déplacements par Le soldat Inconnu
    ;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
      EndEnumeration
     
       ;-déclaration des variables
    niveau.b;numéro du niveau
    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
    ;-_____________________________________________
    ;- 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
               ;-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
                  ;-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
               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
                  ;-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
               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
     
    ;-"jeu:" s'appelle un label, c'est une adresse, un numéro de ligne où l'on peut renvoyer le programme
    jeu:
    ;-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
      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
              Delay(100)
              MessageRequester("Victoire !",Str(nbre_caisses)+" caisses rangées")
              ;-passage au niiveau suivant
              niveau=niveau+1
              If niveau=3
                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
         
         Repeat
            Event = WindowEvent()
            If Event = #PB_Event_CloseWindow
               End
            EndIf
         Until Event = 0
         Delay(1)
         
      ForEver
    ;-____________________________
    ;-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 0,0,1,2,2,2,3,3,2,1
         Data.b 0,0,1,1,1,1,1,1,1,1
         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
         
      EndDataSection


Hasta la vista !

_________________
Elevé au MSX !


Dernière édition par Huitbit le Jeu 08/Juil/2010 5:26, édité 9 fois.

Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté !
MessagePosté: Jeu 29/Avr/2010 6:32 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 09/Nov/2005 9:53
Messages: 2586
Bravo. C'est tres beau et c'est rigolo :P

_________________
i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!
i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!
i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!
i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!

http://xmas.free.fr/


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté !
MessagePosté: Jeu 29/Avr/2010 7:10 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 26/Avr/2004 0:40
Messages: 12946
marche pas chez moi ! (version avec son)

le bonhomme commence en bas du tableau , et est bloqué sur le chemin du bas
de plus si je fais fleche vers le bas , j'ai un plantage ! :)
car le bonhomme , ne peux sortir de la map par le bas (out tableau)

_________________
Image


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté !
MessagePosté: Jeu 29/Avr/2010 7:38 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 26/Avr/2004 0:40
Messages: 12946
je suis parti de ta version sans son (qui marche elle :) )

pour faire une version avec Son en utilisant ma derniere librairie Midi_lib (< on dirai le nom d'un journal "Midi Libre" :lol: )

a recuperer ici :
http://michel.dobro.free.fr/download.php?view.18

voici cette version donc:

Citation:


;sokoban
;pb v4.41
;Auteur Huitbit
;une partie des sprites est tirée du site ci-dessous
;http://www.brothersoft.com/games/soukoban.html
;*********************************
Declare musique(hwnd.l, uMsg.l, idEvent.l, dwTime.l)
#Guitar_Fret_noise =121
#Pan_Flute =66
#timer_1 =1
MIDIOpen() ; ouvre le midi
Global vitesse=60
Charge_Instrument_melodie(1, #Guitar_Fret_noise )
Charge_Instrument_melodie(2, #Pan_Flute )


;-___________________________________
;-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
EndEnumeration

;-déclaration des variables
niveau.b ;numéro du niveau
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.l ; variable utilisée pour temporiser l'animation du personnage
chrono_keyboard.l ;variable utilisée pour temporiser la fonction KeyboardPushed()
largeur_ecran.l
hauteur_ecran.l
x_clip_eau.l ;variable utilisée pour découper le sprite "planche" pixel par pixel au niveau de l'eau
chrono_eau.l ; variable utilisée pour temporiser l'animation de l'eau
;-_____________________________________________
;- 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(direction,dx,dy)
         If keyboardpushed (direction)
                 ;-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
                         ;-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
                                Midi_play_multi(1, "C" , "croche" ,3,127,127,60)
                                 ;-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
                                Midi_play_multi(1, "C" , "croche" ,3,127,127,60)
                         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
                                Midi_play_multi(1, "C" , "croche" ,3,127,127,60)
                                 ;-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
                                Midi_play_multi(1, "C" , "croche" ,3,127,127,60)
                         EndIf
                        
                 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

;-"jeu:" s'appelle un label, c'est une adresse, un numéro de ligne où l'on peut renvoyer le programme
jeu:
;-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
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)

Handle = windowid (0)
SetTimer_ (Handle, #timer_1 , 300, @musique())

;-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
                                         delay (100)
                                         messagerequester ( "Victoire !" , str (nbre_caisses)+ " caisses rangées" )
                                         ;-passage au niiveau suivant
                                        niveau=niveau+1
                                         If niveau=3
                                                niveau=1
                                         EndIf
                                         ;-retour au label "jeu:"
                                         Goto jeu
                                 EndIf
                         EndIf
                 Next x
         Next y
        
         ;-gestion du clavier
         If elapsedmilliseconds ()-chrono_keyboard>160
                chrono_keyboard= elapsedmilliseconds ()
                
                 examinekeyboard ()
                 ;-appel de la macro clavier
                clavier( #PB_Key_Right ,1,0)
                clavier( #PB_Key_Left ,-1,0)
                clavier( #PB_Key_Down ,0,1)
                clavier( #PB_Key_Up ,0,-1)
                
         EndIf
        
         delay (10)
Until windowevent () = #PB_Event_CloseWindow
End



Procedure musique(hwnd.l, uMsg.l, idEvent.l, dwTime.l)
         Select uMsg
                 Case #WM_TIMER
                         Select idEvent
                                 Case #timer_1
                                        
                                        vitesse=120
                                        de= random (7)+1 ; genere une note aleatoire
                                        de2= random (4)+2
                                        p.s= "a#,c#,d#f#,g#,c,d,e" :Note.s= stringfield (p.s,de, "," ): octave=de2
                                        
                                        Midi_play_multi(2,Note.s, "triple_croche" ,octave,60,60,vitesse)
                                         delay (Midi_tempo(vitesse, "triple_croche" ))
                                        Midi_stop_Note(2,Note.s,octave)
                         EndSelect
         EndSelect
EndProcedure


;-____________________________
;-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 0,0,1,2,2,2,3,3,2,1
         Data.b 0,0,1,1,1,1,1,1,1,1
        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
        
EndDataSection


_________________
Image


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté !
MessagePosté: Jeu 29/Avr/2010 9:30 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4311
Localisation: Clermont ferrand OU Olsztyn
Vraiment très sympa, juste un truc au niveau des touches pour le déplacement, c'est parfois pénible car un appui sur une touche n'est pas pris en compte à chaque fois, tu à une forte latence dans le code (mise en place pour l'animation je pense)

_________________
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)]


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté !
MessagePosté: Jeu 29/Avr/2010 11:41 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 08/Déc/2005 5:19
Messages: 728
Localisation: Guadeloupe
Merci pour les tests !

Pour la latence c'est corrigé
Code:
  ;-gestion du clavier
  If ElapsedMilliseconds()-chrono_keyboard=100 <<<
    chrono_keyboard=ElapsedMilliseconds()
.....
  Endif


Mais il faudra que je rajoute la possibilité d'annuler les deux ou trois derniers coups ! Parce que des fois, on pousse un peu fort :lol: !

J'ai supprimé deux lignes inutiles(le son était lancé obligatoirement après le choix du niveau :roll: )
Code:
;-on choisit le niveau de départ
niveau=1
PlaySound(#musique1,#PB_Sound_Loop)  <<<
SoundVolume(#musique1,60)  <<<


@Dobro
Etrange, c'est le même code avec ou sans le son.
Peut-être un problème dans la lecture des data ?

Si quelqu'un d'autre a testé avec la version avec son, un retour m'intéresse.

[Mode "grosse buse" on]
Je n'arrive pas à installer ta lib :oops:
Un message me dit qu'elle est installée mais Pb ne la trouve pas !
Merci d'avoir eu le courage de mettre le nez dans le code !
[Mode "grosse buse" off]

Pour info, mes élèves doivent travailler avec la version démo 4.41 (=>800 lignes max et pas d'API!)
S'il y a d'autres versions du code je leur montrerai mais le midi ça va pas être possible pour eux dommage.
Je peux toujours remplacer par du .mod :roll: !


La latence venait du code qui a servi d'exemple :

Code:
;tuiles
;PureBasic 4.41 (Windows - x86)
;*********************************

#largeur_ecran=800
#hauteur_ecran=600

;-dans l'énumération, on fait correspondre automatiquement des noms de constantes à des nombres (ex: #spr_herbe=0,#spr_mur=1,...etc)
Enumeration
  #spr_herbe
  #spr_mur
  #spr_personnage
  #spr_decor
EndEnumeration

;-on dit au compilateur qu'on va utiliser des sprites
InitSprite()

;-on dit au compilateur qu'on va utiliser le clavier
InitKeyboard()

;-on dit au compilateur d'être prêt à lire les données (dans la datasection) correspondant au "niveau"
Restore niveau
;-on lit la largeur (ici 7 c'est à dire huit cases de 0 à 7)
Read.b largeur_niveau
;-on lit la hauteur
Read.b hauteur_niveau

;-on crée un tableau "carte" où on va ranger toutes les informations
;-les informations sont du type ".b" c'est à dire "bytes", ce sont des nombres qui vont de -128 à +127
Dim carte.b(largeur_niveau,hauteur_niveau)

;-on remplit le tableau avec deux boucles
For y=0 To hauteur_niveau
  For x=0 To largeur_niveau
    ;-on lit les "data" de la gauche vers la droite  et de haut en bas 
    Read.b type_tuile
    carte(x,y)=type_tuile
  Next x
Next y
;-----------------------------------------
;-PROGRAMME PRINCIPAL
;-----------------------------------------
;-on crée une fenêtre
OpenWindow(0,0,0,#largeur_ecran,#hauteur_ecran,"tuiles ",#PB_Window_ScreenCentered|#PB_Window_SystemMenu  )
;-on met un écran dedans
OpenWindowedScreen(WindowID(0),0,0,#largeur_ecran,#hauteur_ecran,0,0,0)

;-on dessine un carré vert bordé de noir pour l'herbe de 100 pixels sur 100 pixels
CreateSprite(#spr_herbe,100,100)
StartDrawing(SpriteOutput(#spr_herbe))
Box(2,2,96,96,RGB(0,255,0))
StopDrawing()

;-on dessine un carré gris bordé de noir pour le mur
CreateSprite(#spr_mur,100,100)
StartDrawing(SpriteOutput(#spr_mur))
Box(2,2,96,96,RGB(0,128,128))
StopDrawing()

;-on dessine un carré rouge bordé de noir pour le personnage
CreateSprite(#spr_personnage,100,100)
StartDrawing(SpriteOutput(#spr_personnage))
Box(2,2,96,96,RGB(255,0,0))
StopDrawing()

;-avec l'herbe et le mur, on va créer un sprite "décor"
;-pour cela, en respectant les données du tableau carte, on va afficher l'herbe et les bouts de mur

;-on "nettoie" l'écran en le coloriant en noir
ClearScreen(RGB(0,0,0))
;-on affiche les éléments du tableau "carte"
;-de gauche à droite et de bas en haut
For y=0 To hauteur_niveau
  For x=0 To largeur_niveau
    DisplaySprite(carte(x,y),x*100,y*100)
  Next x
Next y
;-on prend une "photo" de l'écran et on l'envoie dans le sprite "décor"
GrabSprite(#spr_decor,0,0,#largeur_ecran,#hauteur_ecran)

;-initialisation de la position du personnage
colonne_personnage.b=1
ligne_personnage.b=1
x_personnage.l=100*colonne_personnage
y_personnage.l=100*ligne_personnage

;-information pour l'utilisateur
MessageRequester("Conseil.","Utilisez les flêches du clavier pour déplacer le carré rouge")
;-----------------------------------------
;-BOUCLE PRINCIPALE
;-----------------------------------------
Repeat

  ;-affichage
  FlipBuffers()
  DisplaySprite(#spr_decor,0,0)
  DisplaySprite(#spr_personnage,x_personnage,y_personnage)
 
  ;-gestion du clavier
 
  ;-on "surveille" le clavier avec "ExamineKeyboard()"  toutes les 100 millisecondes (diminuez la valeur et vous verrez pourquoi !)
  If ElapsedMilliseconds()-temporisation_clavier>100
    temporisation_clavier=ElapsedMilliseconds()
   
    ExamineKeyboard()
   
    ;-en fonction de la touche relâchée, on prend une décision
    If KeyboardPushed(#PB_Key_Right)
      ;déplacement possiblle uniquement sur l'herbe !
      If carte(colonne_personnage+1,ligne_personnage)=#spr_herbe
        colonne_personnage=colonne_personnage+1
      EndIf
    EndIf
   
    If KeyboardPushed(#PB_Key_Left)
      If carte(colonne_personnage-1,ligne_personnage)=#spr_herbe
        colonne_personnage=colonne_personnage-1
      EndIf
    EndIf
   
    If KeyboardPushed(#PB_Key_Down)
      If carte(colonne_personnage,ligne_personnage+1)=#spr_herbe
        ligne_personnage=ligne_personnage+1
      EndIf
    EndIf
   
    If KeyboardPushed(#PB_Key_Up)
      If carte(colonne_personnage,ligne_personnage-1)=#spr_herbe
        ligne_personnage=ligne_personnage-1
      EndIf
    EndIf
   
  EndIf
  ;-si un décision a modifié la ligne ou la colonne  du personnage, il faut en tenir compte pour l'affichage
  x_personnage=100*colonne_personnage
  y_personnage=100*ligne_personnage
 
  ;-on laisse un peu souffler l'ordinateur
  Delay(10)
 
Until WindowEvent() = #PB_Event_CloseWindow
;-fin de la boucle principale
;---------------------------------------------------------------------------------
;-stockage des informations en fin de programme
DataSection
niveau:
Data.b 7,5; dimensions 8*6
Data.b 1,1,1,1,1,1,1,1
Data.b 1,0,0,0,0,0,0,1
Data.b 1,0,0,1,0,0,0,1
Data.b 1,0,0,1,1,1,0,1
Data.b 1,0,0,0,0,0,0,1
Data.b 1,1,1,1,1,1,1,1
EndDataSection


Hasta la vista et en core merci aux testeurs !

_________________
Elevé au MSX !


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté ! (MAJ post 1)
MessagePosté: Jeu 29/Avr/2010 12:09 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 5213
J'ai pas le temps tout de suite mais dans la journée, je le testerai, au pire dans la soirée.
J'ai hâte j'ai hâte j'ai hâte !

_________________
.: Ar-S :. - Windows 8 x64 - Radeon HD 7870 - PB 5.11
LDV MULTIMEDIA : Assistance informatique Isère (38) Oyeu
PURE BASIC forum non officiel : Forum PB


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté ! (MAJ post 1)
MessagePosté: Jeu 29/Avr/2010 13:05 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 28/Jan/2004 20:58
Messages: 4311
Localisation: Clermont ferrand OU Olsztyn
Pour la latence du clavier, comme cela, c'est totalement disparu.

Regarde comment je fais

Code:
    ;sokoban
    ;pb v4.41
    ;Auteur Huitbit
    ;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
      EndEnumeration
      
    ;-déclaration des variables
    niveau.b;numéro du niveau
    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.l; variable utilisée pour temporiser l'animation du personnage
    chrono_keyboard.l;variable utilisée pour temporiser la fonction KeyboardPushed()
    largeur_ecran.l
    hauteur_ecran.l
    x_clip_eau.l;variable utilisée pour découper le sprite "planche" pixel par pixel au niveau de l'eau
    chrono_eau.l; variable utilisée pour temporiser l'animation de l'eau
    ;-_____________________________________________
    ;- 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
               ;-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
                  ;-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
               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
                  ;-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
               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
      
    ;-"jeu:" s'appelle un label, c'est une adresse, un numéro de ligne où l'on peut renvoyer le programme
    jeu:
    ;-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
      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
              Delay(100)
              MessageRequester("Victoire !",Str(nbre_caisses)+" caisses rangées")
              ;-passage au niiveau suivant
              niveau=niveau+1
              If niveau=3
                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
         
         Repeat
            Event = WindowEvent()
            If Event = #PB_Event_CloseWindow
               End
            EndIf
         Until Event = 0
         Delay(1)
         
      ForEver
    ;-____________________________
    ;-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 0,0,1,2,2,2,3,3,2,1
         Data.b 0,0,1,1,1,1,1,1,1,1
         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
         
      EndDataSection

_________________
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)]


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté ! (MAJ post 1)
MessagePosté: Jeu 29/Avr/2010 15:46 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 5213
Bizarre le code de LSI passe sous PureBasic.exe mais pas via JapBe (erreur => openscreen ou openwindowed screen doit etre initialisé blabla)
La version de Dobro fonctionne sur les 2.

_________________
.: Ar-S :. - Windows 8 x64 - Radeon HD 7870 - PB 5.11
LDV MULTIMEDIA : Assistance informatique Isère (38) Oyeu
PURE BASIC forum non officiel : Forum PB


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté ! (MAJ post 1)
MessagePosté: Jeu 29/Avr/2010 15:51 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 26/Avr/2004 0:40
Messages: 12946
Citation:
Je n'arrive pas à installer ta lib :oops:
Un message me dit qu'elle est installée mais Pb ne la trouve pas !


mon install pose la librairie dans la derniere version de purebasic installée !

si tu as installé la version 4.50 ; c'est dans ce dossier qu'il faut chercher ma lib !

sinon elle dois etre dans C:\Dobro\Purebasic_4_41\PureLibraries\UserLibraries\ avec comme nom Lib_midi2

:) tiens moi au jus

ps: je me suis emmerdé a lire le registre pour savoir ou installer mes prg
mais je sent que je vais revenir a un mon vieux messagerequester :lol:

_________________
Image


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté ! (MAJ post 1)
MessagePosté: Jeu 29/Avr/2010 17:19 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 5213
Le mieux est d'aller dans le registre chercher le chemin du dernier PB d'installé et de le proposer par defaut à l'utilisateur. Sil veut changer il peut.

_________________
.: Ar-S :. - Windows 8 x64 - Radeon HD 7870 - PB 5.11
LDV MULTIMEDIA : Assistance informatique Isère (38) Oyeu
PURE BASIC forum non officiel : Forum PB


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté ! (MAJ post 1)
MessagePosté: Jeu 29/Avr/2010 17:24 
Hors ligne
Avatar de l’utilisateur

Inscription: Lun 26/Avr/2004 0:40
Messages: 12946
oui ; je pense que je vais faire ça :)

_________________
Image


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté ! (MAJ post 1)
MessagePosté: Jeu 29/Avr/2010 17:54 
Hors ligne

Inscription: Dim 23/Déc/2007 18:10
Messages: 471
Salut.

Pourquoi continuer d'utiliser des .l (long) plutôt que des .i (integer) sachant que ça consomme pareil sous 32 bits mais que cela à l'avantage d'être compatible 64 bits?

Bye.


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté ! (MAJ post 1)
MessagePosté: Jeu 29/Avr/2010 18:23 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 29/Juil/2004 16:33
Messages: 2116
Localisation: . <------ ici
sympatoche sa :wink:

j'avais jouer a un jeux du même style je l'avais trouvé sympa.





@++

_________________
Windows 8 x64, processeur core i7 2.93ghz, mémoire ram 10Go, 2x ati radeon hd 5750 1Go chacune
PureBasic 5.11 x86 & x64 DirectX 11


Haut
 Profil  
 
 Sujet du message: Re: Sokoban ultracommenté ! (MAJ post 1)
MessagePosté: Jeu 29/Avr/2010 18:40 
Hors ligne

Inscription: Dim 23/Déc/2007 18:10
Messages: 471
Re.

Bon je viens de tester.
Même chose que Dobro.

La version sans son pour le niveau 1 pas de problème.
Pour la version avec son, le niveau 1 est infaisable et un appui en bas et crash.

Le double appui pour se déplacer est chiant et à un moment le perso s'est déplacé de 2 cases simultanément, ce qui m'a fait perdre.
du coup j'ai attrappé mon écran et je l'ai jeté par terre.
Tu dois donc me rembourser un écran de trentedouze pouce à 4500€ (Tu me crois j'espère :lol:)
Bon on règle ça par MP.

Bye.

[EDIT]Et en plus le messageRequester arrive avant d'avoir réellement placé la dernière caisse au bonne endroit.

La version de LSI est impeccable concernant les déplacements.


Haut
 Profil  
 
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 41 messages ]  Aller à la page 1, 2, 3  Suivante

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye