AccueilAccueil  PortailPortail  RechercherRechercher  Dernières imagesDernières images  S'enregistrerS'enregistrer  ConnexionConnexion  



Le Deal du moment :
LEGO Icons 10331 – Le martin-pêcheur
Voir le deal
35 €

Partagez
 

 Cours # 6 : Window_Selectable et scene complexe.

Voir le sujet précédent Voir le sujet suivant Aller en bas 
AuteurMessage
ASHKA
Voyageur Lv.10
Voyageur Lv.10
avatar


Masculin Age : 42
Inscrit le : 04/12/2008
Messages : 383

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeMar 10 Fév 2009 - 18:03

Niveau : Intermédiaire.
Prérequis : Les 4 cours sur le Ruby + le cours # 5 sur le RGSS2.
Outils : Créer un nouveau projet vierge RMVX comme si vous vouliez commencer un nouveau jeu.
Sujets traités : Window_Selectable et scene complexe.

Dans le cours # 5, nous avons appris à faire des scenes et des windows, ainsi qu'à utiliser Window_Command.
Dans ce cours, nous allons apprendre comment fonctionne une Window_Selectable, ce qui nous permettra de faire des scenes de plus en plus complexe.


Cours :

Etude de Window_Selectable :

Window_Selectable est une classe spécilament conçu pour permettre de créer des fenetres de choix.
Window_Command ( les listes ) est une sous-classe de Window_Selectable.
Les fenetres de choix d'objets, de competences ou les choix multiples de la commande d'event "Faire un choix" hérite egalement de Window_Selectable.

Code:
class Window_Selectable < Window_Base
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_reader  :item_max                # item count
  attr_reader  :column_max              # digit count
  attr_reader  :index                    # cursor position
  attr_reader  :help_window              # help window
  #--------------------------------------------------------------------------
  # * Object Initialization
  #    x      : window X coordinate
  #    y      : window Y coordinate
  #    width  : window width
  #    height  : window height
  #    spacing : width of empty space when items are arranged horizontally
  #--------------------------------------------------------------------------
  def initialize(x, y, width, height, spacing = 32)
    @item_max = 1
    @column_max = 1
    @index = -1
    @spacing = spacing
    super(x, y, width, height)
  end
# ...
end

En plus de ce qui est commun à toutes les Window, Window_Selectable possede 4 variables d'instances.

"item_max" designe le nombre limite d'objet que contiendra la fenetre, donc par consequence le nombre maximum de choix qu'elle offrira.
Lorsque vous utilisez une Window_Command, vous ne donnez pas de valeur à "item_max", elle prends automatiquement une valeur egale à la taille de votre tableau "commands".
Mais lorsque vous créez une Window_Selectable, il vous faudra lui donner la valeur qui vous convient.
( Sinon, vous ne verrez qu'un choix de disponible ... )

"column_max" designe le nombre de colonne de votre fenetre.
C'est quelque chose que nous avons déjà vu avec Window_Command.
Le nombre total d'objet sera reparti en fonction du nombre de colonne.
Il n'est necessaire d' indiquer une valeur que si le nombre de colonne est different de la valeur par defaut c'est-à-dire 1.

"index" designe la position du curseur.
0 designe le premier choix accessible.
Le reglage par defaut est -1, c'est-à-dire que le curseur sera invisible.
Cette "norme" est utilisé dans la plupart des scripts ( il faut que ce soit inferieur à 0, nous verrons pourquoi plus bas !! ).

"help_window" permet d'associer une deuxieme fenetre à votre Window.
C'est généralement utilisé pour associer une fenetre d'aide, pour guider la selection du joueur.
Tout est déjà pres reglé pour vous.
A chaque deplacement du curseur, si vous avez determiné une fenetre associé, la methode "update_help" sera appelé.
La seule chose que vous avez à faire, c'est donc de definir cette methode "update_help".
( Nous y reviendrons en detail )

Comme vous pouvez le constater, c'est 4 variables ont un attribut de lecture.
Mais "index" et "help_window" peuvent etre modifié par une methode.

Code:
  #--------------------------------------------------------------------------
  # * Set Cursor Position
  #    index : new cursor position
  #--------------------------------------------------------------------------
  def index=(index)
    @index = index
    update_cursor
    call_update_help
  end

  #--------------------------------------------------------------------------
  # * Set Help Window
  #    help_window : new help window
  #--------------------------------------------------------------------------
  def help_window=(help_window)
    @help_window = help_window
    call_update_help
  end

Ce qui signifie que vous pouvez modifier le curseur ou determiner la fenetre associé depuis une autre classe.
( Donc dans la pratique, depuis votre scene !! )
"item_max" et "column_max", quand à elles, doivent etre defini dans "Window_Selectable".

Window_Selectable est préconçu pour gerer les deplacements du curseur de selection mais n'offre aucune methode particuliere consernant l'affichage.
C'est pour cette raison que l'on n'utilise jamais une Window_Selectable mais toujours une Window spécifique héritant de Window_Selectable.

Lorsque tous les choix possibles apparaissent à l'ecran, c'est assez simple.
La complexité vient lorsqu'il y a plus de choix que de place.
En effet, il convient alors de calculer le defilement de la "fenetre".
( Guillemet car je ne parle pas de la fenetre d'un point de vue script mais d'un point de vue visuel )

Examinons la methode "update" de cette classe :

Code:
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    if cursor_movable?
      last_index = @index
      if Input.repeat?(Input::DOWN)
        cursor_down(Input.trigger?(Input::DOWN))
      end
      if Input.repeat?(Input::UP)
        cursor_up(Input.trigger?(Input::UP))
      end
      if Input.repeat?(Input::RIGHT)
        cursor_right(Input.trigger?(Input::RIGHT))
      end
      if Input.repeat?(Input::LEFT)
        cursor_left(Input.trigger?(Input::LEFT))
      end
      if Input.repeat?(Input::R)
        cursor_pagedown
      end
      if Input.repeat?(Input::L)
        cursor_pageup
      end
      if @index != last_index
        Sound.play_cursor
      end
    end
    update_cursor
    call_update_help
  end

Dans l'ensemble, c'est vraiment simple.
Si le curseur peut etre bouger, on regarde quelles sont les touches actives.
Pour chaque cas, on regarde où doit aller le curseur.
S'il a effectivement bouger, petit sound_effect.
On met à jour le curseur, on met à jour l'aide.

Ca n'est pas dans l'update que reside la complexité de cette classe mais dans les methodes qu'elle utilise.


Citation :
Avant d'aller plus loin, petite piqûre de rappel !!
Le modulo ( symbole % ) est tres utilisé dans Window_Selectable.
Cet operateur retourne le reste d'un quotient.

Souvenez vous de vos jeunes années.
6 / 4 = 1 et il reste 2
donc 6 % 4 = 2

Bon, généralement, la question qui vient juste apres est : A quoi ça sert ?

Par exemple, à determiner si un Integer est paire ou non.
6 % 2 = 0 => Paire
5 % 2 = 1 => Impaire

Dans notre cas, ça nous servira à convertir un index en rang et colonne :
Notre index = 17 et nous avons 5 colonne :
Où se trouve notre curseur ?
C'est simple :
rang = index / column_max => 3
column = index % column_max => 2
Notre curseur est au rang 3 et à la colonne 2.

Examinons d'abord les methodes "cursor_down", "cursor_up", "cursor_right" et "cursor_left" :

Code:
  #--------------------------------------------------------------------------
  # * Move cursor down
  #    wrap : Wraparound allowed
  #--------------------------------------------------------------------------
  def cursor_down(wrap = false)
    if (@index < @item_max - @column_max) or (wrap and @column_max == 1)
      @index = (@index + @column_max) % @item_max
    end
  end
  #--------------------------------------------------------------------------
  # * Move cursor up
  #    wrap : Wraparound allowed
  #--------------------------------------------------------------------------
  def cursor_up(wrap = false)
    if (@index >= @column_max) or (wrap and @column_max == 1)
      @index = (@index - @column_max + @item_max) % @item_max
    end
  end
  #--------------------------------------------------------------------------
  # * Move cursor right
  #    wrap : Wraparound allowed
  #--------------------------------------------------------------------------
  def cursor_right(wrap = false)
    if (@column_max >= 2) and (@index < @item_max - 1 or (wrap and page_row_max == 1))
      @index = (@index + 1) % @item_max
    end
  end
  #--------------------------------------------------------------------------
  # * Move cursor left
  #    wrap : Wraparound allowed
  #--------------------------------------------------------------------------
  def cursor_left(wrap = false)
    if (@column_max >= 2) and (@index > 0 or (wrap and page_row_max == 1))
      @index = (@index - 1 + @item_max) % @item_max
    end
  end

Seul les fenetres d'une colonne autorise le passage du dernier rang au permier rang par le bas et reciproque, c'est ce que verifie la condition des methodes "cursor_up" et "cursor_down".
Et on peut pas passer du dernier rang au premier par la droite et recirpoque, c'est ce que verifie la condition des methodes "cursor_right" et "cursor_left".
Si le deplacement est possible, on ajuste le nouvel index.
Le role du modulo est d'ajuster l'index en fonction du nombre maximum d'objet.

Code:
  #--------------------------------------------------------------------------
  # * Move cursor one page down
  #--------------------------------------------------------------------------
  def cursor_pagedown
    if top_row + page_row_max < row_max
      @index = [@index + page_item_max, @item_max - 1].min
      self.top_row += page_row_max
    end
  end
  #--------------------------------------------------------------------------
  # * Move cursor one page up
  #--------------------------------------------------------------------------
  def cursor_pageup
    if top_row > 0
      @index = [@index - page_item_max, 0].max
      self.top_row -= page_row_max
    end
  end

Les methodes "cursor_pagedown" et "cursor_pageup" permettent de passer d'une page à l'autre lorsqu'il y a beaucoup d'objets.

La methode "page_row_max" permet de savoir combien de rang il y a sur une page :

Code:
  def page_row_max
    return (self.height - 32) / WLH
  end

Donc, la taille du bitmap ( la fenetre moins le cadre ) divisé par la hauteur d'un rang.
( La constante WLH defini dans Window_Base est egale à 24 ).

La methode "page_item_max" permet de savoir combien d'objets une page peut contenir au maximum.

Code:
  def page_item_max
    return page_row_max * @column_max
  end

Donc, le nombre de rang d'une page multiplié par le nombre de colonne.

En fonction de cela, l'index est modifié, et la position des rangs est recalculé.

Tout cela ne sert qu'a determiner le nouvel index en fonction des Input.
La position de curseur est calculé par une autre methode : "update_cursor".

Code:
  #--------------------------------------------------------------------------
  # * Update cursor
  #--------------------------------------------------------------------------
  def update_cursor
    if @index < 0                  # If the cursor position is less than 0
      self.cursor_rect.empty        # Empty cursor
    else                            # If the cursor position is 0 or more
      row = @index / @column_max    # Get current row
      if row < top_row              # If before the currently displayed
        self.top_row = row          # Scroll up
      end
      if row > bottom_row          # If after the currently displayed
        self.bottom_row = row      # Scroll down
      end
      rect = item_rect(@index)      # Get rectangle of selected item
      rect.y -= self.oy            # Match rectangle to scroll position
      self.cursor_rect = rect      # Refresh cursor rectangle
    end
  end

Si l'index est inferieur à 0 ( souvenez vous, l'index par defaut est -1 ), le curseur est vidé ( invisible donc ).
Sinon, on ajuste les rangs du haut et du bas, on recupere un rectangle qui sera positionné sur l'objet actuel.
Ce rectangle servira à créer le curseur.
C'est la methode "item_rect" qui va determiner la position du curseur en fonction de l'index.

Code:
  #--------------------------------------------------------------------------
  # * Get rectangle for displaying items
  #    index : item number
  #--------------------------------------------------------------------------
  def item_rect(index)
    rect = Rect.new(0, 0, 0, 0)
    rect.width = (contents.width + @spacing) / @column_max - @spacing
    rect.height = WLH
    rect.x = index % @column_max * (rect.width + @spacing)
    rect.y = index / @column_max * WLH
    return rect
  end

La largeur du rectangle est calculé en fonction de la largeur de la fenetre et du nombre de colonne.
Sa hauteur, c'est notre constante WLH qui la fixe ( je rappelle : 24 pixels ).
La position x, c'est simplement la colonne de l'objet multiplié par la largeur du rectangle.
La position y, c'est le rang multiplié par la hauteur d'un rang.

Maintenant que vous connaissez en detail le fonctionnement de Window_Selectable, il nous reste à jouer avec !!


Dernière édition par ASHKA le Mar 10 Fév 2009 - 18:06, édité 1 fois
Revenir en haut Aller en bas
ASHKA
Voyageur Lv.10
Voyageur Lv.10
avatar


Masculin Age : 42
Inscrit le : 04/12/2008
Messages : 383

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeMar 10 Fév 2009 - 18:04

Utilisation de Window_Selectable :

On va commencer par créer la scene :

Code:
class Scene_Test < Scene_Base
  def start
    create_menu_background
    @win = Window_Test.new
    @help = Window_Help.new
    @win.help_window = @help
  end
  def terminate
    dispose_menu_background
    @win.dispose
    @help.dispose
  end
  def update
    update_menu_background
    @win.update
    if Input.trigger?(Input::B)
      Sound.play_cancel
      $scene = Scene_Map.new
    end
  end
end

Les methodes "create_menu_background", "dispose_menu_background", "update_menu_background" servent à créer un Sprite qui aura l'apparence de la map actuel.
Ces methodes sont notamment utilisés dans le menu.
Si vous voulez connaitre leurs definitions, jetez un oeil à Scene_Base.

Evidement, Window_Test sera notre window héritant de Window_Selectable.
On voit comment associer deux fenetres par l'intermediaire de la variable "help_window" des Window_Selectable.
Il est important d'utiliser l'update de notre fenetre, comme pour les Window_Command.
Rappellez vous, c'est elle qui va gerer l'input et le curseur.

Il est temps de s'interesser à notre fenetre :

Code:
class Window_Test < Window_Selectable
  def initialize
    w = 232
    h = (4*24)+32
    x = 272 - (w/2)
    y = 208 - (h/2)
    super(x, y, w, h)
    @column_max = 5
    @spacing = 0
    self.index = 0
    refresh
  end
  def refresh
    @data = []
    for x in 0...20
      @data.push(x.to_s)
    end
    @item_max = @data.size
    create_contents
    for i in 0...@item_max
      draw_item(i)
    end
  end
  def draw_item(index)
    rect = item_rect(index)
    self.contents.clear_rect(rect)
    item = @data[index]
    if item != nil
      rect.width -= 4
      self.contents.draw_text(rect, item, 1)
    end
  end
  def update_help
    @help_window.set_text("Vous etes sur le numero #{index}", 1)
  end
end

Dans l'initialize, j'indique le nombre de colonne ( ici 5 ) et j'ai choisi de ne mettre aucun espace.
La variable @spacing permet de mettre des espaces entre chaque objets.
Sa valeur par defaut est de 32 pixels ce qui est assez elevé ( une ligne fait 24 pixels par exemple ).
Pour le reste, c'est un copié/collé de Window_Item ( la fenetre de choix d'objet - menu ou combat ) légérement modifié pour coller à nos besoins.
Quasiment toutes les fenetres basé sur Window_Selectable que vous verrez ( script de base ou ceux du Net ) suivent ce même schema.
Evidement, rien ne vous oblige à faire la même chose, vous pouvez trouver votre propre façon de faire.
Mais comme c'est ce qu'il y a de plus repandu, il faut bien vous expliquer comment ça fonctionne.

Dans la methode "refresh", on commence par remplir un tableau.
Ici, il contient des String, dans Window_Item, il contient des objet RPG::Item, ça, c'est à vous de choisir !!
La taille de notre tableau nous donne notre "item_max".
Ce tableau contiendra donc tous nos choix.

Ensuite, on reconnait la methode "create_contents", souvenez vous, celle que nous avons du rajouter dans Window_Command.
Puis, pour chaque element de notre tableau, grace à son index, on appelle la methode "draw_item" qui gere l'affichage.

En parametre, on trouve l'index du choix à afficher.
Grace à cette index, on peut recuperer un Rect en utilisant la methode "item_rect" de Window_Selectable.
Comme cette methode sert également à connaitre la taille et l'emplacement du curseur, nous avons toujours un affichage adapté au curseur.
( Enfin, tant qu'on utilise le Rect obtenu evidement !! )
Ca nous evitera bien des calculs ...
Ensuite, on efface le Bitmap correspond au Rect, histoire de faire place net.
( Dans le script final du cours precedent, toutes nos actions se superposées les unes aux autres, mais ici, ça ne nous convient pas !! )
Grace à notre tableau et notre index, on recupere l'objet qui nous interesse.
Comment ici il s'agit d'une String, je peux directement l'afficher.
J'utilise le Rect pour etre bien positionné ( et centré pour faire plus joli ).

Enfin, comme j'ai associé une fenetre d'aide via ma scene, il faut que je renseigne l'affichage de celle ci.
Rappel : la methode "update_help" est appellé par la methode "update" de Window_Selectable.
Window_Help possede une methode "set_text" bien pratique qui permet d'afficher du texte de maniere simplifié et depuis une autre classe.
On passe en parametre une String et l'alignement.

Il ne nous reste plus qu'a tester tout ça !!

Spoiler:

C'est magique, le curseur bouge parfaitement, la fenetre d'aide réagi aussitôt, vive Window_Selectable !!
Gerer une fenetre, c'est bien pour commencer mais ça n'offre pas grand interet ...
Voyons maintenant un exemple de scene plus complexe, avec plusieurs fenetres de choix !!
Revenir en haut Aller en bas
ASHKA
Voyageur Lv.10
Voyageur Lv.10
avatar


Masculin Age : 42
Inscrit le : 04/12/2008
Messages : 383

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeMar 10 Fév 2009 - 18:08

Exemple de scene complexe :

On va créer une scene qui pourrait bien etre un sous-menu "Option".
Nous avons besoin de trois fenetres :
- Le liste des choix d'options a gauche ( Window_Command ).
- En vis-à-vis à droite, les diferents reglages de chaques options ( Window_Selectable ).
- En bas, une fenetre d'aide qui nous expliquera à quoi correspond les options et les choix.
Pour nous simplifier la vie, nous allons utiliser un module pour regrouper les options, les reglages et les commentaires qui leurs seront associés.

Par contre, nous ne créeront qu'une structure vide.
Les choix ne donneront lieu qu'a un Sound_Effect.
Le but est ici de vous apprendre à utiliser les Window_Selectable.

Voila à quoi ça devrait ressembler à la fin :

Spoiler:

Evidement, avant d'en arriver là, on avons beaucoup de travail en perspective !!
( Enfin, pour vous, parce que moi, le script est déjà fait ... )

Premiere etape : Par quoi est-ce qu'on commence ?

Et bien, tout d'abord, on commence par reflechir !!
Un script, même un simple, ça se pense bien avant de se coder !!
Ca vous evitera bien de problemes de penser avant d'agir.
Evidement, une scene comme celle là, c'est facilement modifiable.
Mais c'est une habitude à prendre.
Parce que, si au bout de 2000 lignes de code, vous vous rendez compte que vous n'arriverais à rien de cette façon, votre super CBS n'est pas pres de voir le jour ...

Vous avez de la chance, j'ai pensé pour vous ( donc, ce sera bien fait ... ).
Il n'y a qu'une difficulté ici, c'est notre Window_Selectable ...
Je me suis un peu laché, j'avoue.

Bon, allons y !!

Tout d'abord, commencons par la scene :

Spoiler:

On utilise la methode "start" pour créer toutes nos fenetres, soit ici :
- Window_Description, une fenetre toute simple qui herite de Window_Base ( celle du bas ).
- Ma_Win_Cmd, une fenetre de choix qui hérite de Window_Command ( celle de gauche ).
- Window_Reglage, une fenetre de choix egalement mais qui hérite de Window_Selectable ( celle de droite ).

Par defaut, les fenetres sont activent, c'est à dire que le curseur est actif.
Pour eviter le probleme de gerer deux fenetres en même temps, on désactive @reglage, on l'a réactivera lorsqu"on aura choisi une option.
Ensuite, on associe une fenetre d'aide ( ici de descritpion plutôt ) à nos fenetres de choix.
Dans la methode de Window_Selectable qui appelle la mise à jour de la fenetre d'aide, il y a une condition "if self.active".
Il n'y aura donc pas de probleme à réutiliser la même fenetre d'aide, nos deux fenetres de choix etant active à tour de role !!

Dans la methode "terminate", on n'oublie surtout pas de detruite nos fenetres !!

Comme on va gerer à tour de role deux fenetres differentes, il faut adapter l'update.
On utilise le fait que la fenetre soit active comme condition de declenchement.
Si @reglage est active, "update" appellera une methode spécifique qui gerera les actions propres à la fenetre active.
Et même chose avec @option, elle aura elle aussi sa propre methode pour gerer les actions.
Rappellez vous bien de ça, c'est fondzmentale pour pouvoir créer des scenes complexes.
Chaque methode à sa fonction, il faut mieux eviter de créer des methodes à rallongue, avec une condition en "fermant" une grande partie.

Chaque methode commence par appeller la methode "update" de la fenetre active.
Rappellez vous que c'est cette methode qui gere les deplacements du curseur, il serait dommage de l'oublier ...
En cas de choix d'une option, on passe d'une fenetre à l'autre en modifiant l'attribut "active" des fenetres.
Dans "update_reglage", en cas de retour, on fixe l'index de la fenetre à -1 pour le rendre invisible.
La methode "set_action" sert à passer à la fenetre @reglage le choix effectué, ce qui influera sur la position du curseur.

Habituellement, les Window_Command n'ont pas de fenetre d'aide.
J'ai donc du en rajouter une, ce qui explique l'utilisation d'une classe spécifique héritant de Window_Command.
Cette classe est vraiment reduite au maximum, la voici :

Code:
class Ma_Win_Cmd < Window_Command
  def update_help(force = false)
    if force or @test_index != self.index
      tab = Test::Desc_Option[self.index]
      @help_window.refresh(tab)
      @test_index = self.index
    end
  end
end

Window_Command hérite de Window_Selectable, toute la structure permettant d'utiliser une fenetre d'aide est déjà là, mais elle n'etait pas utilisé !!
J'ai juste eu à definir ma methode "update_help", l'heritage faisant le reste.
( Encore une fois, je me repete, mais laissons les parents tout faire à notre place !! )
Alors, si jamais le curseur change de position, on mets à jour la fenetre d'aide.
Inutile d'utiliser le "refresh" en permanence, rapellez vous, economisons nos forces !!
J'ai aussi integré une systeme permettant de forcer la mise à jour, voila pourquoi :
Lorsque la deuxieme fenetre devient active, le curseur de la premiere reste en place mais l'affichage de la fenetre d'aide change.
En cas de retour, la fenetre de choix d'option redevient active, il faut donc que l'affichage de la fenetre d'aide revienne adapté.
Mais le probleme est que le curseur n'a pas bougé ... donc ma condition empechera la mise à jour ...
Plutôt que d'appeller la methode "refresh" en permanence, cette astuce de forcer la mise à jour est plus adapté !!
Par defaut ( enfin, sans parametre ), le passage en force est desactivé.
Oui, sans modification, Window_Selectable appelle la methode "update_help", sans parametre !!
Revenir en haut Aller en bas
ASHKA
Voyageur Lv.10
Voyageur Lv.10
avatar


Masculin Age : 42
Inscrit le : 04/12/2008
Messages : 383

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeMar 10 Fév 2009 - 18:14

Depuis le temps qu'on parle d'elle, il faut que je vous la presente ...
Voici notre fenetre de description :

Code:
class Window_Description < Window_Base
  def initialize
    h = (4 * 24) + 32 + 15
    super(0, 416-h, 544, h)
    refresh([])
  end
  def refresh(tab)
    if tab != []
      self.contents.clear
      y = 0
      for line in tab
        self.contents.draw_text(0, y, 544-32, 24, line, 1)
        y += 24
      end
    end
  end
end

Une Window tout ce qu'il y a de plus classique ... sans fioriture.
J'aurais pu mettre de la couleur, un trait pour separer le titre et la description, mais non ... la flemme !!
( Non, en fait, si vous voulez, faite le, moi, je sais déjà comment faire ... )
Comme cette fenetre doit servir dans deux cas differents ( Option et Reglage ), il a fallu trouver un moyen de rendre ça simple.
Evidement, j'aurais pu passer un parametre indiquant quelle fenetre est active, quelle est la postion du curseur et en fonction de ça, avec une suite de condition longue comme une journée sans pain, afficher ce qui correspond.
Mais, je suis un gros paresseux ...
J'ai donc essayé d'automatiser au maximum.
En fonction de l'index, la methode "update_help" envoi en parametre un tableau.
Une petite boucle ( for ) fait le reste.
Tout est donc stocké dans un module.
Plutôt que de mettre toutes mes String directement dans le script, j'utilise un module, c'est nettement plus simple.
Voici ce module ( trop long pour entrer dans un message ) :

Fichier txt ...

On y trouve la liste des options, la liste des reglages, et les descriptions correspondant à tous les choix possible.
Vive les Hash !!
Bon, chaqu'un son truc, moi, j'aime bien les Hash, les Hash, c'est cool.
( Le permier qui tente un jeu d emot avec mon pseudo, je le ........ )
Pour "Desc_Reglage", il faut donc deux clés pour acceder au tableau.
Ces clés seront donc le choix de la fenetre d'option et la position du curseur dans la fenetre de reglage.

La fenetre de reglage ?
Tiens, c'est parfait ça comme enchainement, ok, allons y voici la fenetre de reglage :

Spoiler:

On va diviser l'etude en deux axes :
- L'affichage.
- La gestion du curseur.

Tout d'abord, regardons comment s'effectue l'affichage.
L'initialize n'offre pas grand interet, passons de suite à la methode "refresh".
Notre tableau @data est rempli à partir de notre liste, celle qui se trouve dans le module.
Ici, le tableau ne contient ni des String, ni des objets RPG::Item mais des Array.
Chaque Array correspond à une option.
L'affichage est donc particulier, je ne peux pas afficher le tableau tel quel, ça ne donnerais rien de bien ...
D'ailleurs, on remarquera que je n'ai pas encore donner de valeur à @column_max ( donc c'est 1, la valeur par defaut ) ou à @item_max ( même chose, 1 ).
Pourtant, je passe directement à la methode "draw_item", celle qui habituellement gere l'affichage des objets "choix".

Methode "draw_item" :
Grace à l'index, je recupere mon tableau contenant les choix.
Il ne me reste plus qu'a les afficher.
Comme le nombre de choix est different selon les options, ce n'est que maintenant que je fixe le nombre de colonne et d'objet max.
J'ajuste egalement l'espace ( ici, un case pour reduire l'espace lorsqu'il y a beaucoup de choix à afficher ).
J'ai fixé le nombre de colonne, la methode "item_rect" va donc calculer ele même la position de chaque option.
Ici, je rajoute un parametre, "index", c'est à dire l'option choisi.
Si on regarde la redefinition de "item_rect", on constate que ça me sera utile pour afficher chaque option sur une ligne differente.
C'est aussi simple que ça, tout est automatique, il suffit de s'adapter !!

Passons donc à la gestion du curseur.
Toutes les modifications passent par la methode "set_action", appellé au moment de choisir une option.
En fonction de ce choix, j'ajuste les valeurs de @column_max, @item_max et @spacing.
Comment nous l'avons vu pour l'affichage, ça suffira à créer le curseur adapté.
Le curseur est crée par la methode "item_rect" qui est appellé par la methode "update_cursor" de Window_Selectable.
Je n'allais pas redefinir cette methode juste pour rajouter un parametre à "item_rect".
( Souvenez vous, comme pour l'affichage, l'index indiquant sur quelle ligne se placer ).
Cette fois aussi, j'utilise le principe des valeurs par defaut s'il n'y a pas de parametres.
Cette valeur sera celle de la variable @action.
Tout comme il l'a fait pour l'affichage, "item_rect" nous fournira un Rect adapté pour le curseur.

La derniere chose à faire, c'est mettre en place la mise à jour de la fenetre de description.
C'est quasiment la même methode que pour Ma_Win_Cmd, avec le systeme pour forcer la mise à jour.
Grace aux variables @action et @index, j'ai les deux clés qui me permettent de recuperer le tableau à passer en parametre.

Voila, vous savez tout ce qu'il y a à savoir sur les Window_Selectable.
Vous allez pouvoir créer tous les menus que vous voulez maintenant !!
Comme je vous l'ai dis au debut du cours precedent, les menus sont une part importante dans les RPG.
Et au niveau script, c'est ce qu'il y a de plus simple à créer.
Ce qui nous donne de long et complexe cours en perspective !!

Etudiez le cours avec attention, Hikari postera les exercices à faire !!

ASHKA


Dernière édition par ASHKA le Mar 27 Oct 2009 - 8:19, édité 1 fois
Revenir en haut Aller en bas
MirainoHikari
Ex-Admin-Script
Ex-Admin-Script
MirainoHikari


Masculin Age : 42
Inscrit le : 26/05/2008
Messages : 2360

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeMer 11 Fév 2009 - 13:45

Wow... ASHKA, tu t'es "lâché lousse"... Bon bon bon... Maintenant, faire un exercices pour pratiquer tous ces beaux apprentis... Intelligent

1) Comment est calculer la taille de l'index (4pts)
a) dans une Windows_Command?
b) dans une Windows_Selectable?

2) Quelle variable permet de savoir où est rendu le curseur dans une Windows_Selectable? (2pts)

3) Lorsque nous avons une interface multi-fenêtre, comment est-il préférable de faire la gestion d'affichage de chacune d'elles? (4pts)

4) Au cours 5 et au cours 6, ASHKA a parlé d'une variable qui rendait active et une qui rendait visible les fenêtres. Faites une fenêtre de sélection qui permettra d'afficher ou de masquer la fenêtre d'aide. (4pts)

5) Voyons voir si vous avez bien intégré les concepts. SANS UTILISER DE WINDOWS_COMMAND, vous allez faire une interface permettant de faire une sélection combiné. Vous ferez une première fenêtre de sélection qui vous permettra de choisir parmis les 26 lettres de l'alphabet (A-Z) puis, lorsque la lettre est choisi, ferai la sélection des chiffre (0-9). Chaque fois que vous sélectionnez une lettre, le curseur de la fenêtre des chiffres retourne à 0. Lorsque vous sélectionnez vous lettre et vos chiffre, votre fenêtre d'aide affichera la combinaison. Exemple, « S7 » ou «S - 7». (6pts)

Bonne chance à tous.


Dernière édition par MirainoHikari le Jeu 5 Mar 2009 - 15:04, édité 1 fois
Revenir en haut Aller en bas
http://mirainohikari.deviantart.com
yamazaki
Illusionniste Lv.12
Illusionniste Lv.12
avatar


Masculin Age : 34
Inscrit le : 27/12/2008
Messages : 757

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeJeu 5 Mar 2009 - 14:35

salut
pouvez vous me dire comment on fait
pour changer l'image du rectangle de sélection et le remplacer par un curseur?
Revenir en haut Aller en bas
http://mods-jeu-rpg.forumactif.org
Invité
Invité
avatar



Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeJeu 5 Mar 2009 - 14:38

ASHKA m'avait donné ce code une fois
Code:

class Window_MenuStatus< Window_Selectable
  def initialize(x,y)
    super(x,y,544,275)
    @column_max = 2
    @spacing = 20
    self.active = false
    self.index = -1
    @curseur = Sprite.new
    @curseur.bitmap = Cache.picture("cursor")
    @curseur.z = 100
    @curseur.visible = self.index != -1
    refresh
  end
  def dispose
    @curseur.bitmap.dispose
    @curseur.dispose
    super
  end
  def update_cursor
    return if @curseur == nil
    @curseur.visible = index != -1
    rect = item_rect(index)
    @curseur.x = rect.x + (rect.width / 2) - (@curseur.bitmap.width / 2)
    @curseur.y = rect.y + (@curseur.bitmap.height / 2) + 91
  end
end

Si ça peut aider.
Revenir en haut Aller en bas
MirainoHikari
Ex-Admin-Script
Ex-Admin-Script
MirainoHikari


Masculin Age : 42
Inscrit le : 26/05/2008
Messages : 2360

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeJeu 5 Mar 2009 - 15:05

Je viens de publier les exercices. Ils sont plus difficile cette fois, mais vous avez passer au travers des 5 premiers cours et de l'examen, c'est normal que le niveau augmente un peu.
Revenir en haut Aller en bas
http://mirainohikari.deviantart.com
Invité
Invité
avatar



Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeJeu 5 Mar 2009 - 15:21

Petite question prof, est ce que l'examen doit être fait avant ces exercices ou est ce qu'on peut déjà travailler sur ces exercices?
Revenir en haut Aller en bas
MirainoHikari
Ex-Admin-Script
Ex-Admin-Script
MirainoHikari


Masculin Age : 42
Inscrit le : 26/05/2008
Messages : 2360

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeJeu 5 Mar 2009 - 15:25

Non, les exercices de ce cours peuvent être fait avant l'examen, mais il est obligatoire cependant d'avoir remis les exercices du cours 5 avant de soumettre ses réponse pour l'examen ou le cours 6. D'ailleur, travailler le cours 6 est une révission intéressante pour l'examen, donc je vous le suggère. Cependant, n'oubliez pas de répondre à l'examen un jour. Le site web ne restera pas ouvert indéfiniment. Un jour, je lui trouverai un serveur permanent.
Revenir en haut Aller en bas
http://mirainohikari.deviantart.com
La Meche
Flibustier Lv.21
Flibustier Lv.21
La Meche


Masculin Age : 30
Inscrit le : 24/05/2008
Messages : 3234

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeDim 15 Mar 2009 - 13:44

J'ai une petite question pour ce qui est de la syntaxe :
Est ce que l'on peut mettre des accents ou des "ç" pour les nom de variables, module, class etc... sans qu'il n'y est d'erreur ?
(je viens de tester, pour l'instant sa marche mais je ne sais si sur longue durée c'est bien)
Revenir en haut Aller en bas
berka
Maire Lv.9
Maire Lv.9
berka


Masculin Age : 34
Inscrit le : 15/10/2008
Messages : 351

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeDim 15 Mar 2009 - 14:23

il faut bannir tous les caractères spéciaux des noms de méthodes:
il y a en ruby des conventions de nommages très strictes. Ton interpréteur s'en fout la plupart du temps, mais c'est pour la forme:
Code:

MA_CONSTANTE || MaConstante
$ma_variable
def meth_booleen?  #renvoie true ou false
def destruct!  #change self: methode destructrice
class Chose_Test || class ChoseTest
normalement, après chaque opérateur, on devrait mettre un espace: a = b + (4 ** 2)
mais je trouve que ca prend beaucoup trop de place

Ca sert a se repérer ! Et à éviter les pertes de caractères sur des sites etrangers (utf8/unicode...)

berka
Revenir en haut Aller en bas
http://rpgruby.olympe-network.com
La Meche
Flibustier Lv.21
Flibustier Lv.21
La Meche


Masculin Age : 30
Inscrit le : 24/05/2008
Messages : 3234

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeDim 15 Mar 2009 - 15:16

Donc on peut le faire ?
Ou faut suivre le "lois" qui dit de pas en mettre ?

Aussi comment sais-t-on quel caractétre n'est pas lu par tel site étranger (genre utf8/unicode...)
Revenir en haut Aller en bas
berka
Maire Lv.9
Maire Lv.9
berka


Masculin Age : 34
Inscrit le : 15/10/2008
Messages : 351

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeDim 15 Mar 2009 - 17:58

ce sont des lois: elles sont rendues obligatoires pour simplifier la vie des codeurs, mais elles ne font pas planter ruby...(enfin si tu mets ["#&~... dans ton nom...)

le mieux c'est de les suivre...
Et je ne vois pas tellement ce qui t'empeche de ne pas les suivre ^^


berka
Revenir en haut Aller en bas
http://rpgruby.olympe-network.com
MirainoHikari
Ex-Admin-Script
Ex-Admin-Script
MirainoHikari


Masculin Age : 42
Inscrit le : 26/05/2008
Messages : 2360

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeLun 16 Mar 2009 - 12:00

D'ailleur, j'en ai fait mention dans un cours précédent La Meche... Même si VX ne semble pas trop s'en faire avec les accents/caractère spéciaux, il est préférable de rester en "english style". Donc au lieu d'écrire Français_Éloquent, prends l'habitude d'écrire Francais_Eloquent. C'est peut-être pas dans un beau français sans coquille, mais tu risques moins d'avoir des problème de compatibilité le jour ou tu changeras d'interpréteur. VX supporte bien les UNICODE, mais si tu y réfléchies un peu, ça été développé par des japonais pour supporter leur caractères (tous unicode), donc on comprend pourquoi ça ne le dérange pas trop. Mais prends un interpréteur autre (car je sais que tu voulais te lancé en ruby pur) tu risques fort de tomber sur un interpréteur US qui n'a que le ASCII de base (même pas étendu). Si c'est le cas, ben tes accents vont être interprétés comme des caractère de flux ou des caractères inconnus. Dans un cas comme dans l'autre, tu risques d'avoir des problèmes. Donc à bannir de tes noms de variables. Pour une valeur de chaîne (string) c'est ok (ex. ma_string = "Je suis Français") Entre les guillemets, c'est correct, mais pas dans le nommage. Donc, à bon entendeur... Wink


Dernière édition par MirainoHikari le Lun 16 Mar 2009 - 15:41, édité 1 fois
Revenir en haut Aller en bas
http://mirainohikari.deviantart.com
La Meche
Flibustier Lv.21
Flibustier Lv.21
La Meche


Masculin Age : 30
Inscrit le : 24/05/2008
Messages : 3234

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeLun 16 Mar 2009 - 14:58

Bon bah ok...
En fait c'est juste que je dois écrire hamecon au lieux de hameçon et j'aime pas ^^'
C'est tout !
(Ainsi que Pecher au lieux de Pêcher)
Bref, merci sur ces explications ^^
Revenir en haut Aller en bas
MirainoHikari
Ex-Admin-Script
Ex-Admin-Script
MirainoHikari


Masculin Age : 42
Inscrit le : 26/05/2008
Messages : 2360

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeLun 16 Mar 2009 - 15:43

Ton autre possibilité est de coder en anglais Razz. Donc au lieu de hameçon et pêcher, écrit lure et fishing comme nom de variable...
Revenir en haut Aller en bas
http://mirainohikari.deviantart.com
La Meche
Flibustier Lv.21
Flibustier Lv.21
La Meche


Masculin Age : 30
Inscrit le : 24/05/2008
Messages : 3234

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeLun 16 Mar 2009 - 16:16

ah ouais !
Pas con bête ça !
Merci beaucoup !

Fallait chercher loin dit-moi ma petite mechouille ... !
Revenir en haut Aller en bas
ASHKA
Voyageur Lv.10
Voyageur Lv.10
avatar


Masculin Age : 42
Inscrit le : 04/12/2008
Messages : 383

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeMar 27 Oct 2009 - 8:22

J'ai re-uploadé le .txt du module.

Fichier module
Revenir en haut Aller en bas
Kouett
Mage Lv.11
Mage Lv.11
Kouett


Féminin Age : 26
Inscrit le : 22/08/2010
Messages : 521

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeLun 20 Sep 2010 - 18:25

Ben, Je tiens a vous Féliciter. C'est Pas facile de Créez Des Script Cours # 6 : Window_Selectable et scene complexe. 80245
Revenir en haut Aller en bas
http://eden-making.frbb.net/
Blockade
Ex-Admin Cruelle
Ex-Admin Cruelle
Blockade


Féminin Age : 32
Inscrit le : 03/07/2008
Messages : 2441

Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitimeLun 20 Sep 2010 - 19:25

Ouais cool.
Mais la c'est du nécropost + flood donc désolée mais c'est l'avertissement.
Merci de faire attention à l'avenir Smile
Revenir en haut Aller en bas
Contenu sponsorisé




Cours # 6 : Window_Selectable et scene complexe. Empty
MessageSujet: Re: Cours # 6 : Window_Selectable et scene complexe.   Cours # 6 : Window_Selectable et scene complexe. Icon_minitime

Revenir en haut Aller en bas
 

Cours # 6 : Window_Selectable et scene complexe.

Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1

 Sujets similaires

-
» Un SBS complexe...
» Script d'HP MP "complexe" map
» > Fenêtre de vie complexe <
» Système de pierre de retour complexe.
» Système Morpion complexe (Event)

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
RPG Maker VX :: Entraide :: Apprentissage :: Archives des anciens cours :: Cours de RGSS2-
Créer un forum | ©phpBB | Forum gratuit d'entraide | Signaler un abus | Cookies | Forum gratuit