Niveau : Intermédiaire.
Prérequis : Cours #1 et 2 réussis.
Outils : RPG Maker VX et le projet du cours. Suggérer, un de vos projets en cours sous VX. Nous allons regarder des scripts qui s'y trouve.
Sujets traités : Les classes et les méthodes (j'ai finalement retirer les modules car pour le moment, ce n'est pas important)
Cours :Théories Merci à LaMeche qui m'a donner un coup de main vu qu'il me manquait de temps pour mettre ce cours en ligne à temps.Le temps que vous attendiez tous sans le savoir. Les modules, les classes et les méthodes. Cela permet d'avoir un code plus propre et plus fonctionnel. Grâce aux classes, on peut se créer nos propres types de données complexe. Nous feront également un retour sur les variables locales, d'instances et globales. Dans les classes sont définit les méthodes qui permettrons d'interragir avec les autres type. Par exemple, to_s, operator+, operator=, to_i sont tous des méthodes des types que nous connaissons maintenant. Il est habituellement sage de mettre ces méthodes dans les nouvelles classes que l'on crée si on veut qu'elles puissent être affectées ou converties en d'autres type. L'operateur = est défini par défaut dans la superclass objects qui est toujours présentes par défaut. Cependant, on peut la surchargée afin qu'elle effectue des opérations différentes. Nous verrons la surcharge plus tard dans ce cours.
La création des classes correspond à la définition de la structure du type que l'on veut créer. Si vous ouvrez un projet de RPG Maker VX et que vous allez jetter un coup d'oeil aux scripts, vous verrez plusieurs classe. Entre autre, Game_Player, Game_Map, Game_Event, Window_Base, Scene_Title et j'en passe. Toutes ces classes correspondent à des types de données conçue pour le jeu.
Les méthodes sont des définitions de comportement de la classe. C'est là que le type prends tout son sens. Les modules, pour leur part, ne sont que des regroupements de classes. Le plus grand module de RMVX est sans conteste RPG. Ce module inclu toutes les classes importantes qui sont présente dans votre bases de données.
Pour crée une classe rien de plus simple il suffit de mettre
- Code:
-
class Ma_Classe
end
Avec toujours une majuscule comme première lettre. Les autres lettres n'on pas d'importance, mais on préfère ne pas mettre le nom complètement en majuscule pour ne pas confondre avec des constantes. Notez bien le mot clé class, qui dit au compilateur «Voici une définition de classe.» Oubliez ce mot et vous venez de ratter votre coup royalement. Notez aussi la présence du end. Comme dit précédemment, end est le mot clé qu'on retrouve le plus souvent puisqu'il termine toutes les structure, que ce soit les modules, les classes, les methodes ou les contrôles.
C'est tout pour les classes. C'est aussi simple que ça. Ah oui!?! Bah pas tout à fait. Mais juste avec cette ligne, on viens de définir un nouveau type de données appeler Ma_Classe. Nous allons apprendre à le remplir. Bon. Vous vous rappeler. Au cours 1 je vous disais que tout devait être entre le begin et le end. C'est vrai pour le code qu'on veut exécuter, mais pas pour les définitions. Les définitions doivent se trouver à l'extérieur, plus précisément AVANT le begin de l'exécution principale. C'est pour ça que, dans VX, on vous dit, placer votre script avant Main, qui lui détient le begin et le end qui lance l'exécution du jeu. Tous les scripts avant sont des définitions de classes. Donc, dans le projet du cours, on va se faire une classe puis un code pour regarder son évolution. Votre architecture devrait ressembler à ceci.
- Code:
-
class Ma_Classe
#...définition de la classe Ma_Classe
end
begin
#...code à exécuter
end
Je vous laisse 2 choix pour ce cours. Vous pouvez mettre la définition de votre classe dans un fichier séparé de votre exécution, tel que c'est dans VX, ou vous pouvez le laisser dans le même fichier. D'une façon où d'un autre, assurez vous que votre définition de classe se situe avant votre code d'exécution (que nous appèlerons Main à partir de maintenant). Il n'y a pas de bienfait ou de méfait à placer les définitions et le Main dans le même fichier. C'est uniquement pour s'aider à retrouver plus facilement notre code. En séparant les classes une classe par fichier, on s'assure de retrouver rapidement ce que l'on veut. Le nom que vous donnez au fichier n'est pas important, mais idéalement, question de vous retrouver plus facilement, donner le nom de votre classe au fichier et le nom Main au code d'exécution du Main
. D'une manière où de l'autre, ça va fonctionner. D'ailleurs, combiens de scripts maison ont plusieurs définitions de classe dans un seul fichier? Plusieurs car en fait, ils font la surcharges des certaines classe pour leur ajouter des fonctionnalités. Nous verrons celà à la fin de ce cours.
Bon j'entends déjà ceux qui ont ouvert un projet VX me demander ce que la notation class Scene_Title < Scene_Base signifie. Je vais vous en parler tout de suite, car ce n'est pas très compliquer, même si nous ne l'utiliserons pas pour le moment. Il s'agit d'une hiérarchisation de classe. Cela signifie que Scene_Title est une fille de Scene_Base. Comme chez les humains, les enfants ressemblent à leurs parents. C'est la même chose pour les classes. En disant que Scene_Title est la fille de Scene_Base (ou que Scene_Base est le parent de Scene_Title, à vous de choisir l'appellation que vous préférez), on indique que les définitions de Scene_Base sont également valables pour Scene_Title. Ainsi, en faisant une hiérarchie dans les classes, cela évite de devoir réécrire du code identiques pour toutes les classes qui partages des caractéristiques communes. Ainsi, toutes les classes Windows de VX ont une classe parent commune qui leur permet de faire l'affichage, sans que l'affichage soit une méthode de chacune des classes. La propagation est multi-générationnelle. C'est-à-dire que si on a la définition suivante :
- Code:
-
class Classe_Base
#...définition de la classe
end
class Classe_Mere < Classe_Base
#...définition de la classe
end
class Classe_Fille < Classe_Mere
#...définition de la classe
end
nous n'avons pas besoin de spécifié que Classe_Fille descend de Classe_Base puisque Classe_Mere possède déjà les caractéristique de Classe_Base. Ce principe est très pratique. Vous pourrez vous amuser à regarder la hiérarchie dans VX. Pour l'instant, c'est tout ce qui sera dit sur la hiérarchie.
Maintenant, nous allons donner un peu de vie à notre classe. Nous allons lui ajouter des méthode. Pour créer une méthode, c'est très simple. À l'intérieur de la classe, on ajoute def puis le nom de la méthode et on termine par un end. Nous allons créer une classe voiture et lui donner quelques propriétés. La première méthode qui doit être créer est initialize, qui dit à la classe comment gérer une nouvelle variable de ce type par la méthode de création "new".
- Code:
-
def initialize(marque, modele, annee=1960)
@marque = marque
@modele = modele
@annee = annee
@vitesse = 0
end
Notez qu'on ne met jamais d'accent dans les noms, ceci pour éviter les bug de compilation. Comme vous pouvez le voir, lorsqu'on crée une nouvelle voiture, on donne sa marque, son modèle, son année, puis l'init lui donne automatiquement une vitesse initiale à 0 km/h.
Définisson maintenant une méthode pour modifier la vitesse et une pour la lire.
- Code:
-
def set_vitesse(v = 0)
@vitesse = v
end
def get_vitesse
return @vitesse
end
Remarqué qu'on essaye d'éviter les accents, cela pour s'assurer que le compilateur (qui est en anglais) ne bug pas. Observons la syntaxe de plus près :
On définit une méthode grâce au mot-clé def et on termine par end. Si on a des paramètres (comme dans le cas de set_vitesse) on les ajoute entre parenthèse à la suite du nom de la méthode. On peut donner une valeur par défaut (ici 0), mais la valeur par défaut est optionnel. On aurait pu écrire uniquement
def set_vitesse(v). Quand on lit une valeur, on utilise le mot clé
return avec la valeur à retourner.
Pourquoi y a-t-il un @ devant vitesse. Ah ha! Familiprix! (Désolé, ça sortit tout seul. Les Québécois vont la comprendre.) Retour au cours #1. Les variables qui commencent par un @ sont des variables d'instance. C'est quoi une variable d'instance. Facile. Elle est créé avec l'objet et est détruite avec lui. Donc les variables avec un @ sont permanante et unique pour chaque voiture que vous créez. Donc si voiture1 à une vitesse de 20km/h, elle continuera d'aller à 20km/h même si voiture 2 (qui utilise les même variable par définition) va à 50km/h. Donc si on appelle voiture1.get_vitesse puis voiture2.get_vitesse, nous obtiendrons toujours respectivement 20 et 50 sauf si l'ont fait un set_vitesse à l'une ou l'autre des voitures pour modifier sa valeur. Si on ne met pas ce @, la variable est détruite dès qu'on sort de la classe, ce qui fait que la valeur est perdue à tout jamais. En comparaisons avec les événements de VX, le @ fait des variables locales qui reste vrai tant que l'événement n'est pas détruit. Dans le cas d'un script, ce n'est pas un event, c'est un objet. Vous voyez l'analogie? «OUI!!» D'accord.
Créons à présent la méthode qui va permettre aux voitures d'accélérer :
- Code:
-
def accelerer(a)
@vitesse += a
end
Comme nous l'avons vu au cours 2, += permet de modifier la valeur de vitesse en lui ajoutant la valeur de a. Si a est négatif, alors vitesse sera diminué. Dans VX, vous verrai souvent une définition avec l'opértion inverse, mais qui n'utilise pas le -=. 8Exemple :
- Code:
-
def decelerer(a)
accelerer(-a)
end
Pourquoi mettre accéléré avec une vitesse négative plutôt que de mettre le -=. Supposons que la forumle de accélérer change, nous n'aurons pas besoin de modifier décélérer pour tenir compte du nouveau calcul. Alors pourquoi créer décéléré. Dans le code, nous préférons voir des mots qui nous parlent plutôt que de devoir deviner. C'est tout. La fonction décélérer n'a pas besoin d'y être et ça fonctionne quand même.
Finalement, on peut décider de faire une fontion qui renvoit la voiture sous forme de string (le fameux to_s). Nous n'avons qu'à définir comment doit être renvoyer une voiture.
- Code:
-
def to_s
return @marque.to_s + " " + @modele.to_s + " " + @annee.to_s + " : " + @vitesse + " km/h"
end
Nous pourrions également utiliser une autre syntaxe qui revient au même
- Code:
-
def to_s
return "#{@marque} #{@modele} #{@annee} : #{@vitesse} km/h"
end
La notation #{...} dans un string ajoute directement la valeur de la variable dans la chaîne de caractère. Il existe donc 2 méthodes de créer un string avec des variables. Je n'imposerai aucune d'entre elle. Choisissez celle qui vous convient le mieux.
Donc, voici un exemple complet de la classe et du main qui nous permet de faire nos tests.
- Code:
-
class Voiture
def initialize(marque, modele, annee=1960)
@marque = marque
@modele = modele
@annee = annee
@vitesse = 0
end
def set_vitesse(v = 0)
@vitesse = v
end
def get_vitesse
return @vitesse
end
def accelerer(a)
@vitesse += a
end
def decelerer(a)
accelerer(-a)
end
def to_s
return "#{@marque} #{@modele} #{@annee} : #{@vitesse} km/h"
end
end
begin
voiture1 = Voiture.new("Ford","T",1960)
voiture2 = Voiture.new("Toyota","Prius",2010)
voiture1.set_vitesse(40)
voiture2.accelerer(110)
print voiture1.to_s + "\n" + voiture2.to_s
end
Exercice1. Expliquez-moi dans vos mots :
a) Qu'est-ce qu'une classe. À quoi sert-elle?
b) Qu'est-ce qu'une méthode. À quoi sert-elle?
c) À quoi sert la methode initialize?
d) Quand la méthode initialize est-elle appelée?
e) Même si dans certain cas, les accents ne change rien au code, pourquoi essaye-t-on de les éviter le plus possible dans le noms des varriables, des méthodes et des classes?
2. Reprenez le code créé avec le cours (vous pouvez prendre le vôtre ou celui que j'ai fourni à la fin du cours). Ajouté un tableau (array ou hash, selon votre guise), qui indiquera l'état des 4 pneus individuellement (donc un tableau à 4 éléments). Les états possibles des pneus seront "ok", "flat", "safe" (ou en français "ok", "crevé", "secours"). Ensuite, ajouté une ou des méthode(s) permettant de modifier l'état des pneus. Suggestion. Faites la méthode modifie_pneu avec 2 paramètre ou faites les méthodes crevaison, changement et réparation avec un paramètre. N'oubliez pas de modifier votre initialize.
3. Faites une nouvelle classe. Donnez-lui un nom représentatif de ce qu'elle fera. Implémenter les méthode nécessaires et une méthode qui permet de faire autre chose sur les objets de cette classe. Faites un Main qui montre son utilisation. Pas besoin d'être compliqué, je dois juste voir les éléments importants de votre classe.
Pondération des exercices1. 5pts (5x 1pt)
2. 10pts
3. 5pts