Je ne connais pas les arcanes secrètes de GM donc j'ai abordé le problème comme si je n'avais aucun outil spécifique à GM pour faire ça, peut-être qu'on peut faire plus simple, je suis preneur d'infos...
L'idée est de pouvoir, dans un niveau, actionner des portes (pour commencer) à partir de switchs. Pour garder une bonne évolutivité il faut que le switch puisse s'activer un peu comme on veut et que la porte réagisse un peu comme on veut. Il s'agit donc d'une machinerie qui lie des actions à des résultats d'instance à instance.
Ma méthode est la suivante, il nous faut au moins tous ces objets :
- OBJ : un objet switch
- SCR_OBJ_INIT : un script d'initialisation unique pour tous les switchs
- SCR_OBJ_ACTION : un script d'action unique pour tous les switchs à appliquer à l'événement de notre choix dans l'objet switch
- switch instance creation_code : un code d'instanciation spécifique à chaque instance de switch
- SCR_MACHINERIE_INIT : l'initialisation de la machinerie
- SCR_MACHINERIE : un script de machinerie unique pour faire le lien entre tout ce bazar
- OBJ_DOOR : un objet récepteur
- SCR_REGISTER_MACHINERIE : un script unique qui enregistre les récepteurs dans la machinerie (le franglais est voulu)
- recepteur instance creation_code: un code d'instanciation spécifique à chaque instance de récepteur
Exemple : un interrupteur sur lequel on marche ouvre une porte, ils sont liés par l'id d'action 1.
On ajoute SCR_OBJ_INIT au 'Create' de l'objet switch qui contient peu ou prou :
Code : Tout sélectionner
self.active = false;
self.action_id = 0;// L'ID qui lie un switch à un récepteur
self.image_index = 1;// On part du principe que le sprite utilisé a 2 frames (inactif/actif)
self.image_speed = 0;// On bloque la lecture des frames du sprite
Code : Tout sélectionner
SCR_MACHINERIE(self.action_id);
Code : Tout sélectionner
self.action_id = 1;//L'action 1 est lancée depuis cet objet
Code : Tout sélectionner
"machinerie" : {
"1" : door_1,
"2" : door_2
}
La variable 'machinerie' est un ds_map dont chaque clé est l'action_id et dont la valeur est l'objet récepteur lui-même. Pour ça l'init de la machinerie ne comporte que ça d'important :
Code : Tout sélectionner
ds_map_create(global.machinerie);
1/ Event Create > défini dans le champ Events -> Create de l'objet en lui-même (le modèle de l'objet dans la liste de gauche de l'interface)
2/ Creation code > défini lors de l'instanciation de l'objet dans la room, il faut faire un clic droit sur l'objet posé dans le niveau pour accéder à ses propriétés et son 'creation code'.
3/ Step, collisions, etc... > définis dans les champs events correspondants, là c'est plus free style.
Ce qui est important à voir ici, c'est que l'on peut initialiser des variables par défaut dans l'événement Create et affecter des valeurs pour chaque instance individuellement dans la room, en fonction de leur placement, etc... pour ensuite s'en servir dans les scripts de collision, d'IA, etc...
Tout ça pour dire que ma porte elle s'initialise avec rien de particulier, mais dans son creation_code on exécute le script SCR_REGISTER_MACHINERIE. Le creation code contient :
Code : Tout sélectionner
SCR_REGISTER_MACHINERIE(1);// On s'enregistre avec l'ID 1 dans la machinerie en tant que récepteur
Code : Tout sélectionner
var action_id = argument0;
ds_map_add(global.machinerie, action_id, self.id);
Une fois qu'on entre en collision avec le switch on lance le script SCR_MACHINERIE sans aucun paramètre. On va se servir du self initialisé dans le creation_code. Et c'est là que j'ai eu du mal à trouver comment récupérer les données du ds_map sans debugger. Il faut utiliser la fonction ds_map_find_value pour récupérer la valeur telle qu'elle.
Et donc la machinerie est un peu plus compliqué mais ressemble à ça :
Code : Tout sélectionner
if (self.action_id != 0)// Je vérifie toujours mes données pour ne pas faire de moulinette inutile
{
var door = ds_map_find_value(global.machinerie, self.action_id);
instance.destroy(door);// Parceque on accède à notre instance depuis son ID
}
Pour l'instant la porte disparaît salement, je dois trouver un moyen élégant et raffiné de lancer une anim d'ouverture/fermeture, et surtout supporter autre chose que des portes (des pièges !), mais là ça risque de devenir trop compliqué pour être décrit comme ça dans un post à l'arrache.
PS: je corrigerai les éventuelles erreurs, là je poste en speed depuis le boulot, je suis censé coder autre chose que du GM... Mais n'hésitez pas à me corriger.