❤ 0 Création d'un Shifumi avec le RGSS3
Partie 1/2
Cet article va présenter comment créer un jeu de pierre-feuille-ciseaux en script de manière rapide, sans s'étaler théoriquement sur les concepts survolés. J'invite donc les lecteurs méticuleux à effectuer leurs propres recherches... parce que c'est tout de même plus cool de connaitre correctement ce que l'on utilise.
Introduction
Bonjour ! Si tu as fantasmé sur les scripts des gens, que tu as toujours voulu créer tes propres systèmes, que tu trouves que l'Event-Making, c'est beaucoup de choses pour pas grand chose mais que tu as toujours trouvé que l'apprentissage des scripts était une chose trop complexe (et oui... apprendre le Ruby puis comprendre le RGSS c'est pas toujours évident!), ce tutoriel est pour toi !
En effet, nous allons apprendre à réaliser un Shi-Fu-Mi (qui est l'appellation cool de Pierre-Feuille-Ciseaux) via Ruby et le RGSS3 (de RPG Maker VX Ace donc) en admettant que vous n'avez strictement aucune connaissance en programmation autre que l'Event-Making.
Je suis moi même persuadé que l'apprentissage de la programmation est une démarche rigoureuse et qui demande beaucoup d'implication, mais comme la tendance n'est pas à la rigueure mais au prêt-à-coller, je vais tenter de faire, au mieux, abstraction de pleins de choses compliqués, qui, généralement, font tomber les débutants dans un état de léthargie typique.
Avant propos sur Ruby et le RGSS
J'ai promis qu'il n y aurait pas de baratin technique... j'ai mentit. En effet, je pense que pour que ce tutoriel soit utile, quelques directives techniques sont de mises. Rassurez-vous, je n'ai pas l'intention de vous assommer de jargon, je vais me contenter d'expliquer sommairement certains concepts propre à Ruby et donner quelques informations sur le RGSS(3).
Un langage orienté objet
Derrière cette appellation compliqué: "Orienté Objet", se cache un concept relativement facile à décrire. En effet, l'orienté objet consiste à dire que tout est descriptible. Donc que tous les éléments que je vais être amener à utiliser sont basé sur un "modèle" et le jeu du programmeur est de construire ces modèles et de les remplir. Le moule, le modèle, que l'on utilise pour décrire des éléments est appelé une classe. Dans la programmation orienté objet (plus spécifiquement orienté classe, mais ne nous arrêtons pas sur ce détail), on est amené à utiliser des classes déjà existantes et à créer nos propre classe, pour décrire des éléments.
Dans le jeu de la création de classe, il sera possible de créer des liens entre des classes, on appelle ces liens l'héritage, donc on va écrire une classe qui part avec toutes les caractéristiques d'une autre. C'est assez cool parce que ça évite de devoir réécrire inutilement du code.
Je suis assez évasif sur ce concept, mais pas de panique. Si vous n'avez pas (tout) compris, je détaillerais ça quand nous serons amené à coder nos propre classes et vous verrez que dans la pratique, c'est relativement simple, j'ai juste pris la décision de survoler théoriquement "l'idée" de l'orienté objet pour le raffiner par après.
Le RGSS, c'est pleins de classes
Nous avions dit qu'en Ruby nous manipulerions des classes, et bien le RGSS étant représenté principalement en Ruby, il y a énormément de classes. Pour vous en rendre compte, je vous invite à lancer l'éditeur de script (au moyen de la touche F11), en survolant les différentes sections, vous pourrez voir qu'il y a plein de classes.
Pour faire un système en RGSS, il faudra donc créer des nouvelles classes et manipulez celles déjà existantes. Il existe toute une série d'autres classes qui ne sont pas accessible via l'éditeur de script, ces classes sont accessible (en lecture seule) via l'aide, que l'on peut trouver dans l'onglet "Aide" > "Fichier d'aide", ou simplement en appuyant sur F1. Le scripteur avisé est amené à souvent l'a consulter mais dans notre tutoriel, nous n'en aurons à priori pas besoin.
Si vous n'avez rien compris
Pas de panique ! Nous y serons confrontés via des cas pratiques et ce sera surement beaucoup plus clair pour tout le monde ! Donc ne baissez pas les bras et tâchez de tout de même vous lancer dans la suite, la confrontation à la pratique vous permettra peut être de mieux comprendre pleins de choses !
La notion de Scène
Dans RPG Maker, chaque écran est une scène. Si je lance un jeu RPG Maker, que je lance une nouvelle partie, que je circule sur la map, que je me rende dans le menu, que je retourne sur la map, que je fasse un combat, qui m'amène sur une autre map dans le cas où je gagne, que j'aille dans un magasin, que je retourne sur la map et que je meurs (et donc que j'enclenche un Game Over), j'aurais lancé plusieurs scènes. Voici un petit schéma de mon parcours :
Vous l'aurez compris, tous nos "écrans" seront des scènes. En RGSS, une scène est représentée par une classe. Chaque scène correspond à une classe. Si vous ouvrez l'éditeur de script, dans la partie de gauche, vous pourrez voir l'intégralité des scènes du RGSS :
Si vous êtes intelligent, vous aurez vite compris que pour créer notre mini-jeu, nous allons créer une scène spéciale qui sera notre "arène". Si vous ne l'avez pas compris, c'est que je ne suis pas assez explicite (et pas que vous n'êtes pas intelligent) et dans ce cas je vais ajouter que nous avons vu qu'une scène représente chaque écran de notre jeu, donc que nous allons créer un nouvel écran sur laquelle se trouvera notre Shifumi.
A la création de notre première scène
Dans un premier temps, je vous invite à vous rendre dans l'éditeur de script et à créer un emplacement en dessous de "Materials", généralement on place ses scripts en dessous de cet emplacement pour qu'ils soient en dessous des scripts qui composent le RGSS et au dessus de l'emplacement "main", qui correspond à la boucle du jeu (donc tous les scripts, après "main" ne seraient jamais exécutés) :
Nous avons maintenant un emplacement libre pour écrire nos scripts. Certains programmeurs fractionnent chacune de leur composantes dans des emplacements séparés, moi, quand il s'agit d'aussi petit script que celui que nous allons réaliser aujourd'hui ou que je crée un script destiné à être partagé, je me contente de tout mettre dans un seul emplacement.
Nous pouvons écrire le squelette de notre scène :
1
2
3
| class Scene_Shifumi < Scene_Base
# Ici se trouvera le code notre scène
end |
La première ligne indique que nous créons une classe du nom de Scene_Shifumi et le < Scene_Base indique que notre classé héritera de Scene_Base.
Qu'est-ce que l'héritage ?
Rappellez-vous, nous avions dit que le RGSS était une collection de classes déjà codée. L'héritage permet de dire qu'une classe aura le même comportement qu'une autre classe et il ne suffira plus que d'écraser les comportements que l'ont veut modifier.
Dans l'exemple présent, notre classe (Scene_Shifumi) aura exactement le même comportement qu'une Scene_Base, soit une scène ultra générique qui comprend toutes les routines de base d'une scène.
les lignes précédés de # sont des commentaires, ce qui veut dire qu'elles ne seront pas évaluées lors de l'exécution du jeu. Ce genre de ligne est très pratique pour structurer un script et aider le scripteur à s'y retrouver. On s'en sert aussi parfois pour afficher des indications sur le fonctionnement du script. Ces indications sont destinées à l'utilisateur.
Le end sert, quant à lui, à dire que la définition de la classe se termine. Donc tout notre travail de caractérisation de la table se trouvera entre class Scene_QuelqueChose et le end.
A noter que c'est le end qui caractérise la fin d'un bloc, donc que parfois, il y aura plusieurs end en fermeture. Mais nous verrons ça plus en détail par après.
Testons notre scène !
Nous allons voir un petit appel de script en Event, je vous invite à créer un événement sur la map de départ de votre projet sur lequel vous allez faire un appel de script avec ceci dedans :
1
| SceneManager.call(Scene_Title) |
En le testant, si vous déclenchez cet événement, vous serez renvoyé à l'écran Titre. Je vous invite maintenant à déduire l'appel de Script pour aller sur notre Scene_Shifumi...
Spoiler (cliquez pour afficher)
1
| SceneManager.call(Scene_Shifumi) |
Si vous ne l'avez pas trouvé, vous êtes un peu nul
En le testant, vous devriez voir une scène toute noire... c'est normal, nous n'avons pas encore fait quoi que ce soit sur cette scène. C'est d'ailleurs ce à quoi nous allons nous atteler dans la rubrique suivante !
La structure d'une scène
Avant de nous soucier de "ce que l'on va ajouter" à notre scène, il est important de comprendre la structure de celle-ci. Voici, de manière fort schématique, le déroulement d'une scène :
Cette représentation est un peu naïve et "limité" car il est possible de faire des "pre_terminate", mais pour l'instant, nous allons nous focaliser sur le strict minimum pour ne pas nous encombrer de concepts ennuyeux.
Donc concrètement, quand on appelle une scène, c'est la méthode start (une méthode c'est une action référente à une classe) qui est appelée, donc on va effectuer les premières tâches... afficher les images, les menus etc.
Une fois que cette action est terminée, on va boucler 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, un changement de scène, on va dans la méthode terminate qui elle va supprimer tout ce qu'il faut avant de changer de scène.
Ce qui est chouette avec ce que nous avons vu de l'héritage, c'est que nous ne sommes pas obligé de réécrire toutes les méthodes, car certaines méthodes de Scene_Base ont généralisé leur comportement. Par exemple, l'update rafraichit toute seule chacune des "Window" (nous y arrivons!) et terminate supprime toute seule les "Window". Il ne faut donc pas les réécrire (sauf si on doit modifier/supprimer d'autre chose).
Point sur les variables
La notion de variable est assez simple. Sans nous arrêter sur ce qu'est réellement une variable (sa représentation en mémoire etc.), nous allons voir qu'une variable, c'est simplement une étiquette sur une valeur, ça nous permet de stocker des valeurs :
1
2
| 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 toute sorte de chose dans une variable, par exemple une image, une Window.
Mais une variable possède une portée limité.
Nous avions parlé des méthodes de Scene. 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é à start.
Pour cela, il existe plusieurs "genres" de variables, celui qui nous intéresse est l'attribut. Nous avons vu qu'une classe permet de décrire des chose à l'infini. Pour ça on utilise des caractéristiques. Les attributs sont un genre de variable qui sert à caractériser une classe. Il suffit de rajouter un "@" devant son nom et on pourra accéder à cette variable partout dans la classe.
Concrètement, quand je n'aurai besoin que d'une valeur temporaire, j'utiliserai une variable normale, et quand j'aurai besoin de garder cette valeur tout au long de ma classe, j'utiliserai un attribut, donc une variable dont le nom commence par @.
La méthode start
Nous allons donc préparer notre scène à recevoir des éléments. Pour ça, voici comment j'ai écris ma Scene_Shifumi :
1
2
3
4
5
6
7
| class Scene_Shifumi < Scene_Base
# Lancement de la scène
def start
super
# Initialisation de la scène
end
end |
A quoi sert le super ?
Rappelez-vous que l'on a dit qu'on utilisait l'héritage pour que notre Scene_Shifumi prenne le comportement de Scene_Base.
Quand je fais une simple scène :
1
2
| class Scene_Truc < Scene_Base
end |
Par défaut, Scene_Truc possède toutes les méthodes de Scene_Base, grâce a l'héritage qui est représenté par < Scene_Base.
Si je crée une méthode start dans ma class Scene_Truc :
1
2
3
4
| class Scene_Truc < Scene_Base
def start
end
end |
La méthode de Scene_Base sera écrasée dans Scene_Truc. le mot clé (qui est une méthode aussi) super permet de dire à la méthode qu'elle appellera aussi la méthode de la classe parente (Scene_Base dans cet exemple).
Ce qui nous permet de garder le comportement générique défini dans Scene_Base tout en ajoutant des choses. Dans l'exemple donné, on voit que la méthode start de Scene_Base est définie comme ça :
1
2
3
| def start
create_main_viewport
end |
Donc concrètement, faire ça :
1
2
3
4
5
6
7
| class Scene_Shifumi < Scene_Base
# Lancement de la scène
def start
super
# Initialisation de la scène
end
end |
Est identique que de faire :
1
2
3
4
5
6
7
| class Scene_Shifumi < Scene_Base
# Lancement de la scène
def start
create_main_viewport
# Initialisation de la scène
end
end |
(la méthode create_main_viewport existe dans Scene_Shifumi de par l'héritage... une fois de plus).
Cependant, l'utilisation de super est plus astucieuse parce que bien que dans ce cas, le code de Scene_Base start est très court, il arrive que le code de la méthode parente soit beaucoup plus long (et pourtant requis pour le bon déroulement d'une scène, par exemple).
Notre premier élément
Dans cette section, voici ce que nous allons essayer d'obtenir (enfin, non, nous n'allons pas essayer... nous allons réussir) :
Nous pourrions directement créer cette composante dans la méthode start, cependant j'ai pris l'habitude de fractionner mon code en sous procédure. Nous allons donc, dans notre classe, créer une méthode qui se chargera de créer notre fenêtre de titre :
1
2
3
4
5
6
7
8
9
10
| class Scene_Shifumi < Scene_Base
# Lancement de la scène
def start
super
create_title
end
def create_title
# Ici on créera le titre
end
end |
A ce stade-ci, il va falloir utiliser une nouvelle composante du RGSS pour afficher une fenêtre en haut de scène. Cette composante est Window_Help.
Pour comprendre son fonctionnement, je vous invite à vous rendre dans l'éditeur de script. La méthode initialize est celle qui sera appelée la première fois, quand on construira l'objet. On appel ça un constructeur.
En effet, lorsque je fais "UneClasse.new", j'appelle la méthode initialize de la classe UneClasse et je construit une instance de cette classe. Dans notre exemple, nous aurons besoin d'une fenêtre d'une case de hauteur (en effet, nous n'avons besoin de n'écrire qu'une seule ligne), il nous suffit donc de faire :
1
2
3
4
5
6
7
8
9
10
| class Scene_Shifumi < 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 (rappelez-vous... le @) est obligatoire car notre méthode terminate devra supprimer la fenêtre quand on quitte la scène. Donc même si on a l'impression de n'utiliser notre fenêtre de titre qu'une seule fois, ce n'est pas vrai.
Si on test la scène, on verra que l'on est presque arrivé à ce que l'on voulait, malheureusement, il nous manque du texte. En effet, notre fenêtre est vide. Nous allons donc nous servir d'une méthode de Window_Help qui s'appelle set_text, si vous allez voir le code de Window_Help vous devriez la voir assez vite. Cette méthode nous permet d'écrire du texte dans notre fenêtre :
1
2
3
4
5
6
7
8
9
10
11
| class Scene_Shifumi < Scene_Base
# Lancement de la scène
def start
super
create_title
end
def create_title
@title = Window_Help.new(1)
@title.set_text("SHI FU MI !")
end
end |
Cette fois vous pouvez tester la scène et... magie ! Elle ressemble à ce que nous désirions avoir comme rendu !
Nous avons donc créé notre premier élément graphique et en plus, nous avons étés modernes car nous avons utilisé une méthode ! Sachez que dans les classes vous pouvez créer autant de méthode que vous voulez. Personnellement, je me sers des méthodes pour rendre mon code plus lisible et éviter les trop grosses portions de code !
Si vous avez tout assimilé, vous pouvez poursuivre avec la partie 2 !
Source :
- msp (S4suk3), "Création d'un Shifumi avec le RGSS3", BilouCorp, écrit le 20 avril 2013 [consulté le 15 juin 2021], https://www.biloucorp.com/creation-dun-shifumi-avec-le-rgss3-16
Ce tutoriel a été publié avec l'autorisation de son auteur.
|