PureBasic     Discussion     Modifier     Historique     Forums     Salon IRC

PureBasic:PremiersPas

Un article de Games Creators Network.



PureBasic:PremiersPas

<< Précédent | Sommaire | Suivant >>


Sommaire

[modifier] Préambule

Cet article a été rédigé en utilisant la version 3.94. Depuis, des changements sont apparus dans PureBasic qui feront apparaitre quelques messages d'erreur si vous testez avec une version récente. Il y a très peu de modifications à effectuer, et elles sont indiquées dans le dernier chapitre, qui propose un code complet qui devrait être compatible avec les versions 4.xx.

[modifier] Introduction

Dans ce tut vous apprendrez à utiliser :

  • Le mode plein écran
  • Le clavier
  • Animer des sprites et les déplacer.

L'ensemble des codes présentés ici fonctionnent avec la version démo de PureBasic.
Cette version est gratuite. et n'est pas limitée dans le temps , donc n'hésitez pas à la télécharger

Version demo

Remarque : Apparemment les résidents ne sont pas inclus avec la version démo.
Il s'agit de fichiers qui se chargent automatiquement au démarrage de PureBasic, et qui contiennent la déclaration de quelques milliers de constantes , de structures et d'interfaces. ça évite d'avoir à les renseigner soi même . Dans les exemples qui suivent j'utilise la structure LONG si vous avez une erreur parce que le compilateur ne connait pas cette structure , ajoutez la au début du programme

Structure long
  l.l
EndStructure

[modifier] Premier Programme

Pour faire un jeu en plein écran , la structure minimale du programme devrait ressembler à quelque chose comme ça :

;Tut No1 : Programme minimal pour les jeux en mode plein écran.

;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()
;Initialise l'environnement propre à la gestion du clavier. 
InitKeyboard()
;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur. 
OpenScreen(800,600,32,"Tut Sprite")

Repeat
    ;Inverse le buffer d'arrière plan avec le buffer visible à l'écran. 
    ;La partie invisible du buffer remplace alors complètement La partie visible. 
    FlipBuffers()
    
    ;Efface l'écran courant avec la couleur specifiée. 
    ClearScreen(0,0,0)
    
    ;Met à jour l'état du clavier.Cette fonction doit être appelée avant d'utiliser les commandes 
    ;KeyboardInkey(), KeyboardPushed() et KeyboardReleased(). 
    ExamineKeyboard()
    
Until KeyboardPushed(#PB_Key_Escape)

On peut afficher un petit texte pour indiquer qu'il faut presser la touche [Echap] pour quitter.

Copiez ces lignes dans la boucle ,juste après ExamineKeyboard().

    ;Affiche un texte à l'écran
    StartDrawing(ScreenOutput())
    FrontColor(255,255,0)
    BackColor(0,0,255)
    DrawText("Appuyez sur la touche [Echap] pour quitter")
    StopDrawing() 

[modifier] Les sprites

Dans les exemples qui vont suivre , on utilisera cette planche de sprites.

Exemple de planche de sprite
Exemple de planche de sprite














Avant de charger le sprite , il faut activer le support du format PNG (Portable Network Graphic)

;Active le support du format PNG (Portable Network Graphic)
UsePNGImageDecoder() 

Remarque : Les sprites peuvent être au format BMP (non compressé) ou dans un des formats supportés par la bibliothèque ImagePlugin.

On charge le sprite.

;Charge en mémoire le sprite 
LoadSprite(0,"player.png")

Il est toujours bon de vérifier qu'une opération s'effectue correctement, pour cela il suffit de tester le résultat que retourne la fonction LoadSprite().

Notre programme devient:

;Charge en mémoire le sprite 
If LoadSprite(0,"player.png")=0
    MessageRequester("Erreur","Impossible de charger le sprite Player.png",0)
    End ; Quitte le programme
EndIf  

Si vous êtes impatient de voir ce sprite s'afficher à l'écran, vous pouvez ajouter dans la boucle

;Affiche le sprite à l'écran
DisplaySprite(0,0,0)

Le sprite est affiché à l'écran aux coordonnées (0,0).

[modifier] Animation du sprite

PureBasic possède une fonction très pratique pour gérer le Clipping, ClipSprite().

Cette fonction va nous permettre de gérer l'animation d'un seul personnage en sélectionnnant la portion du sprite principal que l'on souhaite afficher.

Il nous faut d'abord définir quelques éléments.
On peut se déplacer dans 4 directions , pour cela on va définir 4 constantes .

Enumeration
    #AnimeHaut
    #AnimeDroite
    #AnimeBas
    #AnimeGauche
EndEnumeration 

L'ordre des constantes est important.Il correspond à l'ordre des animations sur la planche .
Si vous regardez le premier personnage de la planche , en haut à gauche, vous constaterez qu'une animation occupe 3 images et qu'il possède 4 directions possibles :

  • Haut
  • Droite
  • Bas
  • Gauche

Chaque dessin du personnage peut être contenu dans un cadre de 24x32.

Nous avons besoin de stocker ces informations. On peut le faire de la façon suivante:

Structure s_Sprite
    Direction.l              ; Direction de l'animation , Haut droite bas ou gauche 
    ImageEnCours.l           ; Indique quelle image de l'animation est actuellement en cours 
    ImageMaxi.l              ; Nombre d'image maxi pour une animation , ici on a 3 images par direction
    TailleX.l                ; Dimension en X de chaque image 
    TailleY.l                ; Dimension en Y de chaque image 
EndStructure 

Tout le monde connait le principe de l'animation , les images doivent être affichées successivement pendant une certaine durée pour donner vie à notre personnage.

Pour prendre en compte cette durée d'affichage notre structure devient :

Structure s_Sprite
    Direction.l              ; Direction de l'animation , Haut droite bas ou gauche 
    ImageEnCours.l           ; Indique quelle image de l'animation est actuellement en cours 
    ImageMaxi.l              ; Nombre d'image maxi pour une animation , ici on a 3 images par direction
    TailleX.l                ; Dimension en X de chaque image 
    TailleY.l                ; Dimension en Y de chaque image 
    TempsEnCours.l           ; Indique la durée d'affichage de l'image en cours
    TempsMaxi.l              ; Indique la durée maxi d'affichage d'une image avant de passer à la suivante
EndStructure 

Par la suite nous aurons besoin de connaitre la position du personnage à l'écran, et aussi de le déplacer à une certaine vitesse. Pour finir, notre structure devient :

Structure s_Sprite
    Direction.l              ; Direction de l'animation , Haut droite bas ou gauche 
    ImageEnCours.l           ; Indique quelle image de l'animation est actuellement en cours 
    ImageMax.l               ; Nombre d'image maxi pour une animation , ici on a 3 images par direction
    TailleX.l                ; Dimension en X de chaque image 
    TailleY.l                ; Dimension en Y de chaque image
    TempsEnCours.l           ; Indique la durée d'affichage de l'image en cours
    TempsMaxi.l              ; Indique la durée maxi d'affichage d'une image avant de passer à la suivante
    x.l                      ; Position en X du sprite
    y.l                      ; Position en Y du sprite
    PasX.l                   ; Vitesse déplacement en X
    PasY.l                   ; Vitesse déplacement en Y
EndStructure 

On peut maintenant déclarer un personnage et renseigner les informations nécessaires à l'animation.

Global Gus.s_Sprite
Gus\Direction    = #AnimeDroite          ; On choisit une direction
Gus\ImageMax     = 2                     ; (0,1,2) ce qui fait bien 3 images
Gus\ImageEnCours = 0                     ; On se place sur la première image de l'animation
Gus\TailleX      = 24                    ; Taille d'une image 
Gus\TailleY      = 32                    ; Taille d'une image 
Gus\TempsEnCours = ElapsedMilliseconds() ; Initialise la durée d'affichage de l'ImageEnCours
Gus\TempsMaxi    = 150                   ; Ajuster la vitesse de l'animation ici
Gus\x            = 200                   ; Position à l'écran en X
Gus\y            = 200                   ; Position à l'écran en Y

Nous pouvons désormais revenir à notre fonction ClipSprite().
Elle permet de gérer en une seule ligne l'animation du sprite.

ClipSprite(0,Gus\ImageEnCours * Gus\TailleX, Gus\Direction * Gus\TailleY, Gus\TailleX , Gus\TailleY)

Il reste à gérer la durée de l'animation de chaque image du personnage.

    ;Test si la durée maxi d'affichage d'une image est dépassée 
    If ElapsedMilliseconds()-Gus\TempsEnCours>Gus\TempsMaxi
        
        ;Initialise la durée d'affichage
        Gus\TempsEnCours=ElapsedMilliseconds()
        
        ;Incrémente l'image en cours, pour afficher l'image suivante.
        Gus\ImageEnCours + 1
        
        ;On reboucle l'animation ici 
        If Gus\ImageEnCours>Gus\ImageMaxi
            Gus\ImageEnCours = 0 
        EndIf 
        
    EndIf

Notre personnage est prêt à s'animer .

[modifier] Gestion du Clavier

Pour déplacer le personnage, on va utiliser le curseur du clavier. C'est l'occasion de créer notre première Procédure.

Procedure GestionClavier()
    
    If ExamineKeyboard()
         
        ;La touche haut du curseur est appuyée
        If KeyboardPushed(#PB_Key_Up)
            Gus\Direction=#AnimeHaut
            Gus\PasY = -1
            ;La touche droite du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Right)
            Gus\Direction=#AnimeDroite
            Gus\PasX = 1
            ;La touche bas du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Down)
            Gus\Direction=#AnimeBas
            Gus\PasY = 1
            ;La touche gauche du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Left)
            Gus\Direction=#AnimeGauche
            Gus\PasX = -1
        EndIf
    EndIf    
    
EndProcedure

Il suffit maintenant d'appeler cette procédure dans la boucle principale.


[modifier] Déplacement du sprite

Il ne reste plus grand chose à faire pour déplacer notre personnage.

Procedure DeplaceSprite()
    
    Gus\x + Gus\PasX  ; Ajoute le pas en X à la position courante du sprite
    Gus\y + Gus\PasY  ; Ajoute le pas en Y à la position courante du sprite
    Gus\PasX = 0      ; Initialise le pas , il faudra appuyer à nouveau sur une touche pour l'activer
    Gus\PasY = 0      ; Initialise le pas , il faudra appuyer à nouveau sur une touche pour l'activer
    
    ;Affiche le sprite à la nouvelle position
    DisplayTransparentSprite(0,Gus\x, Gus\y)
    
EndProcedure

[modifier] Programme final

Et on obtient notre premier programme pour animer un sprite :

;Déclare les procédures
Declare GestionClavier()
Declare AnimationSprite()
Declare DeplaceSprite()
Declare AfficheTexte()

Structure s_Sprite
    Direction.l              ; Direction de l'animation , Haut droite bas ou gauche 
    ImageEnCours.l           ; Indique quelle image de l'animation est actuellement en cours 
    ImageMaxi.l               ; Nombre d'image maxi pour une animation , ici on a 3 images par direction
    TailleX.l                ; Dimension en X de chaque image 
    TailleY.l                ; Dimension en Y de chaque image
    TempsEnCours.l           ; Indique la durée d'affichage de l'image en cours
    TempsMaxi.l              ; Indique la durée maxi d'affichage d'une image avant de passer à la suivante
    x.l                      ; Position en X du sprite
    y.l                      ; Position en Y du sprite
    PasX.l                    ; Vitesse déplacement en X
    PasY.l                    ; Vitesse déplacement en Y
EndStructure 

;Déclare 4 constantes 
Enumeration
    #AnimeHaut
    #AnimeDroite
    #AnimeBas
    #AnimeGauche
EndEnumeration  

;On déclare un personnage  
Global Gus.s_Sprite

Gus\Direction    = #AnimeDroite            ; On choisit une direction
Gus\ImageMaxi    = 2                       ; (0,1,2) ce qui fait bien 3 images
Gus\ImageEnCours = 0                       ; On se place sur la première image de l'animation
Gus\TailleX      = 24                      ; Taille d'une image 
Gus\TailleY      = 32                      ; Taille d'une image 
Gus\TempsEnCours = ElapsedMilliseconds() ; Initialise la durée d'affichage de l'ImageEnCours
Gus\TempsMaxi    = 150                     ; Ajuster la vitesse de l'animation ici
Gus\x            = 200                     ; Position à l'écran en X
Gus\y            = 200                     ; Position à l'écran en Y


;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()

;Initialise l'environnement propre à la gestion du clavier. 
InitKeyboard()

;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur. 
OpenScreen(640,480,32,"Tut Sprite")

;Active le support du format PNG (Portable Network Graphic)
UsePNGImageDecoder() 
    
;Charge en mémoire le sprite 
If LoadSprite(0,"player.png")=0
    MessageRequester("Erreur","Impossible de charger le sprite Player.png",0)
    End ; Quitte le programme
EndIf    

Repeat
    ;Inverse le buffer d'arrière plan avec le buffer visible à l'écran. 
    ;La partie invisible du buffer remplace alors complètement La partie visible. 
    FlipBuffers()
    
    ;Efface l'écran courant avec la couleur specifiée. 
    ClearScreen(0,0,0)
    
    ;Gestion du clavier
    GestionClavier()
    
    ;Affiche un texte à l'écran
    AfficheTexte()
    
    ;Anime le sprite
    AnimationSprite()
    
    ;Deplace et affiche le sprite
    DeplaceSprite()
    
Until KeyboardPushed(#PB_Key_Escape)

End

Procedure AfficheTexte()
    
    StartDrawing(ScreenOutput())
    FrontColor(255,255,0)
    BackColor(0,0,255)
    DrawText("Appuyez sur la touche [Echap] pour quitter")
    StopDrawing()
    
EndProcedure

Procedure GestionClavier()
    
    If ExamineKeyboard()
        
        ;La touche haut du curseur est appuyée
        If KeyboardPushed(#PB_Key_Up)
            Gus\Direction=#AnimeHaut
            Gus\PasY = -1
            ;La touche droite du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Right)
            Gus\Direction=#AnimeDroite
            Gus\PasX = 1
            ;La touche bas du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Down)
            Gus\Direction=#AnimeBas
            Gus\PasY = 1
            ;La touche gauche du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Left)
            Gus\Direction=#AnimeGauche
            Gus\PasX = -1
        EndIf
    EndIf    
    
EndProcedure

Procedure AnimationSprite()
    
    ;Test si la durée maxi d'affichage d'une image est dépassée 
    If ElapsedMilliseconds()-Gus\TempsEnCours>Gus\TempsMaxi
        
        ;Initialise la durée d'affichage
        Gus\TempsEnCours=ElapsedMilliseconds()
        
        ;Incrémente l'image en cours, pour afficher l'image suivante.
        Gus\ImageEnCours + 1
        
        ;On reboucle l'animation ici 
        If Gus\ImageEnCours>Gus\ImageMaxi
            Gus\ImageEnCours = 0 
        EndIf 
        
    EndIf
    ClipSprite(0,Gus\ImageEnCours * Gus\TailleX, Gus\Direction * Gus\TailleY, Gus\TailleX , Gus\TailleY)
    
EndProcedure    
Procedure DeplaceSprite()
    
    Gus\x + Gus\PasX  ; Ajoute le pas en X à la position courante du sprite
    Gus\y + Gus\PasY  ; Ajoute le pas en Y à la position courante du sprite
    Gus\PasX = 0      ; Initialise le pas , il faudra appuyer à nouveau sur une touche pour l'activer
    Gus\PasY = 0      ; Initialise le pas , il faudra appuyer à nouveau sur une touche pour l'activer
    
    ;Affiche le sprite à la nouvelle position
    DisplayTransparentSprite(0,Gus\x, Gus\y)
    
EndProcedure

[modifier] Variante déplacement

Je propose une dernière façon de procéder pour le déplacement du personnage, ensuite c'est à chacun de trouver la meilleure méthode qui lui convient (et pourquoi pas la proposer ici dans cet article ?).

Plutôt que gérer un pas de déplacement en X et un pas en Y, on peut se contenter d'un seul paramètre vitesse.
Pour cela il faut modifier la Structure ainsi :

Structure s_Sprite
    Direction.l              ; Direction de l'animation , Haut droite bas ou gauche 
    ImageEnCours.l           ; Indique quelle image de l'animation est actuellement en cours 
    ImageMaxi.l              ; Nombre d'image maxi pour une animation , ici on a 3 images par direction
    TailleX.l                ; Dimension en X de chaque image 
    TailleY.l                ; Dimension en Y de chaque image
    TempsEnCours.l           ; Indique la durée d'affichage de l'image en cours
    TempsMaxi.l              ; Indique la durée maxi d'affichage d'une image avant de passer à la suivante
    x.l                      ; Position en X du sprite
    y.l                      ; Position en Y du sprite
    Vitesse.l                ; Vitesse déplacement 
EndStructure 

Vitesse remplace PasX et PasY.

Ensuite il faut supprimer PasX et PasY dans la procédure GestionClavier()
Et initialiser Vitesse à zéro si aucun déplacement n'est demandé.

Et pour finir on peut modifier la procédure DeplaceSprite() ainsi:

Procedure DeplaceSprite()
    
    Select Gus\Direction
        Case #AnimeHaut
            Gus\y - Gus\Vitesse
        Case #AnimeDroite
            Gus\x + Gus\Vitesse
        Case #AnimeBas
            Gus\y + Gus\Vitesse
        Case #AnimeGauche
            Gus\x - Gus\Vitesse
    EndSelect
     
    ;Affiche le sprite à la nouvelle position
    DisplayTransparentSprite(0,Gus\x, Gus\y)

    ;Initialise la vitesse
    Gus\Vitesse = #VitesseGus
    
EndProcedure

[modifier] Variante animation

C'est plus qu'une variante ,c'est plutôt d'un complément qu'il s'agit ici.
En effet , pour l'instant on peut animer un personnage, mais on ne peut pas encore choisir lequel sera utilisé parmi les 8 existants sur la planche .

Là encore , il existe plusieurs solutions , mais qui reviennent au même , à savoir , calculer les coordonnées de l'image à afficher avec la fonction ClipSprite().

Dans cet exemple on va ajouter deux arguments à la structure :

  • Colonne : Pour indiquer à partir de quelle position en X se trouve la première image de l'animation
  • Ligne  : Pour indiquer à partir de quelle position en Y se trouve la première image de l'animation
Structure s_Sprite
    Direction.l              ; Direction de l'animation , Haut droite bas ou gauche 
    Colonne.l                ; Décalage en X pour la première image
    Ligne.l                  ; Décalage en Y pour la première image   
    ImageEnCours.l           ; Indique quelle image de l'animation est actuellement en cours 
    ImageMaxi.l              ; Nombre d'image maxi pour une animation , ici on a 3 images par direction
    TailleX.l                ; Dimension en X de chaque image 
    TailleY.l                ; Dimension en Y de chaque image
    TempsEnCours.l           ; Indique la durée d'affichage de l'image en cours
    TempsMaxi.l              ; Indique la durée maxi d'affichage d'une image avant de passer à la suivante
    x.l                      ; Position en X du sprite
    y.l                      ; Position en Y du sprite
    Vitesse.l                ; Vitesse déplacement 
EndStructure 

Exemple pour choisir le troisième personnage de la deuxième rangée :

Gus\Colonne      = 6 * Gus\TailleX         ; 6 images avant d'atteindre le 3ème personnage 
Gus\Ligne        = 4 * Gus\TailleY         ; 4 images pour atteindre la deuxième rangée (0 pour la première)

Et pour finir , la procédure AnimationSprite() devient:

Procedure AnimationSprite()
    
    ;Test si la durée maxi d'affichage d'une image est dépassée 
    If ElapsedMilliseconds()-Gus\TempsEnCours>Gus\TempsMaxi
        
        ;Initialise la durée d'affichage
        Gus\TempsEnCours=ElapsedMilliseconds()
        
        ;Incrémente l'image en cours, pour afficher l'image suivante.
        Gus\ImageEnCours + 1
        
        ;On reboucle l'animation ici 
        If Gus\ImageEnCours>Gus\ImageMaxi
            Gus\ImageEnCours = 0 
        EndIf 
        
    EndIf
    ClipSprite(0,Gus\Colonne + Gus\ImageEnCours * Gus\TailleX, Gus\Ligne + Gus\Direction * Gus\TailleY, Gus\TailleX , Gus\TailleY)
    
EndProcedure  

[modifier] Les pointeurs

Jusqu'à présent nous nous sommes occupés d'animer un seul sprite, et pour en animer un second ou un troisième comment faire ? Le plus simple c'est d'utiliser les Pointeurs.

Toutes les procédures utilisants les sprites devront comporter un pointeur associé à la structure s_Sprite. Par exemple la procédure AnimationSprite() devient :

Procedure AnimationSprite(*Sp.s_Sprite)
    
    ;Test si la durée maxi d'affichage d'une image est dépassée 
    If ElapsedMilliseconds()-*Sp\TempsEnCours>*Sp\TempsMaxi
        
        ;Initialise la durée d'affichage
        *Sp\TempsEnCours=ElapsedMilliseconds()
        
        ;Incrémente l'image en cours, pour afficher l'image suivante.
        *Sp\ImageEnCours + 1
        
        ;On reboucle l'animation ici 
        If *Sp\ImageEnCours>*Sp\ImageMaxi
            *Sp\ImageEnCours = 0 
        EndIf 
        
    EndIf
    ClipSprite(0,*Sp\Colonne + *Sp\ImageEnCours * *Sp\TailleX, *Sp\Ligne + *Sp\Direction * *Sp\TailleY, *Sp\TailleX , *Sp\TailleY)
    
EndProcedure 
  • Sp est un pointeur associé à la Structure s_Sprite.

Pour fonctionner la procédure attend l'adresse d'un sprite utilisant également la même structure que le pointeur.
Pour appeler la procédure en lui passant l'adresse d'un sprite on utilise le symbole @:

;Anime le sprite
AnimationSprite(@Gus)

Si on devait en rester là , c'est à dire animer un seul sprite , l'utilisation des pointeurs ne serait pas très convaincante.
Alors on va afficher à l'écran les 8 personnages de la planche, et les animer .

Pour cela on va ajouter un tableau Gus() qui utilisera lui aussi la structure s_Sprite.

Dim Gus.s_Sprite(7) ; 8 personnages de 0 à 7

Remarque : L'utilisation d'un tableau n'est pas le meilleur choix pour la démonstration , un tableau étant global , il n'est donc pas nécessaire de passer par les pointeurs.

Par contre si on avait déclaré chacun de nos sprites ainsi :

Joueur1.s_Sprite
Joueur2.s_Sprite
Guerrier.s_Sprite
Fermier.s_Sprite

L'usage des pointeurs serait pleinement justifié  :

;Anime le fermier
AnimationSprite(@Fermier)
;Anime le Joueur1
AnimationSprite(@Joueur1)
etc

[modifier] Programme avec pointeurs et 8 sprites animés

Structure s_Sprite
    Direction.l              ; Direction de l'animation , Haut droite bas ou gauche 
    Colonne.l                ; Décalage en X pour la première image
    Ligne.l                  ; Décalage en Y pour la première image   
    ImageEnCours.l           ; Indique quelle image de l'animation est actuellement en cours 
    ImageMaxi.l              ; Nombre d'image maxi pour une animation , ici on a 3 images par direction
    TailleX.l                ; Dimension en X de chaque image 
    TailleY.l                ; Dimension en Y de chaque image
    TempsEnCours.l           ; Indique la durée d'affichage de l'image en cours
    TempsMaxi.l              ; Indique la durée maxi d'affichage d'une image avant de passer à la suivante
    x.l                      ; Position en X du sprite
    y.l                      ; Position en Y du sprite
    Vitesse.l                ; Vitesse déplacement 
EndStructure 

;Déclare 4 constantes 
Enumeration
    #AnimeHaut
    #AnimeDroite
    #AnimeBas
    #AnimeGauche
EndEnumeration  
#Joueur = 3     ; Indique le No du personnage utilisé pour le joueur - Contrôlé au clavier
#VitesseGus = 1 ; Déplacement d'un pixel

;Déclare les procédures
Declare GestionClavier(*Sp.s_Sprite)
Declare AnimationSprite(*Sp.s_Sprite)
Declare DeplaceSprite(*Sp.s_Sprite)
Declare IAGus(*Sp.s_Sprite)
Declare AfficheTexte()

;On déclare un personnage  
Dim Gus.s_Sprite(7) ; ; 8 personnages de 0 à 7

For Lig = 0 To 1
    For Col = 0 To 3
        Gus(NoGus)\Direction    = Random(3)                   ; On choisit une direction
        Gus(NoGus)\ImageMaxi    = 2                            ; (0,1,2) ce qui fait bien 3 images
        Gus(NoGus)\ImageEnCours = 0                            ; On se place sur la première image de l'animation
        Gus(NoGus)\TailleX      = 24                           ; Taille d'une image 
        Gus(NoGus)\TailleY      = 32                           ; Taille d'une image 
        Gus(NoGus)\TempsEnCours = ElapsedMilliseconds()      ; Initialise la durée d'affichage de l'ImageEnCours
        Gus(NoGus)\TempsMaxi    = 150                           ; Ajuster la vitesse de l'animation ici
        Gus(NoGus)\x            = 30+Random(600)               ; Position à l'écran en X
        Gus(NoGus)\y            = 30+Random(440)               ;  Position à l'écran en Y
        Gus(NoGus)\Colonne      = (Col*3) * Gus(NoGus)\TailleX ; Calcul la position en X de la première image 
        Gus(NoGus)\Ligne        = (Lig*4) * Gus(NoGus)\TailleY ; Calcul la position en Y de la première image
        NoGus + 1                                               ; Numéro du Gus suivant
    Next Col
Next Lig

;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()

;Initialise l'environnement propre à la gestion du clavier. 
InitKeyboard()

;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur. 
OpenScreen(640,480,32,"Tut Sprite")

;Active le support du format PNG (Portable Network Graphic)
UsePNGImageDecoder() 
    
;Charge en mémoire le sprite 
If LoadSprite(0,"player.png")=0
    MessageRequester("Erreur","Impossible de charger le sprite Player.png",0)
    End ; Quitte le programme
EndIf    

Repeat
    ;Inverse le buffer d'arrière plan avec le buffer visible à l'écran. 
    ;La partie invisible du buffer remplace alors complètement La partie visible. 
    FlipBuffers()
    
    ;Efface l'écran courant avec la couleur specifiée. 
    ClearScreen(0,0,0)
    
    ;Gestion du clavier avec le sprite 2
    GestionClavier(@Gus(#Joueur))
    
    ;Affiche un texte à l'écran
    AfficheTexte()
    
    
    For i=0 To 7
        ;Anime le sprite
        AnimationSprite(@Gus(i))
        
        ;Deplace et affiche le sprite
        DeplaceSprite(@Gus(i))
        
        ;Petite IA simpliste pour contrôler le déplacement des gus
        If i<>#Joueur
            IAGus(@Gus(i))
        EndIf 
        
    Next i
    
Until KeyboardPushed(#PB_Key_Escape)

End

Procedure AfficheTexte()
    
    StartDrawing(ScreenOutput())
    FrontColor(255,255,0)
    BackColor(0,0,255)
    DrawText("Appuyez sur la touche [Echap] pour quitter")
    StopDrawing()
    
EndProcedure

Procedure GestionClavier(*Sp.s_Sprite)
    
    If ExamineKeyboard()
        
        ;La touche haut du curseur est appuyée
        If KeyboardPushed(#PB_Key_Up)
            *Sp\Direction=#AnimeHaut
            
            ;La touche droite du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Right)
            *Sp\Direction=#AnimeDroite
            
            ;La touche bas du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Down)
            *Sp\Direction=#AnimeBas
            
            ;La touche gauche du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Left)
            *Sp\Direction=#AnimeGauche
            
        Else
            *Sp\Vitesse=0
        EndIf
    EndIf    
    
EndProcedure

Procedure AnimationSprite(*Sp.s_Sprite)
    
    ;Test si la durée maxi d'affichage d'une image est dépassée 
    If ElapsedMilliseconds()-*Sp\TempsEnCours>*Sp\TempsMaxi
        
        ;Initialise la durée d'affichage
        *Sp\TempsEnCours=ElapsedMilliseconds()
        
        ;Incrémente l'image en cours, pour afficher l'image suivante.
        *Sp\ImageEnCours + 1
        
        ;On reboucle l'animation ici 
        If *Sp\ImageEnCours>*Sp\ImageMaxi
            *Sp\ImageEnCours = 0 
        EndIf 
        
    EndIf
    ClipSprite(0,*Sp\Colonne + *Sp\ImageEnCours * *Sp\TailleX, *Sp\Ligne + *Sp\Direction * *Sp\TailleY, *Sp\TailleX , *Sp\TailleY)
    
EndProcedure    
Procedure DeplaceSprite(*Sp.s_Sprite)
    
    Select *Sp\Direction
        Case #AnimeHaut
            *Sp\y - *Sp\Vitesse
        Case #AnimeDroite
            *Sp\x + *Sp\Vitesse
        Case #AnimeBas
            *Sp\y + *Sp\Vitesse
        Case #AnimeGauche
            *Sp\x - *Sp\Vitesse
    EndSelect
    
    ;Affiche le sprite à la nouvelle position
    DisplayTransparentSprite(0,*Sp\x, *Sp\y)
    
    ;Initialise la vitesse
    *Sp\Vitesse = #VitesseGus
    
EndProcedure

Procedure IAGus(*Sp.s_Sprite)
    
    ;Test la position des gus 
    If *Sp\x > 640 - *Sp\TailleX
        *Sp\x = 640 - *Sp\TailleX 
        *Sp\Direction + 1
    EndIf
    If *Sp\y > 480 - *Sp\TailleY
        *Sp\y = 480 - *Sp\TailleY 
        *Sp\Direction + 1
    EndIf
    If *Sp\x < *Sp\TailleX
        *Sp\x = *Sp\TailleX 
        *Sp\Direction + 1
    EndIf
    If *Sp\y < *Sp\TailleY
        *Sp\y = *Sp\TailleY 
        *Sp\Direction + 1
    EndIf
    
    If *Sp\Direction > #AnimeGauche
        *Sp\Direction = #AnimeHaut
    EndIf    
    
EndProcedure    


[modifier] Passage à la V4

Voici le premier programme adapté à la V4. Très peu de changements :

  • ClearScreen(), BackColor() et FrontColor() ne prennent plus qu'un paramètre.
  • DrawText() comporte deux paramètres supplémentaires (position en x et y du texte, dans les versions précédentes c'était la commande Locate() qui indiquait la position du texte).

Et j'en ai profité pour supprimer la procédure DeplaceSprite() , histoire de montrer une autre variante possible.

;Déclare les procédures
Declare GestionClavier()
Declare AnimationSprite()
Declare AfficheTexte()

Structure s_Sprite
    Direction.l              ; Direction de l'animation , Haut droite bas ou gauche 
    ImageEnCours.l           ; Indique quelle image de l'animation est actuellement en cours 
    ImageMaxi.l              ; Nombre d'image maxi pour une animation , ici on a 3 images par direction
    TailleX.l                ; Dimension en X de chaque image 
    TailleY.l                ; Dimension en Y de chaque image
    TempsEnCours.l           ; Indique la durée d'affichage de l'image en cours
    TempsMaxi.l              ; Indique la durée maxi d'affichage d'une image avant de passer à la suivante
    x.l                      ; Position en X du sprite
    y.l                      ; Position en Y du sprite
    PasX.l                   ; Vitesse déplacement en X
    PasY.l                   ; Vitesse déplacement en Y
EndStructure 

;Déclare 4 constantes 
Enumeration
    #AnimeHaut
    #AnimeDroite
    #AnimeBas
    #AnimeGauche
EndEnumeration  

;On déclare un personnage  
Global Gus.s_Sprite

Gus\Direction    = #AnimeDroite            ; On choisit une direction
Gus\ImageMaxi    = 2                       ; (0,1,2) ce qui fait bien 3 images
Gus\ImageEnCours = 0                       ; On se place sur la première image de l'animation
Gus\TailleX      = 24                      ; Taille d'une image 
Gus\TailleY      = 32                      ; Taille d'une image 
Gus\TempsEnCours = ElapsedMilliseconds() ; Initialise la durée d'affichage de l'ImageEnCours
Gus\TempsMaxi    = 150                     ; Ajuster la vitesse de l'animation ici
Gus\x            = 200                     ; Position à l'écran en X
Gus\y            = 200                     ; Position à l'écran en Y
Gus\PasX         = 1                       ; Vitesse de déplacement en X
Gus\PasY         = 1                       ; Vitesse de déplacement en Y

;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()

;Initialise l'environnement propre à la gestion du clavier. 
InitKeyboard()

;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur. 
OpenScreen(640,480,32,"Tut Sprite")

;Active le support du format PNG (Portable Network Graphic)
UsePNGImageDecoder() 
    
;Charge en mémoire le sprite 
If LoadSprite(0,"player.png")=0
    MessageRequester("Erreur","Impossible de charger le sprite Player.png",0)
    End ; Quitte le programme
EndIf    

Repeat
    ;Inverse le buffer d'arrière plan avec le buffer visible à l'écran. 
    ;La partie invisible du buffer remplace alors complètement La partie visible. 
    FlipBuffers()
    
    ;Efface l'écran courant avec la couleur specifiée. 
    ClearScreen(0)
    
    ;Gestion du clavier
    GestionClavier()
    
    ;Affiche un texte à l'écran
    AfficheTexte()
    
    ;Anime le sprite
    AnimationSprite()
    
    ;Deplace et affiche le sprite
    DisplayTransparentSprite(0, Gus\x, Gus\y)
    
Until KeyboardPushed(#PB_Key_Escape)

End

Procedure AfficheTexte()
    
    StartDrawing(ScreenOutput())
    FrontColor(RGB(255,255,0))
    BackColor(RGB(0,0,255))
    DrawText(0,0,"Appuyez sur la touche [Echap] pour quitter")
    StopDrawing()
    
EndProcedure

Procedure GestionClavier()
    
    If ExamineKeyboard()
        
        ;La touche haut du curseur est appuyée
        If KeyboardPushed(#PB_Key_Up)
            Gus\Direction=#AnimeHaut
            Gus\Y - Gus\PasY 
            ;La touche droite du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Right)
            Gus\Direction=#AnimeDroite
            Gus\x + Gus\PasX 
            ;La touche bas du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Down)
            Gus\Direction=#AnimeBas
            Gus\Y + Gus\PasY 
            ;La touche gauche du curseur est appuyée
        ElseIf KeyboardPushed(#PB_Key_Left)
            Gus\Direction=#AnimeGauche
            Gus\x - Gus\PasX 
        EndIf
    EndIf    
    
EndProcedure

Procedure AnimationSprite()
    
    ;Test si la durée maxi d'affichage d'une image est dépassée 
    If ElapsedMilliseconds()-Gus\TempsEnCours>Gus\TempsMaxi
        
        ;Initialise la durée d'affichage
        Gus\TempsEnCours=ElapsedMilliseconds()
        
        ;Incrémente l'image en cours, pour afficher l'image suivante.
        Gus\ImageEnCours + 1
        
        ;On reboucle l'animation ici 
        If Gus\ImageEnCours>Gus\ImageMaxi
            Gus\ImageEnCours = 0 
        EndIf 
        
    EndIf
    ClipSprite(0,Gus\ImageEnCours * Gus\TailleX, Gus\Direction * Gus\TailleY, Gus\TailleX , Gus\TailleY)
    
EndProcedure    

 

Rechercher
Installer l'extension de recherche Plus d'informations

 

Comprendre
Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. - Benjamin Franklin

 

Partager
La connaissance est la seule chose qui s'accroit lorsqu'on la partage. - Sacha Boudjema

 

Créer
L'imagination est plus importante que la connaissance. - Albert Einstein

 

 

Le wiki en images Le wiki en images Image du mois: «Snowball: un prototype de jeu développé avec NeL.