Sphinx-Minimap

Sphinx-Minimap

Comme tous mes plugins, ce script est publié sous licence CC BY 4.0.

En ce moment, j’ambitionne de créer un système de donjon aléatoire dont l’idée m’est venue en jouant à Pokémon Donjon Mystère. Ce système se compose en réalité de deux systèmes distincts bien que liés : la génération de donjon aléatoire bien sûr, mais également une minimap qui se découvre au fur et à mesure de l’exploitation de chaque carte (étage du donjon).

Aussi j’ai commencé par le second point, que j’ai développé comme un système à part entière. Et c’est donc mon système de minimap que je vous propose de découvrir aujourd’hui.

Installation

Pour utiliser ce plugin, vous allez tout d’abord devoir installer mon polyfill disponible ici : https://genie23.fr/js-rmmv/sphinx-polyfill/. C’est un plugin tout simple contenant des fonctions que j’utilise ca et là dans certains de mes plugins.

Et maintenant voici le script de mon plugin Sphinx-Minimap :

//=============================================================================
// Sphinx-Minimap.js
//=============================================================================

/*:
 * @plugindesc Minimap affichée à l'écran
 * @author Sphinx
 * 
 * @help
 * //==========================================================================
 * // Plugin : Sphinx-Minimap
 * // Date   : 21 mars 2020
 * // Auteur : Sphinx
 * //==========================================================================
 * Affiche une minimap sur laquelle sont notés la position du joueur et des
 * évènements marqués.
 * La couleur du point symbolisant le joueur est un paramètre de ce plugin.
 * Sont autorisés tous les codes couleurs CSS, tel que le format hexadécimal
 * (#xxx ou #xxxxxx), ou encore des couleurs nommés (voir la liste à cette
 * adresse : https://developer.mozilla.org/fr/docs/Web/CSS/Type_color).
 * 
 * Pour marquer un évènement de la carte sur la minimap, il faut insérer le
 * commentaire suivant quelque part dans la page de l'event :
 * Minimap:COULEUR
 * Où COULEUR est une couleur CSS valide.
 * 
 * Vous pouvez décider au moyen d'un paramètre booléen de ce plugin si la
 * minimap doit s'afficher par défaut ou pas. Dans les deux cas, il est
 * toujours possible soit de l'activer pour certaines cartes (si elle est
 * désactivée par défaut) soit de la désactiver pour certaines cartes (si elle
 * est activée par défaut). Pour se faire, voici les balises meta qu'il faut
 * renseigner sur vos cartes :
 *     - <minimap> : affiche la minimap
 *     - <no-minimap> : masque la minimap
 * 
 * Il est possible de paramétrer d'autres réglages pour la minimap. Par défaut,
 * elle s'affichera entièrement ainsi que tous les events à marquer.
 * 
 * Pour n'afficher qu'une partie de la minimap (utile pour les grosses cartes),
 * vous pouvez régler la taille de la minimap avec la balise meta suivante :
 *     - <minimap-size:LARGEUR HAUTEUR>
 * où LARGEUR et HAUTEUR sont les dimensions de la minimap exprimées en tiles.
 * 
 * Pour régler le niveau d'informations affichées au joueur quand il vient
 * d'arriver sur la map, utilisez l'une des balises meta suivantes :
 *     - <minimap-discovered:map> : le joueur voit tout le niveau (les events
 *                                  mais aussi tous les détails de la carte).
 *                                  C'est l'option par défaut.
 *     - <minimap-discovered:events> : le joueur ne voit que la position des
 *                                     events affichés sur la carte, mais pas
 *                                     la structure de la carte.
 *     - <minimap-discovered:nothing> : le joueur ne voit aucune info sur ce
 *                                      qui l'entoure, jusqu'à ce qu'il explore
 *                                      la carte.
 * 
 * NB : Si vous utilisez en même temps la balise meta minimap-size et
 * minimap-discovered, peu importe le niveau de détail affiché au joueur, il ne
 * verra rien de plus que ce que la balise meta minimap-size permet
 * 
 * Dépendances :
 *     Sphinx-Polyfill
 * 
 * @param defaultDisplay
 * @text Affichage par défaut de la minimap
 * @desc Définit si la minimap doit être affichée par défaut ou non.
 * @type boolean
 * @on Afficher par défaut
 * @off Masquer par défaut
 * @default false
 * 
 * @param tileSize
 * @text Taille d'un tile sur la minimap
 * @desc Dimensions (largeur et hauteur) de chaque case sur la minimap.
 * @type number
 * @min 4
 * @max 16
 * @default 8
 * 
 * @param playerColor
 * @text Couleur du point symbolisant le joueur dans la minimap.
 * @desc Sont autorisés les codes couleur hexadécimaux à 3 ou 6 caractères ou encore les couleurs nommées CSS.
 * @type text
 * @default darkgreen
 * 
 * @param groundColor
 * @text Couleur du sol (et de tout ce qui est praticable d'une manière générale)
 * @desc Sont autorisés les codes couleur hexadécimaux à 3 ou 6 caractères ou encore les couleurs nommées CSS.
 * @type text
 * @default gray
 * 
 * @param wallColor
 * @text Couleur du mur (et de tout ce qui n'est pas praticable d'une manière générale)
 * @desc Sont autorisés les codes couleur hexadécimaux à 3 ou 6 caractères ou encore les couleurs nommées CSS.
 * @type text
 * @default black
 * 
 * @param alpha
 * @text Transparence de la minimap
 * @desc Un nombre décimal compris entre 0 (transparence totale) et 1 (opacité totale).
 * @type number
 * @decimals 2
 * @min 0
 * @max 1
 * @default 0.33
 */
(function() {
	// Regexp complète pour extraire la couleur de l'event sur la minimap (couleurs au format hexadécimal ou l'une des couleurs CSS reconnues jusqu'à la norme CSS4)
	REGEXP_CSS_COLOR = /Minimap\s*:\s*(\#[0-9a-f]{6}|\#[0-9a-f]{3}|black|silver|gray|white|maroon|red|purple|fuchsia|green|lime|olive|yellow|navy|blue|teal|aqua|orange|aliceblue|antiquewhite|aquamarine|azure|beige|bisque|blanchedalmond|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|gainsboro|ghostwhite|gold|goldenrod|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|limegreen|linen|magenta|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|oldlace|olivedrab|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|thistle|tomato|turquoise|violet|wheat|whitesmoke|yellowgreen|rebeccapurple)/i;
	
	// Paramètres du plugin
	PARAMS = PluginManager.parameters("Sphinx-Minimap");
	DEFAULT_DISPLAY = PARAMS["defaultDisplay"] === "true"; // Affichage par défaut de la minimap
	ALPHA = parseFloat(PARAMS["alpha"]); // Transparence du fond (murs & sols) de la minimap
	TILE_SIZE = parseInt(PARAMS["tileSize"], 10); // Taille en pixels de chaque carreau sur la minimap
	PLAYER_COLOR = getColorToRGBA(PARAMS["playerColor"]); // Couleur du repère désignant le joueur
	GROUND_COLOR = getColorToRGBA(PARAMS["groundColor"], ALPHA); // Couleur du sol (et de tout ce qui est praticable)
	WALL_COLOR = getColorToRGBA(PARAMS["wallColor"], ALPHA); // Couleur du mur (et de tout ce qui n'est pas praticable)
	
	/*
	 * Scene_Map
	 */
	// Initialisation de la minimap dans Scene_Map
	Scene_Map.prototype.sphinxMaplinkCreateDisplayObjects = Scene_Map.prototype.createDisplayObjects;
	Scene_Map.prototype.createDisplayObjects = function() {
		Scene_Map.prototype.sphinxMaplinkCreateDisplayObjects.call(this);
		if($gameMap.displayMinimap()) {
			this.initializeMinimap();
			$gameMap.discoverMap($gamePlayer.y, $gamePlayer.x);
		}
	};
	
	// Création de la minimap et ajout à la scène
	Scene_Map.prototype.initializeMinimap = function() {
		this.minimap = new Sphinx_Minimap();
		this.addChildAt(this.minimap, 1);
	};
	
	// Mise à jour de la minimap
	Scene_Map.prototype.sphinxMinimapUpdate = Scene_Map.prototype.update;
	Scene_Map.prototype.update = function() {
		if($gameMap.displayMinimap()) {
			this.minimap.drawMinimap();
		}
		Scene_Map.prototype.sphinxMinimapUpdate.call(this);
	};
	
	/*
	 * Game_Player
	 */
	Game_Player.prototype.sphinxMinimapIncreaseSteps = Game_Player.prototype.increaseSteps;
	Game_Player.prototype.increaseSteps = function() {
		Game_Player.prototype.sphinxMinimapIncreaseSteps.call(this);
		if($gameMap.displayMinimap()) {
			$gameMap.discoverMap($gamePlayer.y, $gamePlayer.x);
		}
	};
	
	/*
	 * Game_Map
	 */
	// Initialise les données de la minimap
	Game_Map.prototype.sphinxMinimapSetup = Game_Map.prototype.setup;
	Game_Map.prototype.setup = function(mapId) {
		Game_Map.prototype.sphinxMinimapSetup.call(this, mapId);
		this.initializeMinimap();
	}
	// Détermine si la minimap doit être affichée ou non
	Game_Map.prototype.displayMinimap = function() {
		return (DEFAULT_DISPLAY && !$dataMap.meta["no-minimap"]) || $dataMap.meta["minimap"];
	}
	
	// Calcul de la carte des colisions de la map courante
	Game_Map.prototype.initializeColliderMap = function() {
		this.colliderMap = [];
		for(var row = 0; row < $dataMap.height; ++row) {
			this.colliderMap[row] = [];
			for(var col = 0; col < $dataMap.width; ++col) {
				this.colliderMap[row][col] = []
				for(var dir = 2; dir < 10; dir += 2) {
					this.colliderMap[row][col][dir / 2 - 1] = this.isPassable(col, row, dir);
				}
			}
		}
	}
	
	// Initialise les informations relatives à la minimap
	Game_Map.prototype.initializeMinimap = function() {
		this.minimapDisplayedWidth = $dataMap.width;
		this.minimapDisplayedHeight = $dataMap.height;
		if($dataMap.meta["minimap-size"] !== undefined) {
			displayedSize = $dataMap.meta["minimap-size"].trim().split(" ").map(value => parseInt(value, 10));
			this.minimapDisplayedWidth = displayedSize[0];
			this.minimapDisplayedHeight = displayedSize[1];
		}
		this.initializeColliderMap();
		this.initializeDiscoveredMap();
	}
	
	// Initialise la découverte de la map
	Game_Map.prototype.initializeDiscoveredMap = function() {
		// Initialisation des données
		this.discoveredMap = [];
		events = false;
		structure = false;
		bubbled = false;
		
		// Niveau de détails affichés
		switch($dataMap.meta["minimap-discovered"]) {
			// Nothing : rien n'est montré au joueur
			case "nothing":
				break;
			
			// Events : la position des évents est affichée, mais ni les murs ni le sol
			case "events":
				events = true;
				break;
			
			// Map : tout est affiché pour l'ensemble de la carte
			case "map":
			default:
				events = true;
				structure = true;
				bubbled = true;
				break;
		};
		
		// Pour chaque tile, enregistrement du niveau de détails affichés
		for(var row = 0; row < $dataMap.height; ++row) {
			this.discoveredMap[row] = [];
			for(var col = 0; col < $dataMap.width; ++col) {
				this.discoveredMap[row][col] = { events: events, structure: structure, bubbled: bubbled };
			}
		}
1	};

	// Affiche les informations découvertes sur la minimap
	Game_Map.prototype.discoverMap = function(startRow, startCol) {
		// Si la case a déjà engendré une propagation, on sort
		if(this.discoveredMap[startRow][startCol].bubbled) return;
		
		// Initialisation de la liste des coordonnées - on part des coordonnées du joueur
		var coords = [ startRow + ";" + startCol ];
		
		// Parcours de la liste des coordonées de la salle
		for(var i = 0; i < coords.length; ++i) {
			// Extraction des coordonnées
			var coord = coords[i].split(";").map(value => parseInt(value, 10));
			var row = coord[0];
			var col = coord[1];
			
			// Exploration dans toutes les directions
			for(var d = 0; d < 4; ++d) {
				// Initialisation des coordonnées explorées
				var r = row; var c = col;
				
				// Calcul de la modification de coordonnées en fonction de la direction
				var x = 0; var y = 0;
				switch(d) {
					// Bas
					case 0:
						y = 1;
						break;
					// Gauche
					case 1:
						x = -1;
						break;
					// Droite
					case 2:
						x = 1;
						break;
					// Haut
					case 3:
						y = -1;
						break;
				}
				// Tant que les cases sont passables dans cette direction (et la case d'en face dans la direction opposée soit 3 - d) et qu'elles sont reliées à plus de 2 cases sur les 8 autour
				while(this.colliderMap[r][c][d] && this.colliderMap[r + y][c + x][3 - d] && this.getPassableCount(r, c) > 2) {
					// On avance d'une case dans cette direction
					r += y;
					c += x;
					// Si elle est reliée à plus de 2 cases sur les 8 autour
					if(!coords.includes(r + ";" + c) && this.getPassableCount(r, c) > 2) {
						// On ajoute les coordonnées de la nouvelle case (on les empacte dans une chaine de caractères pour pouvoir tester si elles existent dans le tableau des coordonnées analysées)
						coords.push(r + ";" + c);
					}
				}
			}
		}
		for(i = 0; i < coords.length; ++i) {
			// Extraction des coordonnées
			var coord = coords[i].split(";").map(value => parseInt(value, 10));
			var row = coord[0];
			var col = coord[1];
			
			// Découverte de la case, et des cases avoisinantes (de [row - 3;col - 1] à [row + 1;col + 1])
			this.discoverTile(row, col);
		}
	};
	
	// Retourne true si les coordonnées sont en dehors de la carte
	Game_Map.prototype.isInvalidCoords = function(row, col) {
		return row < 0 || row >= $dataMap.height || col < 0 || col >= $dataMap.width;
	}
	
	// Retourne le nombre d'accès pour la case passée en paramètres
	Game_Map.prototype.getPassableCount = function(row, col) {
		// Vérification de la propagation : si 3 des cases autour du tile courant sont praticables, alors on active
		if(this.isInvalidCoords(row, col)) return;
		
		// la propagation autour de cette case.
		var count = 0;
		// Vers le bas
		if(row < $dataMap.height - 1 && this.colliderMap[row][col][0] && this.colliderMap[row + 1][col][3]) ++count;
		// Vers la gauche
		if(col > 0 && this.colliderMap[row][col][1] && this.colliderMap[row][col - 1][2]) ++count;
		// Vers la droite
		if(col < $dataMap.width - 1 && this.colliderMap[row][col][2] && this.colliderMap[row][col + 1][1]) ++count;
		// Vers le haut
		if(row > 0 && this.colliderMap[row][col][3] && this.colliderMap[row - 1][col][0]) ++count;
		// Vers le bas gauche
		if(
			row < $dataMap.height - 1 && col > 0 &&
			this.colliderMap[row + 1][col - 1][3] && this.colliderMap[row][col - 1][0] &&
			this.colliderMap[row + 1][col - 1][1] && this.colliderMap[row + 1][col][2]
		) ++count;
		// Vers le haut gauche
		if(
			row > 0 && col > 0 &&
			this.colliderMap[row - 1][col - 1][0] && this.colliderMap[row][col - 1][3] &&
			this.colliderMap[row - 1][col - 1][1] && this.colliderMap[row - 1][col][2]
		) ++count;
		// Vers le haut droite
		if(
			row > 0 && col < $dataMap.width - 1 &&
			this.colliderMap[row - 1][col + 1][0] && this.colliderMap[row][col + 1][3] &&
			this.colliderMap[row - 1][col + 1][2] && this.colliderMap[row - 1][col][1]
		) ++count;
		// Vers le bas droite
		if(
			row < $dataMap.height - 1 && col < $dataMap.width - 1 &&
			this.colliderMap[row + 1][col + 1][3] && this.colliderMap[row][col + 1][0] &&
			this.colliderMap[row + 1][col + 1][2] && this.colliderMap[row + 1][col][1]
		) ++count;
		
		return count;
	}
	
	// Découvre un tile
	Game_Map.prototype.discoverTile = function(row, col) {
		// Elimination des recherches hors de la map
		if(this.isInvalidCoords(row, col)) return;
		
		// Elimination des recherches déjà effectuées
		if(this.discoveredMap[row][col].bubbled) return;
		
		// Affiche la case sur la minimap (event et sol) et propage sur une zone allant de [row - 3;col - 1] à [row + 1;col + 1]
		for(r = row - 3; r <= row + 1; ++r) {
			for(c = col - 3; c <= col + 1; ++c) {
				if(this.isInvalidCoords(r, c) || this.discoveredMap[r][c].structure) continue;
				this.discoveredMap[r][c].events = true;
				this.discoveredMap[r][c].structure = true;
			}
		}
		
		// La case est marquée propagée
		this.discoveredMap[row][col].bubbled = true;
	};
	
	// Met à jour les limites de la minimap (en cas d'affichage partiel)
	Game_Map.prototype.updateMinimapLimits = function() {
		this.firstLineIndex = Math.min(Math.max(0, $gamePlayer.y - this.minimapDisplayedHeight / 2), $dataMap.height - this.minimapDisplayedHeight);
		this.firstColIndex = Math.min(Math.max(0, $gamePlayer.x - this.minimapDisplayedWidth / 2), $dataMap.width - this.minimapDisplayedWidth);
	};
	
	/*
	 * Sphinx_Minimap
	 */
	function Sphinx_Minimap() {
		this.initialize.apply(this, arguments);
	};

	Sphinx_Minimap.prototype = Object.create(Sprite_Base.prototype);
	Sphinx_Minimap.prototype.constructor = Sphinx_Minimap;
	
	// Initialisation de la minimap
	Sphinx_Minimap.prototype.initialize = function() {
		Sprite_Base.prototype.initialize.call(this);
		// $gameMap.initializeMinimap();
		this.x = 12;
		this.y = Graphics.height - $gameMap.minimapDisplayedHeight * TILE_SIZE - 12;
		this.bitmap = new Bitmap($gameMap.minimapDisplayedWidth * TILE_SIZE, $gameMap.minimapDisplayedHeight * TILE_SIZE);
		this.context = this.bitmap._context;
	};
	
	// Dessin de la minimap
	Sphinx_Minimap.prototype.drawMinimap = function() {
		// Fond de la minimap
		this.bitmap.clear();
		this.context.fillStyle = WALL_COLOR;
		this.context.fillRect(0, 0, $gameMap.minimapDisplayedWidth * TILE_SIZE, $gameMap.minimapDisplayedHeight * TILE_SIZE);
		$gameMap.updateMinimapLimits();
		// Dessine la portion de la minimap à afficher
		for(var row = 0; row < $dataMap.height; ++row) {
			for(var col = 0; col < $dataMap.width; ++col) {
				this.drawMinimapTile(row, col);
			}
		}
		
		// Dessin des éléments affichés sur la minimap
		this.markPlayer();
		this.markEvents();
	};
	
	// Marque la position du joueur sur la minimap
	Sphinx_Minimap.prototype.markPlayer = function() {
		this.context.fillStyle = PLAYER_COLOR;
		this.drawMark($gamePlayer.y, $gamePlayer.x);
	};
	
	// Marque la position de tous les évènements sur la minimap
	Sphinx_Minimap.prototype.markEvents = function() {
		for(var eventId = 0; eventId < $gameMap.events().length; ++eventId) {
			var event = $gameMap.events()[eventId];
			if(event._erased) continue;
			if($gameMap.discoveredMap[event.y][event.x].events) {
				var commands = event.page().list
				for(var commandId = 0; commandId < commands.length; ++commandId) {
					var command = commands[commandId];
					if(command.code != 108 && command.code != 408) continue;
					if(command.parameters[0].match(REGEXP_CSS_COLOR)) {
						var color = command.parameters[0].match(REGEXP_CSS_COLOR)[1];
						this.context.fillStyle = color;
						this.drawMark(event.y, event.x);
					}
				}
			}
		}
	};
	
	// Dessine une marque circulaire sur la minimap
	Sphinx_Minimap.prototype.drawMark = function(row, col) {
		this.context.beginPath();
		this.context.ellipse((col - $gameMap.firstColIndex) * TILE_SIZE + TILE_SIZE / 2, (row - $gameMap.firstLineIndex) * TILE_SIZE + TILE_SIZE / 2, TILE_SIZE / 3, TILE_SIZE / 3, 0, 0, 2 * Math.PI);
		this.context.fill();
	};
	
	// Dessine un tile de la minimap
	Sphinx_Minimap.prototype.drawMinimapTile = function(row, col) {
		// Franchissement impossible dans les 4 directions
		if(!$gameMap.discoveredMap[row][col].structure || (!$gameMap.colliderMap[row][col][0] && !$gameMap.colliderMap[row][col][1] && !$gameMap.colliderMap[row][col][2] && !$gameMap.colliderMap[row][col][3])) { // Tile infranchissable ou non découvert
			// this.context.fillStyle = WALL_COLOR;
			// this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE, (row - $gameMap.firstLineIndex) * TILE_SIZE, TILE_SIZE, TILE_SIZE);
		} else {
			// Dessin du sol praticable
			this.context.fillStyle = GROUND_COLOR;
			this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE, (row - $gameMap.firstLineIndex) * TILE_SIZE, TILE_SIZE, TILE_SIZE);
			
			// Dessins d'éventuels murs
			this.context.fillStyle = WALL_COLOR;
			
			// Franchissement impossible vers le bas
			if(!$gameMap.colliderMap[row][col][0]) {
				this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE, (row - $gameMap.firstLineIndex) * TILE_SIZE + TILE_SIZE * 3 / 4, TILE_SIZE, TILE_SIZE / 4);
			}
			// Franchissement impossible vers la gauche
			if(!$gameMap.colliderMap[row][col][1]) {
				this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE, (row - $gameMap.firstLineIndex) * TILE_SIZE, TILE_SIZE / 4, TILE_SIZE);
			}
			// Franchissement impossible vers la droite
			if(!$gameMap.colliderMap[row][col][2]) {
				this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE + TILE_SIZE * 3 / 4, (row - $gameMap.firstLineIndex) * TILE_SIZE, TILE_SIZE / 4, TILE_SIZE);
			}
			// Franchissement impossible vers le haut
			if(!$gameMap.colliderMap[row][col][3]) {
				this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE, (row - $gameMap.firstLineIndex) * TILE_SIZE, TILE_SIZE, TILE_SIZE / 4);
			}
			// Jonction coin haut gauche
			if(col > 0 && !$gameMap.colliderMap[row][col - 1][3] && row > 0 && !$gameMap.colliderMap[row - 1][col][1]) {
				this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE, (row - $gameMap.firstLineIndex) * TILE_SIZE, TILE_SIZE / 4, TILE_SIZE / 4);
			}
			// Jonction coin haut droite
			if(col < $dataMap.width - 1 && !$gameMap.colliderMap[row][col + 1][3] && row > 0 && !$gameMap.colliderMap[row - 1][col][2]) {
				this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE + TILE_SIZE * 3 / 4, (row - $gameMap.firstLineIndex) * TILE_SIZE, TILE_SIZE / 4, TILE_SIZE / 4);
			}
			// Jonction coin bas gauche
			if(col > 0 && !$gameMap.colliderMap[row][col - 1][0] && row < $dataMap.height - 1 && !$gameMap.colliderMap[row + 1][col][1]) {
				this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE, (row - $gameMap.firstLineIndex) * TILE_SIZE + TILE_SIZE * 3 / 4, TILE_SIZE / 4, TILE_SIZE / 4);
			}1
			// Jonction coin bas droite
			if(col < $dataMap.width - 1 && !$gameMap.colliderMap[row][col + 1][0] && row < $dataMap.height - 1 && !$gameMap.colliderMap[row + 1][col][2]) {
				this.context.fillRect((col - $gameMap.firstColIndex) * TILE_SIZE + TILE_SIZE * 3 / 4, (row - $gameMap.firstLineIndex) * TILE_SIZE + TILE_SIZE * 3 / 4, TILE_SIZE / 4, TILE_SIZE / 4);
			}
		}
	};
})();

Et voilà, le plugin est fonctionnel.

Utilisation

Et voilà, le plugin est fonctionnel. Mais il vous reste à le prendre en main. Rassurez-vous, ce n’est pas si compliqué que ca, et nous allons le voir dès maintenant.

Commençons par les paramètres du plugin :

  • defaultDisplay : Booléen. S’il est sur on, affiche la minimap par défaut sur toutes les cartes, sauf celles sur laquelle la minimap est désactivée. S’il est sur off, la minimap ne sera affichée que sur les cartes qui seront configuré pour.
  • tileSize : Nombre entier compris entre 4 et 16. C’est la taille d’un carreau sur la minimap. Plus ce nombre est grand, plus la minimap occupera d’espace. Inversement, plus ce nombre est petit, moins les détails de la minimap seront visibles. Par défaut, je recommande de tester chaque carte avec une taille de 8 (8×8 px par tile).
  • playerColor : Couleur du point qui représente le joueur sur la minimap. Sont autorisés les codes couleur hexadécimaux à 3 ou 6 caractères ou encore les couleurs nommées CSS.
  • groundColor : Couleur du sol, et plus généralement des tiles praticables découverts sur la minimap. Sont autorisés les codes couleur hexadécimaux à 3 ou 6 caractères ou encore les couleurs nommées CSS. Si un tile n’est passable que par certains côtés, le tile sera de cette couleur, mais un liserai de couleur du mur sera présent sur les côtés non passables.
  • wallColor : Couleur des mur, et plus généralement des tiles impassables de la carte. Sont autorisés les codes couleur hexadécimaux à 3 ou 6 caractères ou encore les couleurs nommées CSS. A noter que c’est également cette couleur qui est utilisée comme couleur de fond de la minimap pour toute section non découverte.
  • alpha : Nombre décimal compris entre 0,00 et 1,00. Degré d’opacité de la minimap. Plus cette valeur sera élevée, plus la minimap sera opaque. A noter que les points représentant les events et le joueur ne sont pas affectés par cette valeur (leur opacité est de 1). Seuls les murs et le sol le sont.

Méta-balises des cartes

<minimap> : Si le paramètre defaultDisplay est sur off, affiche la minimap sur la carte courante.

<no-minimap> : Si le paramètre defaultDisplay est sur on, désactive la minimap pour la carte courante.

<minimap-size:LARGEUR HAUTEUR> : Où LARGEUR est la largeur de la minimap exprimée en tiles, et où la HAUTEUR est la hauteur de la minimap exprimée en tiles aussi. Affiche une portion de la minimap, pour qu’elle occupe moins de place (utile sur les grosses maps).

<minimap-discovered:LEVEL> : Où LEVEL est « nothing », « events » ou « map ». Définit le niveau de détails que le joueur verra en arrivant sur la carte. Le niveau « map » affichera la structure de la carte ainsi que la position des events marqués. C’est le comportement par défaut si aucun réglage minimap-discovered n’est renseigné. Le niveau « events » affichera la position des events marqués, mais la structure de la map ne sera affichée qu’au fur et à mesure de l’exploration de la carte (voir ci-après). Le niveau « nothing » n’affichera rien au départ, et révèlera la structure de la carte et la position des events marqués dans les zones explorées.

Comment marche l’exploration de la carte pour l’affichage sur la minimap

Sauf si la carte est réglée pour tout afficher, ou plus précisément si aucun réglage n’affirme le contraire puisque c’est le comportement par défaut, le joueur ne découvrira la structure de la carte (et éventuellement les events) qu’au fur et à mesure de son exploration.

Cette fonctionnalité est prévu à la base pour des cartes de type donjon, composées de salles plus ou moins carrées ; une salle trop complexe pourrait ne pas être détectée complètement en fonction de la position du joueur – dans ce cas je vous recommande de tester l’affichage de la minimap pour votre carte pour vous faire une idée ; et reliées entre elles par des couloirs d’un tile de large. En entrant dans une salle, toute la structure de la salle est révélée sur la minimap. Dans un couloir, seul les tiles autour du joueur sont révélés.

La définition de salle, telle qu’exploitée par ma minimap, est assez délicate à expliquer. En fait, j’explore toutes les cases autour du joueur jusqu’à trouver une case qui n’aurait que par 2 cases passables ou moins sur les 8 autour. Une case entourée par moins de 2 cases passables est considérée comme un couloir.

Ce concept pourrait ne pas être très clair, aussi je vous invite à tester la démonstration de ce système sur mon site de démonstration officiel : https://demos.rmmv.genie23.fr/#minimap.

Marquer un évènement sur la minimap

Jusque là, sauf si vous avez déjà épluché la démo du système, vous aurez remarqué que seule la position du joueur est révélée sur la minimap. Et vous vous demandez surement comment marquer un event pour qu’il apparaisse aussi sur la minimap. Par défaut, un event ne sera pas affiché. Il faut ajouter le commentaire suivant : minimap:COULEUR, où COULEUR est une couleur au format CSS (liste et format de couleurs CSS : https://developer.mozilla.org/fr/docs/Web/CSS/Type_color).

Si votre event a plusieurs pages, sachez qu’il peut changer de couleur en fonction de la page (ce n’est pas obligatoire, mais c’est possible). Dans tous les cas, pour que votre event reste affiché sur la minimap lorsqu’il change de page, il faut bien penser à mettre le commentaire sur chaque page. Si une page d’un event ne doit pas s’afficher sur la minimap, il suffit de ne pas lui mettre de commentaire.

Et voilà !

Laisser un commentaire

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

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.