Obligement - L'Amiga au maximum

Lundi 25 juin 2018 - 04:28  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


Programmation : AMOS - Déplacement case par case
(Article écrit par Jean Monos - mai 2018)


Étant une mécanique de jeu, ce tutoriel peut être facilement adapté à tous les langages de programmation. Ceci n'est qu'un exemple, et une base pour comprendre une mécanique. Il est bien sûr vital de le modifier à votre sauce, de l'améliorer et d'adapter tout cela suivant vos besoins.

Nous allons voir une mécanique de jeu en AMOS qui est souvent utilisée : le déplacement case par case avec une gestion simple de collision. Le déplacement case par case est une mécanique utilisée quand le joueur choisit une direction, son avatar se retrouvera tout simplement dans la case adjacente du quadrillage. La modification peut être directe ou bien avec une animation de mouvement. Dans ce cas, il faudra attendre que l'avatar se retrouve dans la nouvelle position pour que le joueur puisse en choisir une nouvelle.

Tutoriel 1 : un simple déplacement case par case

Pour ce premier tutoriel, nous allons faire un simple déplacement case par case sur notre écran. Nous allons afficher un quadrillage en icônes (les tuiles) et une représentation d'un personnage. Nous allons tout simplement le faire bouger d'une case à l'autre.

Pour l'exemple, lancez l'éditeur d'objets. Dessinez une icône de 16x16 pixels avec une couleur pleine qui le remplit et avec un trait qui entoure les quatre côtés.

AMOS

Dessinez à peu près la même chose avec un objet qui va nous servir à faire un sprite logiciel (un BOB).

AMOS

Voici maintenant le code source pour ce premier exemple. Nous le décrypterons après.

' =================================
' === Déplacement Case par Case ===
' =================================

' ------------------------------------------------ 
' --- Mise en place des paramètres de l'écran --- 
' ------------------------------------------------ 
Screen Open 0,320,200,16,Lowres
Flash Off 
Curs Off 

' -----------------------
' --- Variable Globale --- 
' -----------------------
Global G_QUIT
Global G_POSITION_X, G_POSITION_Y
Global G_DIRECTION,G_DIRECTION_DOWN

P_DRAW_MAP


' ---------------------
' --- Boucle du jeu ---
' ---------------------
While(G_QUIT=0)

' ### Partie Logique ### 
P_INPUT
P_UPDATE_PLAYER

' ### Attente du V Blank ### 
Wait Vbl 

' ### Partie Graphique ### 
P_UPDATE_GRAPHE

Wend 
End

Rem *****************************************
Rem *** Procédure d'affichage de la carte ***
Rem *****************************************
Procedure P_DRAW_MAP
Restore D_MAP

' ------------------------------------ 
' --- Boucle pour poser les tuiles --- 
'------------------------------------- 

For Y=0 To 11
For X=0 To 19

Read ID_MAP
Paste Icon X*16,Y*16,ID_MAP

Next 
Next 

'----------------- 
' --- Map Test --- 
'----------------- 
D_MAP:
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


End Proc

Rem ***************************************
Rem *** Procédure de gestion du clavier ***
Rem ***************************************

' -------------------------- 
' Valeur de G_Direction :
' 8 = Haut 
' 2 = Bas
' 4 = Droite 
' 6 = Gauche 
' -------------------------- 

Procedure P_INPUT


If Key State(76)=True
G_DIRECTION=8

Else If Key State(77)=True
G_DIRECTION=2

Else If Key State(78)
G_DIRECTION=6

Else If Key State(79)=True
G_DIRECTION=4

Else If Key State(69)=True
G_QUIT=1
Else 
G_DIRECTION=0
G_DIRECTION_DOWN=0

End If 


End Proc


Rem *****************************
Rem *** Mise à jour du joueur ***
Rem *****************************
Procedure P_UPDATE_PLAYER

If G_DIRECTION_DOWN=0

If G_DIRECTION=6
G_POSITION_X=G_POSITION_X+1
G_DIRECTION_DOWN=1

Else If G_DIRECTION=4
G_POSITION_X=G_POSITION_X-1
G_DIRECTION_DOWN=1

Else If G_DIRECTION=8
G_POSITION_Y=G_POSITION_Y-1
G_DIRECTION_DOWN=1

Else If G_DIRECTION=2
G_POSITION_Y=G_POSITION_Y+1
G_DIRECTION_DOWN=1

End If 
End If 
End Proc

Rem ********************************** 
Rem *** Mise à jour des graphismes *** 
Rem ********************************** 
Procedure P_UPDATE_GRAPHE
Bob 0,G_POSITION_X*16,G_POSITION_Y*16,1

End Proc

La mise en place de l'écran est banale. Nous ouvrons un écran 0 qui a pour dimension 300x200 pixels en 16 couleurs en mode basse résolution (lowres). C'est basique : nous annulons les couleurs flash (qui clignotent) et nous retirons le curseur à l'écran.

Pour cet exemple, nous allons passer par des variables globales. Je préfixe mes variables globales par un "G_" sur AMOS (c'est une habitude personnelle). Le G_QUIT permet de savoir quand nous terminons la boucle principale et le programme.

La position

G_POSITION_X et G_POSITION_Y permettent de mémoriser les cases X et Y où se trouve le joueur.

G_DIRECTION est la valeur de la direction choisie qui sera mémorisée :
  • 6 = droite.
  • 4 = gauche.
  • 8 = haut.
  • 2 = bas.
  • 0 = centre donc rien.
Associer des actions à une variable est pratique pour la suite. Cela permet de gérer plus facilement des périphériques (clavier/souris/manette).

Le G_DIRECTION_DOWN permet tout simplement de savoir si une touche est enfoncée et permet de réaliser des déplacements coup par coup.

Et enfin le P_DRAW_MAP appelle avant la boucle de jeu une procédure qui permet d'afficher la carte exemple (map) à l'écran.

La boucle du jeu

La boucle du jeu se trouve dans une boucle "While". Elle teste au début de la boucle si la variable G_QUITE vaut 0. Si cette condition est vraie, alors nous entrons dans la boucle. Si elle est fausse, nous sautons la boucle pour finir le programme avec un "End".

Dans notre exemple, la boucle du jeu possède trois procédures et une instruction pour attendre le V-Blank.

Les deux premières procédures sont des procédures dites "Logiques".
Le P_INPUT permet d'interroger l'entrée clavier du jeu au début de la boucle.
Le P_UPDATE_PLAYER permet de modifier les variables de position du joueur en fonction du P_INPUT.

Après le V_Blank, nous attaquons tout ce qui est graphique et le P_UPDATE_GRAPHE qui permet de positionner le joueur à la bonne position.

La procédure P_DRAW_MAP

Le Restore D_MAP permet de brancher le pointeur au bon endroit pour la lecture des données (datas). Pour cet exemple, nous allons utiliser des données pour créer notre carte.

Nous allons poser la tuile sur l'écran : pour cela, deux boucles FOR, l'une dans l'autre est utile. Je commence toujours par la boucle Y puis par X. 12 cases sur la boucle Y (donc 0 à 11), et 20 cases pour la boucle X (0 à 19).

Un Read ID_MAP permet de lire la première valeur des données. Puis la deuxième au deuxième passage, puis la troisième au troisième passage, etc. A chaque fois cette valeur se mémorise dans la variable ID_MAP.

Maintenant, nous n'avons plus qu'à poser les tuiles au bon endroit avec un Paste Icon X*16,Y*16,ID_MAP. Pourquoi X et Y sont multipliés par 16 ? Car il s'agit de la taille d'une tuile ! Cela permet de poser correctement les tuiles au bon endroit.

Nous réalisons enfin notre carte en données. Pour le moment, je n'ai placé que des "1" car il y a qu'une seule tuile en mémoire. Nous préparons ainsi le prochain tutoriel.

Gestion du clavier

Nous allons passer à la gestion du clavier. Pour notre exemple, nous n'allons utiliser que les touches de direction ainsi que la touche "Echap" pour quitter le programme.

La procédure P_INPUT possède une suite de conditions "Else IF" qui permettent de tester les quatre touches de direction et mémoriser la valeur adéquate dans la variable G_DIRECTION.

La condition Key State(x)=true permet donc de tester une touche du clavier :
  • 76 pour haut.
  • 77 pour bas.
  • 78 pour droite.
  • 79 pour gauche.
  • 69 pour la touche "Echap".
Le "Else" permet de tester s'il n'y pas de touche adéquate d'utilisée ; nous passons alors le G_DIRECTION à 0 et le G_DIRECTION_DOWN aussi. Ceci va éviter dans cet exemple de bouger à fond le joueur quand la touche reste appuyée. Il faudra à chaque fois represser la touche.

Mise à jour du joueur

Maintenant, en fonction de l'action du joueur avec le clavier, nous allons mettre à jour les données de celui-ci. En gros, pour notre exemple, nous allons modifier la position X ou Y de celui-ci. Cela se passe dans la procédure P_UPDATE_PLAYER.

Avec une première condition, nous allons tester si la touche de direction est "relâchée" avec un IF G_DIRECTION_DOWN=0. Puis en fonction du mouvement voulu, nous modifions la valeur X ou Y en adéquation avec celui-ci. Exemple :

If G_DIRECTION=6
G_POSITION_X=G_POSITION_X+1

Cela permet donc d'ajouter 1 à la variable G_POSITION_X. Vu que le mouvement est effectué, nous passons aussi la variable G_DIRECTION_DOWN à 1.

Nous faisons pareil avec les autres directions.

Placer le joueur sur la carte

Nous arrivons à la fin du décryptage de ce premier tutoriel. Nous allons positionner l'avatar du joueur au bon endroit. C'est la fonction P_UPDATE_GRAPHE qui s'occupe de ça après le V_Blank. Pour poser un sprite logiciel, la fonction BOB est bien.

Bob 0,G_POSITION_X*16,G_POSITION_Y*16,1

Nous affichons donc le BOB 0 aux positions X et Y contenues dans les variables G_POSITION_X et G_POSITION_Y que nous multiplions par 16, nous affichons enfin l'image 1 de la banque des BOB.

Pourquoi multiplier par 16 ? Parce que les variables contiennent la position en case, il faut transformer cela en pixel. Ce n'est pas très optimisé, mais bon, ça va marcher. Il est possible de partir directement en pixel dans les deux variables. Il suffit juste d'additionner ou soustraire 16 quand un mouvement se produit.

Voilà, vous pouvez tester et bouger votre avatar case par case !

Passons maintenant à une gestion de collision simple pour bloquer le déplacement du joueur ! Vous allez voir, ceci est un jeu d'enfant, nous allons juste apporter des petites modifications à notre code source.

AMOS

Tutoriel 2 : placer des tuiles qui bloquent !

Pour commencer, nous allons placer une nouvelle tuile, de couleur rouge, qui sera une tuile bloquante dans la banque de mémoire.

AMOS

Modifier les données

Maintenant, nous allons modifier les données (datas) pour afficher le carré rouge où nous le souhaitons sur la carte. A vous de jouer. Il suffit de remplacer dans les données les 1 par des 2.

AMOS

AMOS

Dans mon exemple, mon avatar bleu est sur une case rouge. Nous pouvons définir sa position de départ au début du programme avec un truc du genre :

G_POSITION_X=1
G_POSITION_Y=1

Mémorisation des tuiles bloquantes

Maintenant, il va falloir mémoriser les cases qui bloquent le déplacement du joueur. Pour cela, rien de plus simple qu'un bon tableau. Nous pouvons faire un tableau en deux dimensions, une pour l'entrée X et l'autre pour l'entrée Y. Ceci dit, je vais en profiter pour vous montrer une petite formule mathématique pour trouver l'emplacement X et Y d'un point dans un tableau linéaire en une seule dimension.

La formule est toute simple : position Y du joueur * le nombre de cases de la carte sur une ligne + position X du joueur.

Nous allons initialiser le tableau. Nous savons que notre carte exemple fait 20 cases sur 12. Ce qui fait au total 240 cases. Nous allons créer un tableau de 240 entrées et le rendre global. Toujours au début du programme, nous allons donc faire un :

Dim T_PASSABILITE(240)
Global T_PASSABILITE()

Voilà, nous avons un tableau de 240 cases.

Maintenant, nous allons créer une nouvelle procédure qui va ranger dans le tableau soit une valeur 0, soit une valeur 1, cela dépend si la case est traversable ou pas.

Notre petite procédure est simple pour cet exemple :

Procedure P_MEMORIE_PASSABILITE[ID_TUILE,ID_TABLEAU]
End Proc

Voici donc la procédure. Nous allons lui injecter deux valeurs. Le ID_TUILE qui est simplement la valeur de la tuile à poser. Et ID_TABLEAU qui est simplement la case du tableau à modifier en fonction des valeurs de boucle.

Dans la procédure, la routine est simple, nous allons tester l'id (identifiant) de la tuile et si la tuile bloque, nous plaçons la valeur 1 et si la tuile permet de bouger dessus, nous plaçons la valeur 0.

If ID_TUILE=1
PASSE = 0
else IF ID_TUILE=2
PASSE = 1
end if

Nous pouvons configurer d'autres tuiles avec ça...

Et enfin, nous inscrivons la valeur de PASSE dans le tableau :

T_PASSABILITE(ID_TABLEAU)=PASSE

Nous en avons fini avec cette procédure. Maintenant, il faut l'appeler dans le P_DRAW_MAP et injecter les bonnes valeurs après le Read ID_MAP :

P_MEMORIE_PASSABILITE[ID_MAP,ID_TABLEAU]

Nous allons mettre en place une variable pour connaître l'index de la boucle et savoir quelle est la case du tableau que nous devons modifier. Un simple ID_TABLEAU=ID_TABLEAU+1 va convenir à cela. Il ne nous reste plus qu'à appeler notre procédure et qu'à injecter les valeurs voulues.

AMOS

Cette partie est terminée, nous allons passer maintenant au blocage du mouvement.

Interdire le mouvement

Cela se passe dans la mise à jour (update) du joueur. C'est très simple : si le joueur veut se déplacer à droite, nous allons tester la case à sa droite voir s'il peut bouger dessus ou pas. Pour cela, nous allons simplement aller interroger la case du tableau adéquate pour savoir si c'est 0 ou 1. Exemple sur le déplacement de droite :

If G_DIRECTION=6 and T_PASSABILITE(G_POSITION_Y*20+G_POSITION_X+1)=0
...
...

Nous faisons donc un double test pour savoir si le joueur peut se déplacer à droite et modifier les coordonnées de celui-ci. Nous utilisons bien la formule donnée plus haut (Y*Nombre_de_case+X) et comme nous voulons tester la case de droite, ce sera X=X+1. Pour la gauche, ce sera X=X-1. Pour la case de haut : Y=Y-1. Pour la case du bas : Y=Y+1 (ne pas oublier de placer des parenthèses pour Y ! Nous modifions au début Y pour trouver la ligne et après nous faisons la multiplication).

AMOS

' =================================
' === Déplacement Case par Case ===
' =================================

' ------------------------------------------------ 
' --- Mise en place des paramètres de l'écran --- 
' ------------------------------------------------ 
Screen Open 0,320,200,16,Lowres
Flash Off 
Curs Off 

' ------------------------ 
' --- Variable Globale --- 
' ------------------------ 
Global G_QUIT
Global G_POSITION_X,G_POSITION_Y
Global G_DIRECTION,G_DIRECTION_DOWN

' -------------------------------------------- 
' --- Initiation du tableau de passabilité --- 
' ---------------------------------------------


Dim T_PASSABILITE(240)
Global T_PASSABILITE()


' -------------------------------
' --- Initiation du programme ---
' -------------------------------
G_POSITION_X=1
G_POSITION_Y=1


' -------------------------------- 
' --- Affichage de la map test --- 
' -------------------------------- 
P_DRAW_MAP


' ---------------------
' --- Boucle du jeu ---
' ---------------------
While(G_QUIT=0)

' ### Partie Logique ### 
P_INPUT
P_UPDATE_PLAYER

' ### Attente du V Blank ### 
Wait Vbl 

' ### Partie Graphique ### 
P_UPDATE_GRAPHE

Wend 

Rem ***************************************
Rem *** Procedure d'affichage de la map ***
Rem ***************************************
Procedure P_DRAW_MAP
Restore D_MAP

' ------------------------------------ 
' --- Boucle pour poser les tuiles --- 
'------------------------------------- 

For Y=0 To 11
For X=0 To 19

Read ID_MAP

P_MEMORIE_PASSABILITE[ID_MAP,ID_TABLEAU]
ID_TABLEAU=ID_TABLEAU+1

Paste Icon X*16,Y*16,ID_MAP

Next 
Next 

'----------------- 
' --- Map Test --- 
'----------------- 
D_MAP:
Data 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2



End Proc

Rem ***************************************
Rem *** Procedure de Gestion du clavier ***
Rem ***************************************

' -------------------------- 
' Valeur de G_Direction :
' 8 = Haut 
' 2 = Bas
' 4 = Droite 
' 6 = Gauche 
' -------------------------- 

Procedure P_INPUT


If Key State(76)=True
G_DIRECTION=8

Else If Key State(77)=True
G_DIRECTION=2

Else If Key State(78)
G_DIRECTION=6

Else If Key State(79)=True
G_DIRECTION=4

Else If Key State(69)=True
End 
Else 
G_DIRECTION=0
G_DIRECTION_DOWN=0

End If 


End Proc


Rem *****************************
Rem *** Mise à jour du joueur ***
Rem *****************************
Procedure P_UPDATE_PLAYER

If G_DIRECTION_DOWN=0

If G_DIRECTION=6 and T_PASSABILITE(G_POSITION_Y*20+G_POSITION_X+1)=0
G_POSITION_X=G_POSITION_X+1
G_DIRECTION_DOWN=1

Else If G_DIRECTION=4 and T_PASSABILITE(G_POSITION_Y*20+G_POSITION_X-1)=0
G_POSITION_X=G_POSITION_X-1
G_DIRECTION_DOWN=1

Else If G_DIRECTION=8 and T_PASSABILITE((G_POSITION_Y-1)*20+G_POSITION_X)=0
G_POSITION_Y=G_POSITION_Y-1
G_DIRECTION_DOWN=1

Else If G_DIRECTION=2 and T_PASSABILITE((G_POSITION_Y+1)*20+G_POSITION_X)=0
G_POSITION_Y=G_POSITION_Y+1
G_DIRECTION_DOWN=1

End If 
End If 
End Proc

Rem ********************************** 
Rem *** Mise à jour des graphismes *** 
Rem ********************************** 
Procedure P_UPDATE_GRAPHE
Bob 0,G_POSITION_X*16,G_POSITION_Y*16,1

End Proc


Rem ********************************************** 
Rem *** Mémorisation du tableau de passabilité *** 
Rem ********************************************** 

Procedure P_MEMORIE_PASSABILITE[ID_TUILE,ID_TABLEAU]

If ID_TUILE=1
PASSE=0
Else If ID_TUILE=2
PASSE=1
End If 

T_PASSABILITE(ID_TABLEAU)=PASSE

End Proc

Fluidifions le mouvement

Un déplacement case par case "strict" comme ça c'est bien, mais voir le déplacement du carré bouger petit à petit, c'est bien mieux ! Pas de panique, nous allons mettre une petite base en place !

Dans la déclaration des variables globales, nous allons déclarer quatre compteurs de mouvement qui vont nous permettre de faire des cycles de mouvement :

Global G_MVT_GAUCHE,G_MVT_DROITE,G_MVT_HAUT,G_MVT_BAS

AMOS

Pour notre exemple, nous allons nous baser sur cela pour savoir si l'avatar bouge. Nous allons devoir transformer la G_Position_X et G_Position_Y en mode pixel et non en case cette fois-ci.

Dans l'initiation du programme, j'ai passé les deux variables à 16, et dans la mise à jour des graphismes, j'ai retiré les *16. Nous affichons directement la position en fonction du contenu exact de la variable.

Le plus gros du travail se trouve dans le P_Update_Player. Les conditions pour tester les collisions sont directement en case. Dans nos variables, c'est maintenant au format pixel, il faut donc transformer tout cela en case : nous appliquons ici une division. La taille du bloc est de 16 pixels, donc nous allons diviser les X et les Y par 16. Nous allons obtenir des cases et pouvoir tester notre collision.

Un petit truc rigolo en AMOS (et d'autres langages de programmation), c'est qu'avec ce genre de division, les virgules sont effacées et nous avons vraiment des cases. Exemple : 36/3 ne donnera pas 2,25 mais bien 2... C'est chouette, non ?

Voici l'exemple pour le déplacement droite :

If G_DIRECTION=6 and T_PASSABILITE(G_POSITION_Y/16*20+G_POSITION_X/16+1)=0

Maintenant, nous allons enclencher le déplacement droite. Pour cela, nous allons mettre la variable G_MVT_DROITE à 8 tout simplement.

Voici donc la nouvelle condition pour la droite :

If G_DIRECTION=6 and T_PASSABILITE(G_POSITION_Y/16*20+G_POSITION_X/16+1)=0
G_MVT_DROITE=8
G_DIRECTION_DOWN=1

Bon, il va falloir apporter un petit truc dans la condition générale, là où nous testons si G_DIRECTION_DOWN=1. Nous allons ajouter (ou remplacer) cela pour tester s'il n'y a aucun mouvement de l'avatar. Il faut donc que tous les G_MVT... soient à 0. Rien de plus simple, nous allons faire une addition de tous les G_MVT et tester si c'est égal à 0.

If(G_MVT_GAUCHE+G_MVT_DROITE+G_MVT_HAUT+G_MVT_BAS)=0 and G_DIRECTION_DOWN=0

AMOS

Maintenant, il reste à produire le mouvement.

Toujours pour cet exemple, dans le P_Update_Player nous allons tester si le G_MVT_DROITE est >0 et si cela est vrai. Nous ajoutons alors 2 à la variable G_POSITION_X et nous retirons 1 à la variable G_MVT_DROITE. A chaque boucle cette action sera réalisée et nous aurons un déplacement. Voici le petit code pour le mouvement droite :

If G_MVT_DROITE>0
G_POSITION_X=G_POSITION_X+2
G_MVT_DROITE=G_MVT_DROITE-1

C'est la même chose pour les autres mouvements. Voici le code source de la version fluidifiée :

' =================================
' === Déplacement Case par Case ===
' === MVT Fluide ===
' =================================

' ------------------------------------------------ 
' --- Mise en place des paramètres de l'écran --- 
' ------------------------------------------------ 
Screen Open 0,320,200,16,Lowres
Flash Off 
Curs Off 

' ------------------------ 
' --- Variable Globale --- 
' ------------------------ 
Global G_QUIT
Global G_POSITION_X,G_POSITION_Y
Global G_DIRECTION,G_DIRECTION_DOWN
Global G_MVT_DROITE,G_MVT_GAUCHE,G_MVT_HAUT,G_MVT_BAS

' -------------------------------------------- 
' --- Initiation du tableau de passabilité --- 
' ---------------------------------------------


Dim T_PASSABILITE(240)
Global T_PASSABILITE()


' -------------------------------
' --- Initiation du programme ---
' -------------------------------
G_POSITION_X=16
G_POSITION_Y=16


' ---------------------------------- 
' --- Affichage de la carte test --- 
' ---------------------------------- 
P_DRAW_MAP


' ---------------------
' --- Boucle du jeu ---
' ---------------------
While(G_QUIT=0)

' ### Partie Logique ### 
P_INPUT
P_UPDATE_PLAYER

' ### Attente du V Blank ### 
Wait Vbl 

' ### Partie Graphique ### 
P_UPDATE_GRAPHE

Wend 

Rem *****************************************
Rem *** Procedure d'affichage de la carte ***
Rem *****************************************
Procedure P_DRAW_MAP
Restore D_MAP

' ------------------------------------ 
' --- Boucle pour poser les tuiles --- 
'------------------------------------- 

For Y=0 To 11
For X=0 To 19

Read ID_MAP

P_MEMORIE_PASSABILITE[ID_MAP,ID_TABLEAU]
ID_TABLEAU=ID_TABLEAU+1

Paste Icon X*16,Y*16,ID_MAP

Next 
Next 

'----------------- 
' --- Map Test --- 
'----------------- 
D_MAP:
Data 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2
Data 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2


End Proc

Rem ***************************************
Rem *** Procédure de gestion du clavier ***
Rem ***************************************

' -------------------------- 
' Valeur de G_Direction :
' 8 = Haut 
' 2 = Bas
' 4 = Droite 
' 6 = Gauche 
' -------------------------- 

Procedure P_INPUT

If Key State(76)=True
G_DIRECTION=8

Else If Key State(77)=True
G_DIRECTION=2

Else If Key State(78)
G_DIRECTION=6

Else If Key State(79)=True
G_DIRECTION=4

Else If Key State(69)=True
End 
Else 
G_DIRECTION=0
G_DIRECTION_DOWN=0

End If 



End Proc


Rem *****************************
Rem *** Mise à jour du joueur ***
Rem *****************************
Procedure P_UPDATE_PLAYER

If(G_MVT_GAUCHE+G_MVT_DROITE+G_MVT_HAUT+G_MVT_BAS)=0 and G_DIRECTION_DOWN=0


Rem -------------------------
Rem -- Tester la direction --
Rem -------------------------

If G_DIRECTION=6 and T_PASSABILITE(G_POSITION_Y/16*20+G_POSITION_X/16+1)=0
G_MVT_DROITE=8
G_DIRECTION_DOWN=1

Else If G_DIRECTION=4 and T_PASSABILITE(G_POSITION_Y/16*20+G_POSITION_X/16-1)=0
G_MVT_GAUCHE=8
G_DIRECTION_DOWN=1

Else If G_DIRECTION=8 and T_PASSABILITE((G_POSITION_Y/16-1)*20+G_POSITION_X/16)=0
G_MVT_HAUT=8
G_DIRECTION_DOWN=1

Else If G_DIRECTION=2 and T_PASSABILITE((G_POSITION_Y/16+1)*20+G_POSITION_X/16)=0
G_MVT_BAS=8
G_DIRECTION_DOWN=1


End If 
End If 

Rem -------------------------
Rem -- Mouvement du joueur --
Rem -------------------------

If G_MVT_DROITE>0
G_POSITION_X=G_POSITION_X+2
G_MVT_DROITE=G_MVT_DROITE-1

Else If G_MVT_GAUCHE>0
G_POSITION_X=G_POSITION_X-2
G_MVT_GAUCHE=G_MVT_GAUCHE-1

Else If G_MVT_HAUT>0
G_POSITION_Y=G_POSITION_Y-2
G_MVT_HAUT=G_MVT_HAUT-1

Else If G_MVT_BAS>0
G_POSITION_Y=G_POSITION_Y+2
G_MVT_BAS=G_MVT_BAS-1
End If 


End Proc

Rem ********************************** 
Rem *** Mise à jour des graphismes *** 
Rem ********************************** 
Procedure P_UPDATE_GRAPHE
Bob 0,G_POSITION_X,G_POSITION_Y,1

End Proc


Rem ********************************************** 
Rem *** Mémorisation du tableau de passabilité *** 
Rem ********************************************** 

Procedure P_MEMORIE_PASSABILITE[ID_TUILE,ID_TABLEAU]


If ID_TUILE=1
PASSE=0
Else If ID_TUILE=2
PASSE=1
End If 

T_PASSABILITE(ID_TABLEAU)=PASSE

End Proc

Voilà donc un début de jeu en mode case par case. Vous avez appris à tester les cases adjacentes, vous pouvez faire de même maintenant avec la case où se situe votre avatar pour, par exemple, ramasser un objet.

Il y a donc de quoi débuter des jeux de labyrinthe ou des petits RPG. Il y a bien sûr plein de trucs à améliorer. Mais vous avez une base de travail pour vous amuser avec l'AMOS sur Amiga.


[Retour en haut] / [Retour aux articles]