Créer une grille avec Game Maker Studio 2

Si vous souhaitez créer un niveau en damier pour un jeu d’échec, ou un jeu en tour par tour comme Advance Wars 2 (qui en passant est un jeu formidable, si vous ne connaissez pas, jouez-y !), vous êtes au bon endroit pour débuter. Dans ce tutoriel, nous apprendrons à créer une grille à l’aide d’un tableau en 2 dimensions. Puis nous remplirons cette grille des différents objets contenus dans notre niveau.

Advance Wars 2 – L’original, pas l’autre.

Introduction rapide : le tableau en 2D

Quand je parle de tableau en 2D sur GameMaker Studio, c’est tout simplement un tableau dont chaque entrée contient… un autre tableau. La plupart des langages de développement possèdent ce type de variables, et c’est un incontournable dans le jeu vidéo. De cette façon, on peut stocker de nombreuses informations de façon ordonnée, que ce soit notre futur level ou bien une liste de personnages et leurs couleurs favorites :

// Player
array_2d = [
    ["Mario", "Red", 1],
    ["Luigi", "Green", 2],
    ["Peach", "Pink" , 3]
];

// Output result
array_2d[0,0] = "Mario";
array_2d[0,1] = "Red";
array_2d[0,2] = "1";

Pour en savoir plus, je vous invite à vous rendre sur cette page.

Initialisation et création de la grille

Pour commencer, nous allons créer un objet qui s’appelle oGrid et initialiser dans son create event un tableau en 2D qui nous servira de niveau. Nous souhaitons obtenir un niveau de 20 cases en long et en large, avec des cases de 32 pixels.

// Create event oGrid

depth = -1000;

// Width & Height size
gridWidth  = 20;
gridHeight = 20;

// Box size
boxSize = 32;

// Create 2D array filled with 0
for(var i = 0; i < gridWidth; i++){
    for(var j = 0; j < gridHeight; j ++){
        global.grid[i, j] = 0;
    }
}

Plaçons cet objet dans notre room et… Félicitations ! Nous avons un objet oGrid qui contient un tableau en 2D :

  • depth -1000 de cette façon la grille est au-dessus du reste
  • gridWidth et gridHeight c’est la taille de la grille
  • boxSize c’est la taille de chaque case
  • Et global.grid la variable qui contient notre grille, actuellement toutes les cases contiennent la valeur « 0 »

Vous l’avez vu, nous utilisons le mot global pour définir notre grille. Étant un élément essentiel de notre jeu, et comme nous allons souvent l’utiliser c’est mieux de se servir de ce type de variable.

A basic description of a global variable is one that, once declared, it belongs to no instance in particular and yet can be accessed by all.

Game Maker Studio

Dessiner la grille avec la fonction draw_line()

Pour visualiser notre tableau en 2D nous pouvons utiliser l’outil de debug proposé par Game Maker Studio, puis examiner ce que contient la variable global.grid. La deuxième solution est de le dessiner à l’écran. Sachant que cette solution nous facilite la vie lors de la phase de debug, voici ce que nous devons écrire dans le draw event de l’objet oGrid pour faire apparaître notre grille :

// Draw event oGrid

// Set opacity & color
draw_set_alpha(.5);
draw_set_color(c_green);

// Loop trought each row and column
for (var i = 0; i < gridWidth; i+=1){
    draw_line(0, i*boxSize, room_width, i*boxSize);
}

for (var j = 0; j < gridHeight; j+=1) {
    draw_line(j*boxSize, 0, j*boxSize, room_height);
}

// Reset opacity & color
draw_set_color(c_white);
draw_set_alpha(1);

Avec ces quelques lignes de code, nous affichons maintenant les 400 cases (20 * 20, je suis une bille en maths, mais là, c’est bon) de notre level :

  • draw_set_alpha et draw_set_opacity permettent de modifier l’opacité et la couleur des lignes
  • Les deux boucles for parcourent la grille
  • Et draw_line dessine des lignes horizontales et verticales à chaque itération
Comme promis, une grille de 20×20 avec GameMaker

Ajouter des murs dans le niveau

Ajoutons des éléments dans notre niveau, puis transférons-les dans notre grille. Je propose que nous ajoutions des murs : pour ça, il faut créer un objet oWall et lui assigner un sprite. Pour ce tutoriel, je conseille d’utiliser un sprite de 32px par 32px.

Ensuite, utilisons l’éditeur de room disponible sur Game Maker pour placer l’objet en question dans le niveau. Afin de se faciliter la tâche, réglons la taille de la grille sur 32px et utilisons la fonctionnalité snap, de cette façon les éléments seront toujours positionnés sur un multiple de 32.

L’option « snap » sur GameMaker Studio

À ce stade là, nous avons une grille de dessinée et des objets dans notre niveau, mais les deux ne sont pas liés. En effet, les objets sont présents dans la room, mais à aucun moment nous ne les avons ajouté à notre variable global.grid. Je ne fais pas durer le suspens plus longtemps, c’est ce que nous allons faire maintenant.

Insérer les murs dans la grille

// Create event oWall

// Array position
var _x = x / oGrid.boxSize;
var _y = y / oGrid.boxSize;

// Add id to the array
array_set(global.grid[_x], _y, id);

Félicitations, chaque objet oWall de notre room est désormais ajouté à notre grille lors de sa création. Attention, pour que cela fonctionne, assurez-vous que l’objet oGrid soit créé avant vos objets oWall dans l’ordre de création de votre room, sinon vous allez tenter d’accéder à une variable qui n’existe pas encore.

Notre niveau est maintenant entouré de murs

Ajouter des objets sur plusieurs cases en même temps

Imaginons un monde où l’un de vos murs mesure 32px de large pour 16px de haut (incroyable, je sais). Avec notre code, il sera ajouté seulement sur la case où se trouve son origine, et non pas sur toutes les cases qu’il chevauche. Voici comment régler ce problème :

// Create event oWall

// Array position
var _x = x / oGrid.boxSize;
var _y = y / oGrid.boxSize;

// Obj size
var _width  = sprite_width / oGrid.boxSize;
var _height = sprite_height / oGrid.boxSize;

// Add the id of the object on the grid
for (var i = 0; i < _width; ++i) { 
    for (var j = 0; j < _height; ++j) {
        // Add id to the array
        array_set(global.grid[i + _x], j + _y, id);
    }
}
  • On calcule la taille de l’objet par rapport à ses variables sprite_width et sprite_height
  • On traduit ça en nombre de cases avec / oGrid.boxSize
  • On boucle sur ces dernières et on modifie array_set() pour ajouter l’objet sur les cases en question

Détecter les murs contenus dans la grille

C’est super, maintenant notre grille contient l’identifiant des objets ajoutés dans la room. Essayons de modifier notre code pour visualiser la grille afin d’afficher les cases bloquées par des murs.

// Draw event oGrid

// Set opacity & color
draw_set_alpha(.5);
draw_set_color(c_green);

// Loop trought each row and column
for (var i = 0; i < gridWidth; i+=1){
    draw_line_width(0, i*boxSize, room_width, i*boxSize, 1);
}

for (var j = 0; j < gridHeight; j+=1) {
    draw_line_width(j*boxSize, 0, j*boxSize, room_height, 1);
}

// Display values
for (var i = 0; i < gridWidth; i+=1) {
    for (var j = 0; j < gridHeight; j+=1) {
        var _value = array_get(global.grid[i], j);
        if(_value != 0) {
            draw_set_color(c_red);
            draw_rectangle(i * boxSize, j * boxSize, i * boxSize + boxSize, j * boxSize + boxSize, false);
        }

    }
}

// Reset opacity & color
draw_set_color(c_white);
draw_set_alpha(1);
  • Notre tableau est parcouru avec les boucles for
  • Puis les valeurs contenues pour chaque itération sont récupérées avec array_get(global.grid[i], j)
  • Et enfin, si c’est différent de 0 qui est notre valeur de base, on affiche un rectangle rouge avec draw_rectangle()
Les rectangles rouges représentent les murs stockés dans notre tableau

Conclusion

Nous avons une grille, qui contient les murs de notre room, et nous savons comment les détecter. Et c’est tout pour ce tutoriel ! Voici ce que vous pouvez faire ensuite :

  • Ajouter plus d’un objet par case
  • Détruire un mur au clic sur la bonne case
  • Ajouter des éléments à la volée
  • Déplacer un personnage case par case en vérifiant s’il y a une collision
  • Ou encore utiliser des algorithmes de path finding pour s’assurer qu’un chemin est disponible

Si vous avez des questions sur ce tutoriel ou un besoin spécifique, dites-le moi en commentaire que l’on puisse en parler ensemble.

À plus !

Clément 'Indieklem' Jacquelin - Auteur
Clément "Indieklem" Jacquelin

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *