Créer des zones d'intéraction avec l'Event-Extender
Dans ce tutoriel, nous allons nous intéresser aux commandes de manipulation des zones, qui permettent de faire plein de choses intéressantes.
Nous essayerons d'évaluer certaines issues envisageables au moyen de ces outils.
- Grim, 13/11/2014 à 09h57.


Créer des zones d'intéraction avec l'Event-Extender - Grim

Créer des zones d'intéraction avec l'Event-Extender



Attention, ce tutoriel utilise la version 4.5.6 de l'Event Extender (ou ultérieur), je vous invite à mettre vos EE à jours (en cliquant ici) si la version ne correspond pas.


Sachez, pour information, que la mise en forme des évènements est gérée par l'Event-Printer, un excellent script de Zangther, qui permet d'exporter les évènements en HTML/BBcode et qui offre à ce tutoriel cet excellent rendu visuel !

icone Introduction


Après le tutoriel sur la création d'une jauge avec l'Event-Extender, j'ai décidé de continuer de présenter certains de ses outils au moyen d'un nouvel article. Cette fois, nous allons apprendre à nous servir des zones.
Les zones sont un outil très utile et nous allons voir de quoi il s'agit et comment s'en servir. Sachez que mon estimé collègue, Joke, en avait déjà rédigé un qui ne tirait pas partit de l'Event-Extender, vous verrez que l'Event-Extender rend la création/utilisation des zones (dites, par variables) beaucoup plus concise et aisée.

Tout d'abord, qu'est ce qu'une zone?


Les zones permettent de représenter une portion de la carte. Une fois cette portion définie, on peut l'utiliser pour tester des choses. Par exemple, est-ce que ces points (référencés par x et y) y sont inscrits, ou encore, est-ce que la zone est survolée par la souris, cliqué par la souris. C'est donc un outil puissant pour effectuer des Point&Click ou déclencher des actions spécifiques si un évènement traverse une zone.
Il existe plusieurs type de zones :

• Les zones rectangulaires
• Les zones circulaires
• Les zones elliptiques
• Les zones polygonales (convexes ou non)


Concrètement, une zone c'est juste une portion de la carte... qui peut avoir plusieurs formes. POINT ! Smiley


icone A l'assaut de notre première zone


Nous allons aborder les zones par la pratique, nous allons donc voir un premier cas de figure (honteusement plagié du tutoriel original de Joke). Imaginons cette carte, au climat... étrange (et totalement réaliste Smiley) :



Notre objectif sera de nous servir d'une zone pour que quand le héros se trouve dans la partie enneigée de la carte, on change le climat de la carte pour afficher une chute de neige et que quand il en sorte, le climat redevienne normal !

Création de la zone



Pour créer une zone rectangulaire, nous aurons besoin des coordonnées de son point haut-gauche (H-G) et des coordonnées de son point bas-droit (B-D) :



Maintenant que nous avons récupéré les coordonnées, il nous suffit de créer une zone qui correspond à ces coordonnées. Pour ce faire, je crée un évènement en processus parallèle qui va construire la zone et la placer dans une variable (pour que l'on puisse l'utiliser dans les commandes de test de zones).

Code (Ruby):
  1. SV[1] = create_rect_area(14, 4, 21, 15)


Ici, je dis que la zone référencée par les coordonnées (14,4) et (21,15) se trouve dans la variable locale 1. (J'utilise une variable locale pour que ma zone ne soit accessible que de l'évènement dans lequel je me trouve Smiley).
Maintenant que notre zone est définie, on peut créer une boucle qui va tester si le héros s'y trouve !

Détecter si un point se trouve dans une zone



A partir de maintenant, notre zone est construite. Pour tester la présence d'un point dans une zone. Il suffit d'utiliser la commande in_area?(ZONE, X, Y) qui va vérifier si un point référencé par (X,Y) se trouve dans la zone passée en premier argument (c'est pour ça qu'on stocke la zone dans une variable, pour pouvoir la relayer dans les commandes, par après).
Pour savoir si notre héros marche dans la zone. Nous pourrons nous servir des commandes player_x et player_y :

Event - EV001
| > Commentaire : Nous sommes dans un évènement en processus parallèle, on
| > Commentaire : initialise les données :
| > Commentaire : Création de la zone dans la variable locale 1
| > Appeler Script : SV[1] = create_rect_area(14, 4, 21, 15)
| > Commentaire : Initialisation de l'interrupteur pour dire s'il neige
| > Opération : Interrupteur [0001:IlNeige] Désactivé
| > Commentaire : Boucle de vérification
| > Boucle
| >| > Attendre : 1 Frames
| >| > Condition : Script : in_area?(SV[1], player_x, player_y)
| >| >| > Commentaire : Si on est dans la zone, on peut vérifier qu'il faille activer la neige.
| >| >| > Commentaire : Soit activer la neige si l'interrupteur est désactivé !
| >| >| > Condition : Interrupteur [0001:IlNeige] == Désactivé
| >| >| >| > Commentaire : On active l'interrupteur et on lance la neige !
| >| >| >| > Opération : Interrupteur [0001:IlNeige] Activé
| >| >| >| > Effet Météorologique : Neige, 9, 60 Frames, Attendre
| >| >| >| >
| >| >| > Fin - Condition
| >| >| >
| >| > Sinon
| >| >| > Commentaire : Si on n'est pas dans la zone, vérifions que l'on vient d'en sortir,
| >| >| > Commentaire : soit si l'interrupteur neige est toujours activé !
| >| >| > Condition : Interrupteur [0001:IlNeige] == Activé
| >| >| >| > Commentaire : On désactive l'interrupteur et on lance la neige !
| >| >| >| > Opération : Interrupteur [0001:IlNeige] Désactivé
| >| >| >| > Effet Météorologique : Aucun, 60 Frames, Attendre
| >| >| >| >
| >| >| > Fin - Condition
| >| >| >
| >| > Fin - Condition
| >| >
| > Fin - Boucle
| >


Comme en court de route, j'ai perdu, malheureusement, le projet sur lequel je faisais mes démonstration, voici tout de même un petit gif qui correspond "plus ou moins" à l'effet attendu :



Le code n'est à priori pas trop complexe à comprendre. Techniquement, on crée un évènement en processus parallèle pour qu'il se déclenche automatiquement (mais sans bloquer le héros). Ensuite on initialise les données. Puis on crée une boucle (qui s'exécute plus vite, donc elle rafraichit plus vite les modifications) et dedans on vérifie si on vient de rentrer dans la zone, ou si on vient de sortir de la zone. (Cette vérification "plus raffinée", se fait au moyen de l'interrupteur).


icone Un mini champ de vision


Maintenant que nous avons vu comment créer une zone simple et fixe, nous allons aller un peu plus loin en concevant un "petit champ de vision", au moyen des zones circulaires. Vous allez voir, c'est très très simple !

Il est important de noter que la modification/création d'une zone est une opération très peu gourmande. On peut donc modifier une zone en l'écrasant !


Création et mise à jours de la zone


La première étape est de construire une zone circulaire. Elle est aussi simple à créer qu'une zone rectangulaire, si ce n'est qu'elle demande moins d'argument. En effet, une zone circulaire n'a besoin que d'un point (x, y) pour définir son centre et un rayon. Par exemple :
Code (Ruby):
  1. V[1] = create_circle_area(x, y, rayon)
.
Concrètement, cette fois, nous allons créer un évènement qui initialisera une zone circulaire, dans une variable globale car nous aurons besoin de la zone en dehors de l'évènement qui l'appelle. Et ensuite, comme toujours, viendra une boucle, qui écrasera la zone par une nouvelle zone placée aux coordonnées du héros. Voici à quoi peut ressembler notre évènement parallèle :
Event - EV002
| > Commentaire : On initialise la zone
| > Appeler Script : V[1] = create_circle_area(player_x, player_y, 3)
| > Commentaire : Vient notre habituelle boucle !!!
| > Boucle
| >| > Attendre : 1 Frames
| >| > Commentaire : On met à jours la boucle !
| >| > Appeler Script : V[1] = create_circle_area(player_x, player_y, 3)
| >| >
| > Fin - Boucle
| >


On crée une première fois la zone pour être sur qu'elle existe quand nous la testerons sur les PNJ's qui devront réagir à la zone. J'ai choisi un rayon de trois mais vous êtes évidemment libre de choisir le rayon de votre choix ! Smiley

Faire apparaître et disparaître les PNJ's


Maintenant qu'à chaque frame de notre carte, notre zone est mise à jours avec les bonnes coordonnées, il suffit de créer un évènement (que nous pourrons dupliquer) qui, s'il se trouve dans la zone, devient visible, s'il ne l'est pas devient invisible ! Rien de très compliqué Smiley

Event - EV001
| > Boucle
| >| > Attendre : 1 Frames
| >| > Condition : Script : in_area?(V[1], event_x(@event_id), event_y(@event_id))
| >| >| > Déplacer évènement : Cet événement (Attendre la fin)
| >| >| > Déplacer évènement : > Transparent OFF
| >| >| > Afficher une émoticône : Cible - Cet événement, Exclamation
| >| >| >
| >| > Sinon
| >| >| > Déplacer évènement : Cet événement (Attendre la fin)
| >| >| > Déplacer évènement : > Transparent ON
| >| >| >
| >| > Fin - Condition
| >| >
| > Fin - Boucle
| >


Cette fois, on se sert des coordonnées de l'évènement courant et non du héros, pour voir s'il se trouve dans la zone.

J'utilise @event_id qui signifie "Cet évènement ci", soit l'évènement appelant! Comme ça je peux dupliquer comme un sauvage mon évènement :D


Voyons tout de suite ce que cela donne :



Comme vous pouvez le voir, c'est très facile à utiliser et les ça réduit tout de même une grande partie des calculs :)

icone Attaquons les zones polygonales: système d'infiltration !!!


Les zones polygonales... elles sont... ahem... trop cool ! C'est une des composantes de l'Event Extender que je préfère ! Non seulement parce que je trouve leur implémentation (la manière dont elles sont codées) trop cool, mais aussi parce qu'elles ouvrent des perspectives de programmation assez cools !


Une fois n'est pas coutume, je vais vous montrer ce que nous allons programmer avant que nous le fassions, soit un tout petit système d'infiltration tout mignon, basé sur un champ de vision un peu plus précis !


Il est possible que ce Gif lag un petit peu mais je suppose que vous voyez l'idée !


Cette fois l'exercice sera un petit peu plus complexe. Voyons voir étape par étape comment j'ai fait !

Créer une zone polygonale


La construction d'une zone polygonale (potentiellement non convexe) est une tâche un petit plus complexe, il faut lui passer une liste de points :
Code (Ruby):
  1. V[1] = create_polygon_area([[x1,y1],[x2,y2],[x3,y3],[x4,y4]])
.
On peut évidemment mettre autant de points que l'on désire ! Le premier point est lié avec le second, le second avec le troisième, qui lui même est lié avec le quatrième etc. Le dernier point est toujours lié avec le premier. Il est donc important d'encoder ses points dans un ordre cohérent :)

La construction des images


J'ai d'abord mappé ma carte fort minable, ensuite, j'ai pris une capture d'écran et dans photoshop, j'ai construit mes deux images de zones (celle de gauche et celle de droite). J'ai pu récupérer leurs coordonnées via Photoshop (bouuuuh, un logiciel non libre !!!). Je les aies soigneusement notée et j'ai exportée mes deux images.

Construction de l'évènement principal


Une fois de plus, on commence par un évènement en processus parallèle ! Je vous montre le code puis je l'explique :
Event - EV002
| > Commentaire : On affiche les deux images. Dont la seconde (la vue a droite)
| > Commentaire : est transparente car elle ne doit pas être visible !
| > Afficher une image : 1, 'left', H.G. (0,0), (100%,100%), 255, Normale
| > Afficher une image : 2, 'right', H.G. (0,0), (100%,100%), 0, Normale
| > Commentaire : On fixe les images sur la carte au moyen de la commande
| > Commentaire : picture_pin !
| > Appeler Script : picture_pin(1)
| > Appeler Script : picture_pin(2)
| > Commentaire : On initialize les variables
| > Commentaire : SV[1] sera un compteur
| > Commentaire : SS[1] est un interupteur désactivé, il correspondra au changement
| > Commentaire : d'axe
| > Appeler Script : SV[1] = 0
| > Appeler Script : SS[1] = false
| > Commentaire : On stocke la liste des coordonnées
| > Commentaire : V[2] = les coordonnées de la zone de gauche
| > Commentaire : V[3] = les coordonnées de la zone de droite !
| > Appeler Script : V[2] = [[350, 192], [350, 217], [192, 310], [192, 126]]
| > Appeler Script : V[3] = [[382, 192], [392, 217], [541, 310], [541, 126]]
| > Commentaire : Au début le méchant regarde à gauche ! Donc la zone de gauche
| > Commentaire : est basé sur la variable 2
| > Appeler Script : V[4] = create_polygon_area(V[2])
| > Boucle
| >| > Attendre : 1 Frames
| >| > Commentaire : On incrémente le compteur et on le limite à la valeur 400
| >| > Commentaire : grâce au MODULO ! (N'hésitez pas à lire le tuto de Joke si
| >| > Commentaire : c'est flou, le modulo)
| >| > Appeler Script : SV[1] += 1
| >| > Appeler Script : SV[1] %= 400
| >| > Commentaire : Si le compteur est inférieur à 200, le personnage regarde à gauche
| >| > Commentaire : et son interrupteur doit être désactivé.
| >| > Commentaire : Si le compteur est superieur ou égal à 200, le personnage regarde
| >| > Commentaire : à droite et son interrupteur doit être activé !
| >| > Condition : Script : SV[1] >= 200
| >| >| > Commentaire : Il regarde a droite
| >| >| > Condition : Script : not SS[1]
| >| >| >| > Afficher une image : 1, '', H.G. (0,0), (100%,100%), 0, Normale, 60 Frames
| >| >| >| > Déplacer évènement : [EV001] (Attendre la fin)
| >| >| >| > Déplacer évènement : > Regarde vers la Droite
| >| >| >| > Afficher une image : 2, '', H.G. (0,0), (100%,100%), 255, Normale, 60 Frames, Attendre
| >| >| >| > Appeler Script : V[4] = create_polygon_area(V[3])
| >| >| >| > Appeler Script : SS[1] = true
| >| >| >| >
| >| >| > Fin - Condition
| >| >| >
| >| > Sinon
| >| >| > Commentaire : Il regarde a gauche
| >| >| > Condition : Script : SS[1]
| >| >| >| > Afficher une image : 2, '', H.G. (0,0), (100%,100%), 0, Normale, 60 Frames
| >| >| >| > Déplacer évènement : [EV001] (Attendre la fin)
| >| >| >| > Déplacer évènement : > Regarde vers la Gauche
| >| >| >| > Afficher une image : 1, '', H.G. (0,0), (100%,100%), 255, Normale, 60 Frames, Attendre
| >| >| >| > Appeler Script : V[4] = create_polygon_area(V[2])
| >| >| >| > Appeler Script : SS[1] = false
| >| >| >| >
| >| >| > Fin - Condition
| >| >| >
| >| > Fin - Condition
| >| >
| > Fin - Boucle
| >


La phase d'initialisation consiste à afficher les deux images des zones. Comme le méchant commence en regardant à gauche, l'image de gauche est visible, celle de droite est invisible (au moyen de l'opacité). Ensuite, comme la map est plus grande que l'écran. J'utilise la commande picture_pin(ID), pour dire que l'image référencée par l'ID passé en argument défile avec la carte (comme si elle était attachée).
Ensuite j’initialise un compteur (via une variable locale Smiley) et un interrupteur!
Ensuite je crée les points dans des variables pour n'avoir qu'a changer la valeur de la zone en fonction de la direction où regarde le méchant !

Il existe des manières d'effectuer des projections matricielles sur les zones, et de les déformer, cependant, c'est un petit peu (de mon point de vue), trop complexe, donc pour l'usage nous n'allons que préparer deux collections de coordonnées pour notre zone et fonction de la direction de l'ennemi, nous lui attribueront les bonnes valeurs!


Ci fait, nous pouvons créer la zone en lui donnant les coordonnées de la zone de gauche (car notre grand méchant regarde d'abord vers la gauche). Puis s'en suit une petite boucle qui alterne toutes les 200 frames de côté. Changeant la zone, l'opacité des images et activant/désactivant l'interrupteur (pour ne modifier la zone que quand c'est nécessaire).
Bref, rien de très compliqué, le contenu de la boucle est "un peu long" car il y a un tout petit peu d'habillage.
Il ne nous reste plus qu'a détecter si le héros est dans la zone, car il n y en a qu'une seule (qui change en fonction du regard de l'antagoniste).

Vérifier si le héros est prit ou non!


Cette partie ressemble fortement aux autres, cependant il y a une petite nuance. En effet, par soucis de précision, j'ai utilisés les coordonnées en pixels et non en cases de la zone. Il faudra donc se servir des commandes player_pixel_x et player_pixel_y (qui existent aussi pour les évènements Smiley).
Je me suis servi d'un autre évènement en processus parallèle qui boucle :

Event - EV003
| > Boucle
| >| > Attendre : 1 Frames
| >| > Condition : Script : in_area?(V[4], player_pixel_x, player_pixel_y)
| >| >| > Déplacer évènement : [EV001] (Attendre la fin)
| >| >| > Déplacer évènement : > Saut : 0 en X, 0 en Y
| >| >| > Déplacer évènement : > Attendre : 10 Frames
| >| >| > Déplacer évènement : > Saut : 0 en X, 0 en Y
| >| >| > Message : Ø, Ø, Normal, Haut
| >| >| > Message : VU ! VU ! VU !
| >| >| > Téléporter l'équipe : [003:30], (X:002, Y:004)
| >| >| >
| >| > Fin - Condition
| >| >
| > Fin - Boucle
| >


Rien de bien compliqué de ce côté non plus !!

icone Conclusions


C'en est fini de cette introduction aux zones d'interactions. J'espère de tout coeur que ce didacticiel aura été formateur et que cela vous ouvrira des perspectives amusantes! Car je n'ai évidemment pas survolé toutes les possibilités offertes par cette fonctionnalité ! (Vous pourriez par exemple, rapidement mettre en place un système de "Point And Click").
Mais je vous laisse à votre imagination pour impressionner le MONDE ENTIER !

Je conclurai par ... YEAH ! On est de RETOUR !
Je passe donc un Bigup à Zangther pour l'Event Printer, Nuki pour l'avoir corrigé pour la Biloucorp, Joke pour être là Smileyet à tous mes camarades bilouteux et tous les makers qui aiment créer et qui s'amuse INTO DA LIFE !

Good night and Good Luck !

Index

Tags

Annonces
Bilou Concept
BilouCorp
Découvertes
Event Extender
Jeux
RPG Maker
Script
Tutoriel

Auteurs

2cri
Grim
Hiino
Joke
Nuki
PypeBros
Raho
S4suk3

Suivez nous
Rss

Poster un commentaire



Commentaires

Kijewoku
Merci beaucoup pour ce tuto ! Je suis en train de me familiariser avec l'Event Extender, et les tutos sont bien utiles pour commencer à le prendre en main. ;)

Posté le : 20/01/2016 à 15h37
Grim
Merci à vous !
Gaetz > La concurrence c'est aussi offrir aux makers l'alternative !
Et je t'assure que je rédigerai toujours quelqu'un vers GeeX s'il vise quelque chose de "plus ambitieux" :) Posté le : 14/11/2014 à 16h03
Gaetz
Très bon tuto ! C'est un peu dommage qu'on ait développé la même chose avec Geex et EE ^^ Posté le : 14/11/2014 à 10h09
Joke
OMG!!

Excellente rédaction, Grim, pour un sujet qui illuminera plus d'un maker ! Posté le : 13/11/2014 à 18h21
spyrojojo
parfait alor ^^. pour le moment j'ai les infos qu'il me faut , merci ;) Posté le : 13/11/2014 à 13h24
Grim
Oui oui, les zones de RM sont compatibles avec les zones de l'EE. Les zones de l'EE ne sont pas "dessinables" sur la carte, mais sont tout de même bien plus flexibles (elle peuvent bouger, être détecter à la souris, être au pixel près, carrées, rectangulaires, circulaires, elliptiques et même polygonales non convexes). Elles peuvent aussi changer de cible :)

N'hésite pas a poser tes questions ici ;) Posté le : 13/11/2014 à 10h31
spyrojojo
Intéressant tout ça .Surtout la partie sur les zones polygonales qui semble assez complexe sur le coup mais sacrément utile si on les utilise bien .Bien que les options de bases d'Ace sur les zones sont déjà assez complètes, la possibilité de le faire au pixel près reste très utile (bonne nouvelle pour moi sa). reste à savoir , pour mon projet si on peut chevaucher les zones de RM sur celle d'EE ^^ (mais je pense que oui), et si l'utilisation de variable local pour un system de ce genre est possible. Pour conclure , cet article a pu éclairer certains points sur lequel je m'interroger mais me pousse vers 2 autres questions ^^ (et aussi vers le tuto de Joke sur les modulo :( ° Posté le : 13/11/2014 à 10h28