Skip to content

Commit

Permalink
feat(content): New chapter 'Scripting in Ruby' in RPG Maker
Browse files Browse the repository at this point in the history
Chapter ported from the wiki with minor adjustments
  • Loading branch information
aureliendossantos committed Dec 15, 2022
1 parent 8f563ee commit 3850d9e
Show file tree
Hide file tree
Showing 20 changed files with 874 additions and 0 deletions.
82 changes: 82 additions & 0 deletions content/rpg-maker/04-rgss3/01-principes-du-rgss.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
title: "Créer un pierre-feuille-ciseaux"
description: "Le guide pour créer un pierre-papier-ciseaux entièrement en scripts sur RPG Maker VX Ace. Apprenez à scripter en Ruby et RGSS pour créer vos propres systèmes sur RPG Maker !"
---

Vous créez des jeux sur RPG Maker, vous gérez bien les évènements et vous vous demandez comment écrire des scripts ? Alors ce chapitre est fait pour vous !

Nous allons réaliser un jeu de chifoumi (qui est l'appellation cool de pierre-papier-ciseaux) via Ruby et RGSS3 pour RPG Maker VX Ace, en partant du principe que vous n'avez aucune connaissance en programmation en dehors des évènements.

<Video
src="demo.mp4"
poster="resultat.png"
muted loop controls
/>

<Callout heading="Attention">
Ce guide fonctionne uniquement avec RPG Maker VX Ace, qui utilise le langage de script Ruby et RGSS3. Vous ne pourrez pas utiliser ce code pour les autres versions de RPG Maker.
</Callout>

Même si l'histoire de votre jeu n'implique pas un tournoi de chifoumi, ce cours peut vous être très utile pour découvrir la programmation. Ainsi, vous aurez les bases pour écrire les scripts de votre projet, mais vous serez aussi plus à l'aise pour programmer sur d'autres moteurs par la suite !

<Bulle emote="remi-prof">
Nous ferons abstraction de la théorie compliquée, mais vous allez pratiquer de nombreux concepts utilisés en programmation.
</Bulle>

<Bulle emote="astride-smile">
Et tout cela, sans quitter RPG Maker !
</Bulle>

### Principes du RGSS

#### La notion de scène

Dans RPG Maker, chaque écran est une scène. Suivons un parcours typique dans un jeu RPG Maker :

1. On arrive sur l'écran-titre,
2. on lance une nouvelle partie,
3. on explore la carte,
4. on ouvre le menu,
5. on retourne sur la carte,
6. on entre dans un combat,
7. la victoire nous amène sur une autre carte,
8. on entre dans un magasin,
9. on retourne sur la map et on meurt.

On aura lancé plusieurs scènes comme le montre ce schéma.

<Image
src="schema1.png"
alt="Schéma du parcours typique d'un joueur."
/>

Vous l'aurez compris, tous les écrans sont des scènes. En RGSS, une scène est représentée par une classe. Dans l'éditeur de script, vous pouvez consulter l'intégralité des scènes du RGSS.

<Image
src="scenes.png"
alt="Scènes du RGSS dans l'éditeur de script."
/>

Pour créer notre mini-jeu, nous allons créer un nouvel écran où se déroulera le chifoumi, et donc une scène dédiée.

#### Un langage orienté objet

Ruby est un langage orienté objet, ce qui signifie que tous les éléments sont basés sur un modèle, appelé classe. Par exemple, dans un système de combat, nous serons amenés à créer toutes sortes de monstres : des zombies, des chauve-souris... Tous ces ennemis ont des choses en commun : ils ont des caractéristiques et peuvent attaquer le joueur. Au lieu de réécrire ces comportements dans chaque monstre, nous écrivons une classe « ennemi » contenant ces informations communes, et nous l'appliquons à chaque monstre. Dans la programmation orientée objet (plus spécifiquement orientée classe), on est amené à utiliser des classes déjà existantes et à créer nos propres classes pour décrire des éléments.

#### Le RGSS, c'est plein de classes

Dans RPG Maker, le RGSS nous offre énormément de classes déjà écrites. Pour vous en rendre compte, je vous invite à ouvrir l'éditeur de script et à survoler les différentes sections. Pour réaliser un système en RGSS, on part de classes déjà existantes et on en crée de nouvelles.

<Bulle emote="remi-smile">
Il existe toute une série d'autres classes qui sont inaccessibles via l'éditeur de script, mais décrites dans l'aide du logiciel.
</Bulle>

<Bulle emote="astride-wink">
Le scripteur averti les consultera régulièrement, mais nous n'en aurons pas besoin ici !
</Bulle>

Dans la prochaine section, nous allons créer notre propre scène en utilisant des classes existantes !

<Callout heading="Crédits">
Ce chapitre est adapté de l'article de msp (S4suk3) sur la [BilouCorp](http://www.biloucorp.com/creation-dun-shifumi-avec-le-rgss3-16).
</Callout>
138 changes: 138 additions & 0 deletions content/rpg-maker/04-rgss3/02-creation-d-une-scene.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
title: "Création d'une scène"
description: "Le guide pour créer un pierre-papier-ciseaux entièrement en scripts sur RPG Maker VX Ace. Apprenez à scripter en Ruby et RGSS pour créer vos propres systèmes sur RPG Maker !"
---

Rendez-vous dans l'éditeur de script et créez un emplacement sous Materials. On place généralement nos scripts dans Materials pour qu'ils soient en dessous des scripts qui composent le RGSS, et au dessus de Main, qui correspond à la boucle du jeu. Un script placé après Main ne serait jamais exécuté.

<Image
src="emplacement.png"
alt="Création d'un emplacement dans l'éditeur de script."
/>

Certains programmeurs fractionnent les différentes composantes de leurs scripts dans des emplacements séparés. Pour un script aussi petit que le notre, ou pour un script destiné au partage, on peut tout mettre dans un seul emplacement. Ecrivons le squelette de notre scène :

```ruby
class Scene_Chifoumi < Scene_Base
# Ici se trouvera le code notre scène
end
```

Les textes précédés de `#` sont des commentaires ignorés par le programme. Cela permet de structurer le code pour aider le scripteur à s'y retrouver. On s'en sert également pour expliquer le fonctionnement du script aux utilisateurs.

La première ligne indique que nous créons une classe appelée `Scene_Chifoumi`, et `< Scene_Base` indique que notre classe héritera de la classe `Scene_Base`.

`end` marque la fin d'un bloc. Ici, cela signifie que la définition de la classe se termine. Toute la caractérisation de la scène se trouvera entre `class` et `end`.

### Qu'est ce que l'héritage ?

En créant une nouvelle classe, on peut faire en sorte qu'elle possède toutes les caractéristiques d'une autre classe déjà existante. On appelle ce lien l'héritage.

<Bulle emote="astride-smile">
Cela vous évite de réécrire du code qui existe déjà !
</Bulle>

Le RGSS comporte une collection de classes déjà programmées pour nous faciliter le travail. Notre classe `Scene_Chifoumi` aura exactement le même comportement que `Scene_Base`, une classe très générique qui comprend toutes les routines de base d'une scène.

### Testons notre scène !

Dans un évènement, utilisez la commande « Appel de script » et écrivez :

```ruby
SceneManager.call(Scene_Chifoumi)
```

Dans le jeu, déclencher cet évènement vous enverra sur notre scène, qui devrait être toute noire. C'est normal, nous n'avons encore rien fait dessus. Avec cette commande, vous pouvez également essayer d'accéder à d'autres scènes, comme `Scene_Title` !

### La structure d'une scène

Avant de nous soucier d'ajouter des choses à notre scène, il est important de comprendre sa structure. Voici, de manière fort schématique, le déroulement d'une scène :

<Image
src="schema2.png"
alt="Schéma du déroulement d'une scène"
/>

Quand on appelle une scène, la méthode `start` se lance. Une méthode est une action référente à une classe. On va donc effectuer les premières tâches : afficher les images, les menus, etc.

Une fois que cette action est terminée, on boucle dans la méthode `update`, jusqu’à ce qu'une interruption soit envoyée. Si cette interruption engendre la fin de la scène, par exemple dans le cas d'un changement de scène, on va dans la méthode `terminate`. Celle-ci va supprimer tout ce qu'il faut avant de quitter la scène.

Grâce à l'héritage de `Scene_Base`, nous n'avons pas à écrire ces méthodes. `update` rafraichit déjà chacune des `Window` et `terminate` les supprime. Nous devrions réécrire ces méthodes uniquement pour rafraichir ou supprimer d'autres éléments.

### Les variables d'attribut

Une variable est une étiquette liée à une valeur :

```ruby
je_suis_une_variable = 10
je_suis_une_variable = je_suis_une_variable + 1
```

Dans cet exemple, `je_suis_une_variable` vaudra 11. On peut stocker toutes sortes de choses dans une variable, par exemple une image ou une `Window`. Cependant, une variable possède une portée limitée ! Par exemple, si je crée une variable dans la méthode `start`, elle n'existera pas dans la méthode `update`, parce que sa durée de vie est limitée à `start`. Pour pallier à cela, il existe les variables d'attribut.

Nous avons vu qu'une classe permet de décrire des éléments par des caractéristiques. Les attributs sont des variables servant à caractériser une classe. Il suffit de rajouter `@` devant le nom et on pourra accéder à cette variable partout dans la classe.

Concrètement, quand j'aurai besoin d'une valeur temporaire, j'utiliserai une variable normale, et quand j'aurai besoin de garder cette valeur tout au long de la classe, j'utiliserai un attribut, dont le nom commence par `@`.

### Notre premier élément

Réalisons la première fenêtre de notre scène :

<Image
src="premierefenetre.png"
alt="Capture d'écran de la première fenêtre de la scène"
/>

Nous pourrions directement créer cette composante dans la méthode start, cependant j'ai l'habitude de fractionner mon code en sous-procédures. Dans notre classe, nous allons donc créer une nouvelle méthode chargée de créer la fenêtre de titre :

```ruby
class Scene_Chifoumi < Scene_Base
# Lancement de la scène
def start
super
create_title
end
def create_title
# Ici on créera le titre
end
end
```

Pour afficher une fenêtre en haut de la scène, utilisons une composante du RGSS : `Window_Help`. Pour comprendre son fonctionnement, ouvrez le script dans l'éditeur. La méthode `initialize` sera appelée la première fois, pour la construction de l'objet. On appelle cela un constructeur.

En écrivant `MaClasse.new`, j'appelle la méthode `initialize` de la classe `MaClasse` et je construis une instance de cette classe. Dans notre exemple, nous avons besoin d'une fenêtre d'une case de hauteur, afin d'écrire une ligne. Nous écrivons ceci :

```ruby
class Scene_Chifoumi < Scene_Base
# Lancement de la scène
def start
super
create_title
end
def create_title
@title = Window_Help.new(1)
end
end
```

L'utilisation d'un attribut avec `@` est obligatoire, car la méthode `terminate` devra supprimer la fenêtre lorsqu'on quitte la scène. Ainsi, même si on a l'impression d'utiliser la fenêtre de titre une seule fois, ce n'est pas vraiment le cas.

En testant la scène, on peut voir notre fenêtre, bien qu'elle soit vide. Nous allons utiliser une méthode de `Window_Help` qui s'appelle `set_text`. Vous pouvez examiner son fonctionnement dans le code de `Window_Help`. Cette méthode permet d'écrire du texte dans la fenêtre :

```ruby
class Scene_Chifoumi < Scene_Base
# Lancement de la scène
def start
super
create_title
end
def create_title
@title = Window_Help.new(1)
@title.set_text("CHI FOU MI !")
end
end
```

Cette fois vous pouvez tester la scène et... magie ! Elle ressemble à notre objectif !

Nous avons créé un premier élément graphique et en plus, nous avons été modernes car nous avons utilisé une méthode ! Sachez que dans une classe, vous pouvez créer autant de méthodes que vous le souhaitez. Personnellement, j'utilise les méthodes pour améliorer la lisibilité et éviter les trop grosses portions de code !
139 changes: 139 additions & 0 deletions content/rpg-maker/04-rgss3/03-le-menu-de-selection.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
title: "Le menu de sélection"
description: "Le guide pour créer un pierre-papier-ciseaux entièrement en scripts sur RPG Maker VX Ace. Apprenez à scripter en Ruby et RGSS pour créer vos propres systèmes sur RPG Maker !"
---

Nous avons un titre... c'est un début. Maintenant, il serait intéressant d'avoir un véritable élément d’interactivité : un menu de sélection des coups pierre, papier et ciseaux. C'est sans doute la partie la plus importante de ce guide. En effet, nous allons apprendre à créer des interactions entre l'utilisateur et le jeu au moyen d'une composante du RGSS !

### Une classe héritée de Window_Command

Le RGSS met à notre disposition la classe `Window_Command` pour représenter des listes de choix. Comme pour notre scène, nous allons créer, sous la classe `Scene_Chifoumi`, une classe pour la sélection du coup ! Vous pouvez l'ajouter dans un autre emplacement de script, mais je choisis de l'écrire à la suite, dans le même emplacement.

```ruby
class Window_Chifoumi < Window_Command
end
```

Dans le code de `Window_Command`, on peut voir que son constructeur prend deux arguments déterminant la position en X et en Y. Créons une fenêtre Window_Chifoumi dans une nouvelle méthode `create_commands`.

```ruby
# Scène principale
class Scene_Chifoumi < Scene_Base
# Lancement de la scène
def start
super
create_title
create_commands
end
# Création de la fenêtre de titre
def create_title
@title = Window_Help.new(1)
@title.set_text("CHI FOU MI !")
end
# Création de la fenêtre de sélection
def create_commands
@window_selection = Window_Chifoumi.new(0, 48)
end
end

# Fenêtre de sélection du coup
class Window_Chifoumi < Window_Command
end
```

En testant ceci... vous ne voyez rien de plus qu'une petite fenêtre positionnée en (0, 48) et dotée d'une petite flèche ! C'est normal, car nous n'avons pas encore spécifié les choix disponibles.

### Ajouter des commandes

Ajouter une liste de commandes à notre fenêtre de sélection est très simple. Il suffit d'ajouter une méthode `make_command_list` dans laquelle on utilise la méthode `add_command`, qui prend deux arguments : le texte affiché dans la liste, et un symbole pour identifier la valeur sélectionnée. Le symbole est un texte précédé de `:` et sera traité quand on programmera l'interaction avec notre fenêtre de sélection.

```ruby
class Window_Chifoumi < Window_Command
# Création de la liste de sélection
def make_command_list
add_command("Pierre", :pierre)
add_command("Papier", :papier)
add_command("Ciseaux", :ciseaux)
end
end
```

Nous pouvons tester la scène : ça a tout de même plus de classe que précédemment !

<Image
src="choix.png"
alt="Capture d'écran de la fenêtre de sélection"
/>

C'est génial parce qu'en très peu de lignes, nous avons déjà pas mal de choses, et nous avons survolé une grande quantité de concepts. Maintenant, nous pouvons programmer des actions en fonction du choix.

### Créer des cas de figure

Chaque cas de figure sera une méthode, appelée si le bon choix est effectué. Dans un premier temps, notre application se contentera de confirmer le coup choisi en l'écrivant dans la console. Si ce n'est pas déjà fait, cliquez sur « Afficher la console » dans le menu Jeu.

```ruby
class Scene_Chifoumi < Scene_Base
# Lancement de la scène
def start
super
create_title
create_commands
end
# Création de la fenêtre de titre
def create_title
@title = Window_Help.new(1)
@title.set_text("CHI FOU MI !")
end
# Création de la fenêtre de sélection
def create_commands
@window_selection = Window_Chifoumi.new(0, 48)
end
# Cas de sélection de Pierre
def pierre
p "Vous avez choisi la pierre"
end
# Cas de sélection de Papier
def feuille
p "Vous avez choisi la feuille"
end
# Cas de sélection de Ciseaux
def ciseaux
p "Vous avez choisi les ciseaux"
end
end
```

La méthode `p` affiche un message dans la console, mais cela ne va pas encore fonctionner. Maintenant que nos méthodes sont prêtes, nous allons indiquer à la fenêtre de sélection qu'elle doit appeler la bonne méthode d'après le choix du joueur.

Nous devons utiliser la méthode `set_handler` de `Window_Base`, que `Window_Chifoumi` possède aussi grâce à l'héritage. `set_handler` prend deux arguments : un symbole et une méthode à appeler. Nous avons déjà défini les symboles dans `add_command`.

```ruby
# Création de la fenêtre de sélection
def create_commands
@window_selection = Window_Chifoumi.new(0, 48)
@window_selection.set_handler(:pierre, method(:pierre))
@window_selection.set_handler(:feuille, method(:papier))
@window_selection.set_handler(:ciseaux, method(:ciseaux))
end
# Cas de sélection de Pierre
def pierre
p "Vous avez choisi la pierre."
end
# Cas de sélection de Papier
def feuille
p "Vous avez choisi le papier."
end
# Cas de sélection de Ciseaux
def ciseaux
p "Vous avez choisi les ciseaux."
end
```

J'ai utilisé `method(:nom_methode)` pour passer la méthode en argument à `set_handler`. Celle-ci prend en argument une chose à exécuter. En testant la scène, vous remarquerez que le message correspondant à votre sélection s'affiche bien dans la console.

<Image
src="console.png"
alt="La console RGSS"
/>

Nous avons assez de matière pour créer notre application. Nous savons afficher des fenêtres, créer des fenêtres de sélection, relier une sélection à une action... Nous pouvons coder le raisonnement logique du jeu !
Loading

0 comments on commit 3850d9e

Please sign in to comment.