DynamicLight

📅avril 20, 2019 👨‍💼

Introduction

Bonjour à tous 🙂

J’ai programmé un système de lumière dynamique. Ce système permet de reproduire des choses comme l’arène de Rosalia (dans HGSS), il vous permettra également de réaliser des grottes un peu plus vivantes. Voici une vidéo de démonstration :

Comment installer le script

Pour installer le script, vous devez télécharger le fichier suivant : 00500_NuriYuri_DynamicLight.7z
Et l’extraire à l’aide de 7zip dans le dossier scripts de votre projet ( DossierDuProjet/scripts ).

Vous aurez également besoin du fichier suivant : dynamic_light.7z à extraire dans graphics/particles.

Démarrer le système

Pour démarrer le système vous devez mettre (dans un événement) la commande de script suivante avant la commande de téléportation :

NuriYuri::DynamicLight.start do |dl|
  # Light definition
end

Vous pouvez mettre toutes vos définitions de lumière avant la ligne end de cette commande.
Par exemple :

NuriYuri::DynamicLight.start do |dl|
  dl.add(0, 0, 2, 0, 0, 0.3, type: dl::ScalableDLS)
  dl.switch_off(0)
  dl.add(1, 2, 2)
  dl.add(2, 2, 2)
  dl.add(3, 2, 2)
end

Cette commande affichera une lumière zoomable animée sur le héros (qui sera éteinte), et des lumières animées sur les événements 001 002 et 003, le résultat sera le suivant :

Pour bien comprendre ce qu’il s’est passé, voici les explications détaillés.
On a dit à NuriYuri::DynamicLight d’exécuter les instructions indiquées entre do |dl| et end lors de la prochaine téléportation. Quand les instructions sont exécutées dl contient NuriYuri::DynamicLight (c’est un raccourcis d’écriture). On lui indique d’ajouter des lumières.

L’instruction d’ajout de lumière est NuriYuri::DynamicLight.add(event_id, light_type, animation_type, zoom_count, opacity_count, *args)

  • dl.add(0, 0, 2, 0, 0, 0.3, type: dl::ScalableDLS) ajoute une lumière zoomable (c’est type: dl::ScalableDLS qui l’indique) ayant pour zoom 0.3. Son type est 0 (les lumières ayant un cercle de 320 px de rayon) et son animation est l’animation n°2 (zoom variant entre 0.65 et 0.75, opacité variant entre 225 et 255).
  • dl.switch_off(0) éteint la lumière d’index 0 (la première ajoutée à l’aide de dl.add).
  • dl.add(1, 2, 2) ajoute une lumière normale de type 2 (cercle de 96 px de rayon) et d’animation 2 sur l’évènement 001 de la map où on va se téléporter.
  • dl.add(2, 2, 2) pareil mais avec l’évènement 002.
  • dl.add(3, 2, 2) pareil mais avec l’évènement 003.

Vous pouvez appeler la fonction NuriYuri::DynamicLight.start entre chaque téléportation (quand les salles sont différentes). Notez d’ailleurs que le script se charge de mémoriser vos ajouts et changements pour le cas où le joueur recharge la partie 🙂

Arrêter le système

Lorsque vous sortez de la grotte, il est intéressant de désactiver le système de DynamicLight, pour ça rien de plus compliqué, ajoutez la commande suivante avant la commande de téléportation :

NuriYuri::DynamicLight.stop_delay

Allumer / éteindre des lumières

Pour allumer une lumière, vous pouvez utiliser la commande :

NuriYuri::DynamicLight.switch_on(light_index)

light_index est un nombre variant de 0 à n-1 où n est le nombre de .add que vous avez mis dans la commande de démarrage. (0 est le premier .add, 1 le deuxième etc…)

Pour éteindre une lumière, entrez la commande :

NuriYuri::DynamicLight.switch_off(light_index)

Détecter si une lumière est allumée

Pour savoir si une lumière est allumée, utilisez la condition de script suivante :

NuriYuri::DynamicLight.light_sprite(light_index).on

Accéder au zoom d’une lumière zoomable

Pour accéder au zoom d’une lumière zoomable, vous devez entrer le morceau de code suivant :

NuriYuri::DynamicLight.light_sprite(light_index).scale

Par exemple, pour savoir si la lumière du héros est pas très grande en condition script :

NuriYuri::DynamicLight.light_sprite(0).scale < 0.5

Modifier le zoom d’une lumière zoomable

Entrez la commande suivante :

NuriYuri::DynamicLight.light_sprite(0).scale_to(target_zoom, duration)
  • target_zoom est le zoom final de la lumière, par exemple 0.5
  • duration est la durée de l’animation pour passer du zoom actuel au zoom final. (0 = immédiat)

Créer un nouveau type d’animation de zoom / opacité

Les animations sont stockées dans NuriYuri::DynamicLight::ANIMATIONS c’est un tableau qui contient chaque animation sous forme de Hash contenant les valeurs de zoom et d’opacité pour chaque frame de l’animation.

Pour en ajouter une vous pouvez entrer dans un nouveau script la ligne suivante :

NuriYuri::DynamicLight::ANIMATIONS[animation_id] = { zoom: [list_zoom], opacity: [list_opacity] }

Par exemple, pour créer l’animation 3 affichant une lumière qui déconne complètement :

rand_array = Array.new(10) { Math::exp(rand) / 2.71 }
NuriYuri::DynamicLight::ANIMATIONS[3] = { 
  zoom: Array.new(50) { |i| rand_array[i / 5].to_f }, 
  opacity: [255]
}

Je vous invite à lire cette partie du tutoriel ruby pour comprendre : Lien vers la partie.

Créer un nouveau type de lumière

Chaque type de lumière est stocké dans la variable NuriYuri::DynamicLight::LIGHTS, ce tableau contient des tableaux indiquant les infos des lumières.

La première case du tableau d’infos est le type :

  • :normal : Ne regarde pas la direction de son événement pour changer son angle.
  • :direction : Regarde la direction de son événement pour changer son angle.

(Toutes les lumières sont normalement dirigées vers le haut)

La deuxième case indique le nom du fichier dans graphics/particles qui servira de masque pour afficher la lumière.
La troisième case est optionnelle (ne la mettez pas si vous ne vous en servez pas) elle donne le nom de l’image (dans graphics/particles) qui sera affiché dans le viewport de la map.

Exemple : Ajouter un cercle de 128px de rayon

NuriYuri::DynamicLight::LIGHTS[3] = [:normal, 'dynamic_light/circle_128']

Code à mettre dans un nouveau script, pensez à mettre l’image du cercle de 128px de rayon dans graphics/particles/dynamic_light.

Il faudra mettre light_type à 3 pour utiliser ce cercle de 128px de rayon comme masque.

Autres infos

Ce script est disponible sur Gitlab (dynamiclightscript), vous pouvez l’ajouter et le mettre à jour à l’aide de git. Il vous suffit soit d’ajouter ce script en sous module dans le dossier scripts de votre projet, soit de le cloner dans le dossier scripts :

git submodule add git@gitlab.com:NuriYuri/dynamiclightscript.git "00500 NuriYuri DynamicLight"

Ou

git clone git@gitlab.com:NuriYuri/dynamiclightscript.git "00500 NuriYuri DynamicLight"

Script