Auteur : Åvygeil
VI) Référence
Voilà un petit point qui risque de faire bugger un algorithme bien rôdé, si
l'on n'y prend pas garde...
Un objet est définit par son état, son comportement, mais aussi par son
identité, sa référence, en gros son adresse en mémoire ; et une variable
contient en faite non pas l'objet directement, mais la référence vers cet
objet.
Par exemple, quand on écrit
Voiture.new(0) crée un objet puis renvoie la référence de cette objet
qui est ensuite stockée dans la variable $voiture1.
Les problèmes surgissent si l'on fait par exemple
car cela va faire accélérer $voiture1 ET $voiture2, car $voiture2 contient une référence vers la même Voiture que $voiture1... ce qui n'est sûrement pas le but recherché...
Un autre exemple, qui va permettre de mieux visualiser le problème :
Vous avez peut-être remarqué que l'on ne peut avoir 2 fois le même personnage au sein d'une équipe... cela peut-être gênant si, pour l'accompagner, votre héros doit engager des soldats qui seront tous identiques...
- Initialisez l'équipe de départ avec le héros seul et testez en créant un évènement qui rajoute votre héros à l'équipe... non non, votre héros ne se démultiplie pas...
- Pour régler ceci, allez dans le script Game_Party à la ligne 106 ; la méthode add_actor(actor_id) permet de rajouter à l'équipe un Game_Actor selon actor_id (en gros un numéro parmi les Game_Actor en réserve...) ; à la ligne 110, on voit que le Game_Actor est effectivement ajouté si l'équipe ne contient pas déjà 4 Game_Actor, et si il n'y est pas déjà inclus : Mettez and not @actors.include?(actor) en commentaire.
- A présent, votre héros peut se multiplier, testez le...
- Maintenant, créez un évènement qui lance un combat, et battez vous avec votre équipe de héros.
- Laissez un personnage se faire toucher : tous les personnages perdent de la vie ! Que se passe-t-il ?
En gros, l'équipe est un tableau de Game_Actor ; seulement à la ligne 112 @actors.push(actor) ajoute au tableau une référence vers toujours le même Game_Actor...
Comment régler celà ? en n'ajoutant non pas une référence vers l'objet, mais une référence vers un clone de l'objet : il a les mêmes valeurs aux attributs au moment de sa création, mais ce n'est pas le même objet !
Créons une méthode que l'on nommera «clone» à l'intérieur de la classe Game_Actor :
Cette méthode crée un Game_Actor ayant le même id et donc les mêmes caractéristiques,
au moment de sa création, que l'objet courant, et renvoie une référence vers
ce nouveau Game_Actor.
Ensuite dans la méthode add_actor de Game_Party, au lieu d'ajouter un
Game_Actor à l'équipe par
ajoutez un clone à la place
A présent, tous les héros ont leurs vies propres.

