Un niveau du jeu est une grille de cases carrées. Evidemment, quand vous jouez au jeu vous pouvez voir que vous bougez case par case.
Mais comment allons-nous représenter un mur ?
Il y a deux façons de voir les murs.
-
La représentation "murs épais", ou map basée sur les cases.
Vous pouvez voir une map comme une grille de mots croisés avec des cases vides ou pleines.
Pour savoir si on peut se déplacer d'une case à une autre, on doit seulement tester si la case de destination est vide.
Mais il nous faut aussi des infos supplémentaires sur les murs, par exemple si un bouton est sur un coté d'une case.
-
La représentation "murs fins", ou map basée sur les murs.
On se concentre plus sur les murs qui séparent les cases que sur les cases elles-mêmes.
Avec cette représentation, on a aussi besoin d'infos sur les cases, car dans le jeu il y a des éléments qui sont posés
au milieu d'une case comme les téléporteurs ou les trous dans le sol.
Mais cette façon de voir la map est plus flexible car elle permet aussi de représenter une map basée sur les cases.
On doit aussi se demander si les murs sont identiques des 2 cotés. Ou si on peut avoir par ex. un bouton d'un coté et un levier de l'autre.
Je ne savais pas quelle représentation était utilisée dans le jeu d'origine. Alors je me suis demandé "Qu'est-ce qu'on voit quand on joue ?"
On voit des murs. On ne sait pas quand on voit un mur si la case derrière est pleine ou vide.
Et comme je pense que l'éditeur de niveaux pourrait être utilisé pour d'autres jeux, j'ai opté pour le format le plus flexible, même s'il est plus coûteux
en quantité de mémoire.
Chaque case contiendra un octet représentant son type, qui nous dira si c'est une case vide, une case avec un trou dans le sol, un téléporteur, etc...
Chaque case contiendra aussi 4 éléments "murs" représentant la face "intérieure" de chaque mur (la face qu'on voit quand on est à l'intérieur de la case).
Evidemment la face extérieur de chaque mur est la face intérieure du mur correspondant de la case d'à coté.
Chacun de ces éléments "mur" contiendra un octet qui nous donnera son type (soit si c'est un mur normal, un mur avec un bouton , un mur avec une alcove, etc...).
La map sera basée sur les murs. Donc, si on veut aller d'une case à une autre on testera les murs entre elles. En fait on testera seulement le mur intérieur de la
case de départ.
Voila la première version de l'éditeur de niveau.
Sur la gauche, il y a évidemment la map. Si vous redimensionnez la fenêtre, vous verrez que cette zone sétirera pour remplir l'espace disponible.
Comme vous le voyez sur l'image, si cette zone est trop petite pour contenir la map, une barre de défilement apparaitra pour nous permettre de nous déplacer dans la map.
De cette façon, on peut travailler sur des map de n'importe quelle taille.
Sur la droite, il y a la zone des outils. Pour le moment il y a seulement des onglets qui nous permettront de travailler à différents niveaux sur la map.
- Dans l'onglet "Map" on pourra régler les données qui n'apparaissent qu'une fois pour toute la map. Pour l'instant on peut y modifier la taille de la map.
- Dans l'onglet "Cases" il y aura une liste pour sélectionner le type de case qu'on voudra mettre dans la map.
- Dans le même esprit, dans l'onglet "Murs" il y aura une liste de types de murs.
- L'onglet "Objets" sera utilisé pour placer des objets sur le sol.
Il y aura probablement d'autres onglets à l'avenir, par ex. pour les monstres...
Cliquez sur l'onglet "Cases" et déplacez la souris sur la map. Vous verrez un carré vert qui montre la case où est la souris.
Appuyez sur le bouton gauche et la case se changera en une belle texture de pierre dessinée à la main.
Appuyez sur le bouton droit et la case redeviendra noire.
Note: Si vous avez compilé vous-même les sources et que vous ne voyez rien changer quand vous cliquez, vérifiez le chemin de "Tile.png" dans Map.cpp
Maintenant, dessinez quelques cases comme ça, et cliquez sur l'onglet "Murs".
Si vous déplacez votre souris sur la map, vous verrez que le carré vert est maintenant un rectangle qui représente les murs.
Vous ne pouvez pas encore dessiner de murs pour le moment.
Si vous cliquez qur l'onglet "Objets", vous verrez que le carré vert est plus petit. Parce que dans le jeu d'origine il y a 4 positions possibles pour placer un objet
dans une case.
Voila une description des différents fichiers:
- MapEditor.pro est le fichier de projet Qt à ouvrir avec Qt Creator. Il liste tous les fichiers ".h" et ".cpp".
- qml.qrc fait aussi partie des informations du projet que Qt utilise. Il liste tous les fichiers qml.
- MainForm.ui.qml le fichier principal décrivant l'interface.
- main.qml un fichier qui contient les actions qu'on va exécuter quand on presse un bouton ou qu'on change une valeur dans l'interface,
car pour suivre les règles de Qt, on ne peut pas appeler de fonction dans les fichiers ".ui". Vous verrez qu'on appelle principalement des fonction de "Bridge.cpp" ici.
- MapTab.qml le fichier qui décrit l'onglet "Map" dans le tabview.
- main.cpp le point d'entrée principal de notre programme. Ici on enregistre les fonctions de "Bridge.cpp" pour pouvoir les utiliser dans les fichiers qml.
- Bridge.h & Bridge.cpp contiennent des fonctions pour communiquer entre les parties qml et c++. Ici, on recoit principalement les données de l'interface et on les stocke.
Il contient aussi l'"image provider". Comme l'image de la map n'est pas rafraichie automatiquement, quand on la change, on appelle updateQMLImage() qui envoie un signal à la partie qml.
A son tour, le qml appelle l'"image provider" qui redessine l'image.
- cmaths.h & cmaths.cpp quelques fonctions mathématiques. Comme on va utiliser beaucoup de coordonnées 2D, il contient principalement une classe de vecteur 2D (CVec2) et des fonctions
pour faire toutes sortes de calculs dessus.
- cgraphics2d.h & cgraphics2d.cpp des fonctions graphiques basiques pour tracer des lignes, des rectangles et copier des images comme nos cases dans la grosse image de la map.
- Map.h & Map.cpp contient la représentation de la map comme on l'a décrite ci-dessus et quelques fonctions pour la manipuler.
Entre autres choses, la fonction "display" qui la dessine à l'écran.