Dans ce didacticiel, je vais vous aider à créer des niveaux pour n’importe quel genre de jeu et à rendre la conception des niveaux beaucoup plus facile. Vous allez apprendre à créer votre premier moteur de carte en mosaïque à utiliser dans l’un de vos projets futurs. Je vais utiliser Haxe avec OpenFL, mais vous devriez pouvoir suivre dans n'importe quelle langue..
Voici ce que nous allons couvrir:
Vous pourriez aussi bien commencer une nouvelle idée de jeu.!
Naturellement, Wikipedia a une définition détaillée de ce qu’est un jeu basé sur des tuiles, mais pour comprendre l’essentiel, il n’ya que quelques points à connaître:
Pour être encore plus basique, je vais le mettre comme ceci:
Un jeu basé sur des tuiles établit des tuiles afin de créer chaque niveau.
En référence aux types de carreaux courants - rectangulaire et isométrique - nous utiliserons les carreaux rectangulaires dans cet article pour leur simplicité. Si vous décidez d’essayer des niveaux isométriques un jour, des calculs supplémentaires sont nécessaires pour que cela fonctionne. (Une fois que vous avez terminé ici, consultez ce guide de base sur la création de mondes isométriques.)
L'utilisation d'un moteur de tuiles présente des avantages intéressants. L'avantage le plus évident est que vous n'aurez pas besoin de créer des images massives à la main pour chaque niveau. Cela réduira le temps de développement et la taille des fichiers. Avoir 50 images de 1280x768px pour un jeu à 50 niveaux et avoir une image avec 100 tuiles fait toute la différence.
Un autre effet secondaire est que la localisation d'éléments sur votre carte à l'aide de code devient un peu plus facile. Au lieu de vérifier des éléments tels que les collisions basées sur un pixel exact, vous pouvez utiliser une formule simple et rapide pour déterminer la mosaïque à laquelle vous devez accéder. (J'y reviendrai un peu plus tard.)
La première chose dont vous aurez besoin pour construire votre moteur de tuiles est un ensemble de tuiles. Vous avez deux options: utiliser les carreaux de quelqu'un d'autre ou créer votre propre.
Si vous décidez d'utiliser des carreaux déjà réalisés, vous pourrez trouver des œuvres d'art librement disponibles sur le Web. L'inconvénient est que cet art n'a pas été conçu spécialement pour votre jeu. D'un autre côté, si vous ne faites que du prototypage ou que vous essayez d'apprendre un nouveau concept, les tuiles gratuites feront l'affaire..
Il existe assez peu de ressources sur l'art libre et open source. Voici quelques endroits pour commencer votre recherche:
Ces trois liens devraient vous donner suffisamment d’espace pour trouver des tuiles correctes pour vos prototypes. Avant de devenir fou en prenant tout ce que vous trouvez, assurez-vous de bien comprendre en quoi une licence est couverte par une licence et quelles sont les restrictions associées. De nombreuses licences vous permettent d’utiliser l’art librement et à des fins commerciales, mais elles peuvent nécessiter une attribution..
Pour ce tutoriel, j'ai utilisé des tuiles d'un lot artistique The Open Game pour les utilisateurs de plateformes. Vous pouvez télécharger mes versions réduites ou les originaux.
Si vous n'avez pas encore plongé dans la création artistique pour vos jeux, cela pourrait être un peu intimidant. Heureusement, il existe des logiciels simples et étonnants qui vous plongent dans le vif du sujet et vous permettent de commencer à vous entraîner..
De nombreux développeurs débutent avec le pixel art pour leurs jeux et voici quelques excellents outils:
Ce sont quelques-uns des programmes les plus populaires pour la création de pixel art. Si vous voulez quelque chose d'un peu plus puissant, GIMP est une excellente option. Vous pouvez également réaliser des dessins vectoriels avec Inkscape et suivre des didacticiels étonnants sur 2D Game Art For Programmers..
Une fois que vous avez saisi le logiciel, vous pouvez commencer à expérimenter pour créer vos propres tuiles. Puisque ce tutoriel est destiné à vous montrer comment créer votre carte de tuiles moteur Je n'entrerai pas dans les détails sur la fabrication des carreaux eux-mêmes, mais il y a une chose à toujours garder à l'esprit:
Assurez-vous que vos carreaux s'agencent parfaitement et ajoutez des variations pour les garder intéressants.
Si vos tuiles montrent des lignes évidentes entre elles lorsqu'elles sont assemblées, votre jeu ne sera pas très joli. Assurez-vous de consacrer du temps à la création d'un joli "puzzle" de tuiles en les rendant transparentes et en ajoutant des variations..
Maintenant que nous avons tous ces trucs d’art, nous pouvons plonger dans le code pour afficher vos vignettes nouvellement acquises (ou créées)..
Commençons par la tâche très élémentaire d’affichage d’une seule tuile à l’écran. Assurez-vous que vos carreaux ont tous la même taille et sont enregistrés dans des fichiers image séparés (nous parlerons plus en détail des feuilles de sprite)..
Une fois que vous avez les tuiles dans votre dossier d’actifs de votre projet, vous pouvez écrire un très simple Tuile
classe. Voici un exemple dans Haxe:
import flash.display.Sprite; import flash.display.Bitmap; importer openfl.Assets; class Tile s étend Sprite private var image: Bitmap; fonction publique new () super (); image = new Bitmap (Assets.getBitmapData ("assets / grassLeftBlock.png")); addChild (image);
Comme tout ce que nous faisons maintenant consiste à placer une seule mosaïque à l'écran, la seule chose que la classe fait est d'importer l'image de mosaïque à partir du les atouts
dossier et l'ajouter en tant qu'enfant à l'objet. Cette classe variera probablement beaucoup en fonction du langage de programmation que vous utilisez, mais vous devriez pouvoir trouver facilement un guide sur la manière d'afficher une image à l'écran..
Maintenant que nous avons un Tuile
classe, nous devons créer une instance d'un Tuile
et l'ajouter à notre classe principale:
import flash.display.Sprite; import flash.events.Event; importer flash.Lib; la classe Main étend Sprite fonction publique new () super (); var tile = new Tile (); addChild (tuile); fonction statique publique main () Lib.current.addChild (new Main ());
le Principale
la classe crée un nouveau Tuile
lorsque le constructeur (le Nouveau()
fonction, appelée lorsque le jeu commence) est appelée et l'ajoute à la liste d'affichage.
Lorsque le jeu est lancé, le principale()
fonction sera également appelée, et une nouvelle Principale
objet sera ajouté à la scène. Vous devriez maintenant avoir votre tuile apparaissant tout en haut à gauche de l'écran. Jusqu'ici tout va bien.
Pointe: Si rien de tout cela n'a de sens, ne vous inquiétez pas! C'est juste le code standard standard Hache. La chose clé à comprendre est que cela crée un Tuile
objet et l'ajoute à l'écran.
L'étape suivante consiste à trouver un moyen de remplir tout l'écran avec des carreaux. L’un des moyens les plus simples consiste à remplir un tableau avec des entiers représentant chacun un ID de tuile. Ensuite, vous pouvez parcourir le tableau pour décider quelle mosaïque afficher et où l’afficher..
Vous avez la possibilité d'utiliser un tableau typique ou un tableau à 2 dimensions. Au cas où vous ne maîtriseriez pas les tableaux 2D, il s’agirait en principe d’un tableau unique rempli de plusieurs tableaux. La plupart des langues vont indiquer cela comme nameOfArray [x] [y]
où X
et y
sont des indices pour accéder à un seul élément.
Puisque X
et y
sont également utilisés pour les coordonnées de l'écran, il peut être judicieux d'utiliser X
et y
comme coordonnées pour nos carreaux. Le truc avec les tableaux 2D consiste à comprendre comment les entiers sont organisés. Vous pourriez avoir à inverser la y
et X
lors d'une itération dans les tableaux (exemple ci-dessous).
private var exampleArr = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]];
Notez que dans cette implémentation, l'élément "0th" du tableau est lui-même un tableau de cinq entiers. Cela signifierait que vous accédez à chaque élément avec y
premier, puis X
. Si vous essayez d'accéder exampleArr [1] [0]
, vous accéderiez au sixième tuile.
Si vous ne comprenez pas très bien comment fonctionnent les tableaux 2D, ne vous inquiétez pas. Pour ce tutoriel, je vais utiliser un tableau normal afin de simplifier les choses et de les rendre plus faciles à visualiser:
private var exampleArr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0];
L'exemple ci-dessus montre comment un tableau normal peut être un peu plus simple. Nous pouvons visualiser exactement où la tuile sera et tout ce que nous avons à faire est d'utiliser une formule simple (ne vous inquiétez pas, ça arrive!) Pour obtenir la tuile que nous voulons..
Maintenant écrivons du code pour créer notre tableau et remplissons-le. Le numéro un sera l'identifiant qui représente notre première tuile.
Nous devons d’abord créer une variable dans notre classe Main pour contenir notre tableau:
carte var privée: Array;
Cela peut sembler un peu étrange, alors je vais le décomposer pour vous.
Le nom de la variable est map et je lui ai donné un type très spécifique: Tableau
. le
La partie indique simplement à notre programme que le tableau ne contiendra que des entiers. Les tableaux peuvent contenir n'importe quel type. Par conséquent, si vous utilisez autre chose pour identifier vos mosaïques, n'hésitez pas à modifier le paramètre ici..
Ensuite, nous devons ajouter du code à notre Principale
Le constructeur de la classe (rappelez-vous, c'est le Nouveau()
fonction) afin que nous puissions créer une instance de notre carte:
map = nouveau tableau();
Cette ligne créera un tableau vide que nous pourrons bientôt remplir avec notre pour le tester. Tout d’abord, définissons quelques valeurs qui nous aideront dans nos calculs:
public static var TILE_WIDTH = 60; public static var TILE_HEIGHT = 60; public static var SCREEN_WIDTH = 600; public static var SCREEN_HEIGHT = 360;
J'ai fait ces valeurs statique publique
parce que cela nous donnera accès à eux de n’importe où dans notre programme (via Main.Tile_WIDTH
etc). En outre, vous avez peut-être remarqué que la division SCREEN_WIDTH
par TILE_WIDTH
nous donne dix
et divisant SCREEN_HEIGHT
par TILE_HEIGHT
nous donne 6
. Ces deux nombres seront utilisés pour décider du nombre d'entiers à stocker dans notre tableau.
var w = Std.int (SCREEN_WIDTH / TILE_WIDTH); var h = Std.int (SCREEN_HEIGHT / TILE_HEIGHT); pour (i dans 0… w * h) map [i] = 1
Dans ce bloc de code, nous assignons dix
et 6
à w
et h
, comme je l'ai mentionné ci-dessus. Ensuite, nous devons sauter dans un pour
boucle pour créer un tableau qui peut tenir 10 * 6
entiers. Cela représentera assez de tuiles pour remplir tout l'écran.
Nous avons maintenant construit notre carte de base, mais comment allons-nous dire aux tuiles de se mettre à leur place? Pour cela, nous devons revenir à la Tuile
classe et créer une fonction qui nous permettra de déplacer les tuiles à volonté:
fonction publique setLoc (x: Int, y: Int) image.x = x * Main.TILE_WIDTH; image.y = y * Main.TILE_HEIGHT;
Quand on appelle le setLoc ()
fonction, nous passons dans le X
et y
coordonnées en fonction de notre classe de carte (formule à venir, je vous le promets!). La fonction prend ces valeurs et les traduit en coordonnées de pixel en les multipliant par TILE_WIDTH
et TILE_HEIGHT
, respectivement.
La seule chose qui reste à faire pour obtenir nos carreaux à l’écran est de dire à notre Principale
classe pour créer les tuiles et les mettre en place en fonction de leur emplacement sur la carte. Revenons à Principale
et mettre en œuvre que:
pour (i dans 0… map.length) var tile = new Tile (); var x = i% w; var y = Math.floor (i / w); tile.setLoc (x, y); addChild (tuile);
Oh oui! C'est vrai, nous avons maintenant un écran plein de tuiles. Décomposons ce qui se passe ci-dessus.
La formule que je continue de mentionner est enfin là.
Nous calculons X
en prenant le module (%
) de je
et w
(qui est 10, rappelez-vous).
Le module est juste le reste après la division entière: \ (14 \ div 3 = 4 \ text reste 2 \) so \ (14 \ text modulus 3 = 2 \).
Nous utilisons cela parce que nous voulons que notre valeur de X
pour revenir à 0
au début de chaque ligne, nous dessinons donc la tuile respective à l'extrême gauche:
Pour ce qui est de y
, nous prenons le sol()
de i / w
(c’est-à-dire que nous arrondissons ce résultat à la baisse) parce que nous ne voulons que y
pour augmenter une fois que nous avons atteint la fin de chaque ligne et avons descendu d’un niveau:
Math.floor ()
en divisant des nombres entiers; Haxe gère simplement la division entière différemment. Si vous utilisez une langue qui divise en nombres entiers, vous pouvez simplement utiliser i / w
(en supposant qu'ils soient tous deux entiers). Enfin, je voulais parler un peu des niveaux de défilement. Généralement, vous ne créez pas de niveaux qui correspondent parfaitement à votre fenêtre. Vos cartes seront probablement beaucoup plus grandes que l'écran et vous ne voudrez plus continuer à dessiner des images que le lecteur ne pourra pas voir. Avec quelques calculs simples et rapides, vous devriez pouvoir calculer quelles mosaïques doivent être affichées à l’écran et lesquelles ne doivent pas être dessinées..
Par exemple: votre taille d'écran est 500x500, vos tuiles sont 100x100 et votre taille mondiale est 1000x1000. Avant de dessiner des tuiles, il vous suffirait de faire une vérification rapide pour savoir quelles sont les tuiles affichées à l'écran. En utilisant l'emplacement de votre fenêtre d'affichage - 400x500, par exemple - il vous suffirait de dessiner des mosaïques des lignes 4 à 9 et des colonnes 5 à 10. Vous pouvez obtenir ces nombres en divisant l'emplacement par la taille de la mosaïque, puis en décalant ces valeurs avec l'écran. taille divisée par la taille de la tuile. Simple.
Cela pourrait ne pas sembler beaucoup, car toutes les tuiles sont identiques, mais les fondations sont presque là. Il ne reste plus qu'à créer différents types de carreaux et à concevoir notre carte de manière à ce qu'ils s'alignent et créent quelque chose de joli..
Très bien, nous avons maintenant une carte qui est pleine de celles qui couvrent l’écran. À ce stade, vous devriez avoir plus d’un type de tuile, ce qui signifie que nous devons changer notre Tuile
constructeur à rendre compte de cela:
fonction publique new (id: Int) super (); switch (id) case 1: image = new Bitmap (Assets.getBitmapData ("assets / grassLeftBlock.png")); cas 2: image = new Bitmap (Assets.getBitmapData ("assets / grassCenterBlock.png")); cas 3: image = new Bitmap (Assets.getBitmapData ("assets / grassRightBlock.png")); cas 4: image = new Bitmap (Assets.getBitmapData ("assets / goldBlock.png")); cas 5: image = new Bitmap (Assets.getBitmapData ("assets / globe.png")); cas 6: image = new Bitmap (Assets.getBitmapData ("assets / mushroom.png")); addChild (image);
Comme j’ai utilisé six tuiles différentes pour ma carte, j’avais besoin d’un commutateur
déclaration qui couvre les numéros un à six. Vous remarquerez que le constructeur prend maintenant un entier comme paramètre pour que nous sachions quel type de tuile créer..
Maintenant, nous devons revenir à notre Principale
constructeur et corriger la création de tuiles dans notre pour
boucle:
pour (i dans 0… map.length) var tile = new Tile (map [i]); var x = i% w; var y = Math.floor (i / w); tile.setLoc (x, y); addChild (tuile);
Tout ce que nous devions faire était de passer le carte [i]
au Tuile
constructeur afin de le faire fonctionner à nouveau. Si vous essayez de courir sans passer un entier à Tuile
, cela vous donnera des erreurs.
Presque tout est en place, mais nous avons maintenant besoin d’un moyen de concevoir des cartes au lieu de les remplir avec des mosaïques aléatoires. Tout d’abord, retirez le pour
boucle dans le Principale
constructeur qui définit chaque élément à un. Ensuite, nous pouvons créer notre propre carte à la main:
map = [0, 4, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 0, 0, 0, 0, 6 , 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3];
Si vous formatez le tableau comme ci-dessus, vous pouvez facilement voir comment nos tuiles seront organisées. Vous pouvez également simplement entrer le tableau sous la forme d'une longue ligne de chiffres, mais le premier est agréable car vous pouvez en voir 10 de travers et 6 de bas..
Lorsque vous essayez d’exécuter le programme maintenant, vous devriez recevoir des exceptions de pointeur nul. Le problème est que nous utilisons des zéros dans notre carte et notre Tuile
la classe ne sait pas quoi faire avec un zéro. Tout d'abord, nous allons réparer le constructeur en ajoutant une vérification avant d'ajouter l'image enfant:
if (image! = null) addChild (image);
Cette vérification rapide permet de s’assurer que nous n’ajoutons aucun enfant nul à la Tuile
objets que nous créons. Le dernier changement pour cette classe est le setLoc ()
une fonction. En ce moment, nous essayons de définir la X
et y
valeurs pour une variable qui n'a pas été initialisée.
Ajoutons un autre contrôle rapide:
fonction publique setLoc (x: Int, y: Int) if (image! = null) image.x = x * Main.TILE_WIDTH; image.y = y * Main.TILE_HEIGHT;
Avec ces deux correctifs simples en place et les tuiles que j'ai fournies ci-dessus, vous devriez être capable de lancer le jeu et de voir un simple niveau de plateforme. Puisque nous avons laissé 0 comme "non-pavé", nous pouvons le laisser transparent (vide). Si vous voulez relever le niveau, vous pouvez mettre un fond avant de disposer les carreaux; Je viens d'ajouter un dégradé bleu clair pour ressembler à un ciel en arrière-plan.
C’est à peu près tout ce dont vous avez besoin pour configurer un moyen simple d’éditer vos niveaux. Essayez d’expérimenter un peu avec le tableau et voyez quelles conceptions vous pouvez proposer pour d’autres niveaux.
Une fois que vous avez acquis les bases, vous pouvez utiliser d'autres outils pour vous aider à concevoir rapidement des niveaux et à voir à quoi ils ressemblent avant de les lancer dans le jeu. Une option consiste à créer votre propre éditeur de niveau. L'alternative consiste à récupérer un logiciel disponible gratuitement. Les deux outils populaires sont Tiled Map Editor et Ogmo Editor. Ils facilitent beaucoup l'édition de niveaux avec plusieurs options d'exportation.
Articles SimilairesMaintenant, vous savez ce qu'est un jeu basé sur des tuiles, comment obtenir des tuiles à utiliser pour vos niveaux, comment se salir les mains et écrire le code de votre moteur, et vous pouvez même faire quelques éditions de niveau de base avec un simple tableau . Rappelez-vous que ce n’est que le début; il y a beaucoup d'expérimentation que vous pouvez faire pour faire un moteur encore meilleur.
De plus, j'ai fourni les fichiers source que vous pouvez extraire. Voici à quoi ressemble le fichier SWF final:
Téléchargez le SWF ici.… Et voici à nouveau le tableau à partir duquel il est généré:
map = [0, 4, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 0, 0, 0, 0, 6 , 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3];
Votre prochaine tâche consiste à faire des recherches et à essayer de nouvelles choses pour améliorer ce que vous avez fait ici. Les feuilles de Sprite sont un excellent moyen d’améliorer les performances et de rendre la vie un peu plus facile. L'astuce consiste à obtenir un code solide pour la lecture sur une feuille de sprite afin que votre jeu ne lise pas chaque image individuellement..
Vous devriez également commencer à pratiquer vos compétences artistiques en fabriquant vous-même quelques ensembles de carreaux. De cette façon, vous pouvez obtenir le bon art pour vos futurs jeux.
Comme toujours, laissez ci-dessous des commentaires sur la façon dont votre moteur fonctionne pour vous - et peut-être même des démos afin que nous puissions essayer votre prochain jeu de tuiles.