Submit Your Article Guild Wars 2 Forum RPG Maker VX.com
 
RPG Maker
 

 Username:
 Password:
   Not a member? Register!



Home > RGSS Script Reference > Window_Message

Window_Message


Inherits from: Window_Selectable

Description: This is the main message window shown when a "Show Message" event command is used.

Code


class Window_Message < Window_Selectable
# ------------------------------------
 def initialize
    super(80, 304, 480, 160)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.visible = false
    self.z = 9998
    @fade_in = false
    @fade_out = false
    @contents_showing = false
    @cursor_width = 0
    self.active = false
    self.index = -1
  end
# ------------------------------------
  def dispose
    terminate_message
    $game_temp.message_window_showing = false
    if @input_number_window != nil
      @input_number_window.dispose
    end
    super
  end
# ------------------------------------ 
  def terminate_message
    self.active = false
    self.pause = false
    self.index = -1
    self.contents.clear
    @contents_showing = false
    if $game_temp.message_proc != nil
      $game_temp.message_proc.call
    end
    $game_temp.message_text = nil
    $game_temp.message_proc = nil
    $game_temp.choice_start = 99
    $game_temp.choice_max = 0
    $game_temp.choice_cancel_type = 0
    $game_temp.choice_proc = nil
    $game_temp.num_input_start = 99
    $game_temp.num_input_variable_id = 0
    $game_temp.num_input_digits_max = 0
    if @gold_window != nil
      @gold_window.dispose
      @gold_window = nil
    end
  end
# ------------------------------------
  def refresh
    self.contents.clear
    self.contents.font.color = normal_color
    x = y = 0
    @cursor_width = 0
    if $game_temp.choice_start == 0
      x = 8
    end
    if $game_temp.message_text != nil
      text = $game_temp.message_text
      begin
        last_text = text.clone
        text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
      end until text == last_text
      text.gsub!(/\\[Nn]\[([0-9]+)\]/) do
        $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
      end
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" }
      text.gsub!(/\\\\/) { "\\" }
      while ((c = text.slice!(/./m)) != nil)
        if c == "\001"
          text.sub!(/\[([0-9]+)\]/, "")
          color = $1.to_i
          if color >= 0 and color <= 7
            self.contents.font.color = text_color(color)
          end
          next
        end
        if c == "\002"
          if @gold_window == nil
            @gold_window = Window_Gold.new
            @gold_window.x = 560 - @gold_window.width
            @gold_window.y = self.y >= 128 ? 32 : 384
            @gold_window.opacity = self.opacity
            @gold_window.back_opacity = self.back_opacity
          end
          next
        end
        if c == "\n"
          if y >= $game_temp.choice_start
            @cursor_width = [@cursor_width, x].max
          end
          y += 1
          x = 0
          if y >= $game_temp.choice_start
            x = 8
          end
          next
        end
        self.contents.draw_text(4 + x, 32 * y, 40, 32, c)
        x += self.contents.text_size(c).width
      end
    end
    if $game_temp.choice_max > 0
      @item_max = $game_temp.choice_max
      self.active = true
      self.index = 0
    end
    if $game_temp.num_input_variable_id > 0
      digits_max = $game_temp.num_input_digits_max
      number = $game_variables[$game_temp.num_input_variable_id]
      @input_number_window = Window_InputNumber.new(digits_max)
      @input_number_window.number = number
      @input_number_window.x = self.x + 8
      @input_number_window.y = self.y + $game_temp.num_input_start * 32
    end
  end
# ------------------------------------
  def reset_window
    if $game_temp.in_battle
      self.y = 16
    else
      case $game_system.message_position
      when 0
        self.y = 16
      when 1
        self.y = 160
      when 2
        self.y = 304
      end
    end
    if $game_system.message_frame == 0
      self.opacity = 255
    else
      self.opacity = 0
    end
    self.back_opacity = 160
  end
# ------------------------------------
  def update
    super
    if @fade_in
      self.contents_opacity += 24
      if @input_number_window != nil
        @input_number_window.contents_opacity += 24
      end
      if self.contents_opacity == 255
        @fade_in = false
      end
      return

    end
    if @input_number_window != nil
      @input_number_window.update
      if Input.trigger?(Input::C)
        $game_system.se_play($data_system.decision_se)
        $game_variables[$game_temp.num_input_variable_id] =
          @input_number_window.number
        $game_map.need_refresh = true
        @input_number_window.dispose
        @input_number_window = nil
        terminate_message
      end
      return
    end
    if @contents_showing
      if $game_temp.choice_max == 0
        self.pause = true
      end
      if Input.trigger?(Input::B)
        if $game_temp.choice_max > 0 and $game_temp.choice_cancel_type > 0
          $game_system.se_play($data_system.cancel_se)
          $game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
          terminate_message
        end
      end
      if Input.trigger?(Input::C)
        if $game_temp.choice_max > 0
          $game_system.se_play($data_system.decision_se)
          $game_temp.choice_proc.call(self.index)
        end
        terminate_message
      end
      return
    end
    if @fade_out == false and $game_temp.message_text != nil
      @contents_showing = true
      $game_temp.message_window_showing = true
      reset_window
      refresh
      Graphics.frame_reset
      self.visible = true
      self.contents_opacity = 0
      if @input_number_window != nil
        @input_number_window.contents_opacity = 0
      end
      @fade_in = true
      return
    end
    if self.visible
      @fade_out = true
      self.opacity -= 48
      if self.opacity == 0
        self.visible = false
        @fade_out = false
        $game_temp.message_window_showing = false
      end
      return
    end
  end
# ------------------------------------
  def update_cursor_rect
    if @index >= 0
      n = $game_temp.choice_start + @index
      self.cursor_rect.set(8, n * 32, @cursor_width, 32)
    else
      self.cursor_rect.empty
    end
  end
end

Properties


Fade_In: This flag is set to true if the window is in the process of fading in. It is set to false otherwise

Fade_Out: This flag is set to true if the window is in the process of fading out. It is set to false otherwise

Contents_Showing: This flag is set to true if the window's contents are showing. It is set to false otherwise

Input_Number_Window: This is a Window_InputNumber object that contains the number input window associated with the message window. This window is nil if there's no "Input Number" event command either by itself or following a "Show Message" command of three or fewer lines. Note that the window's border is invisible, so only the window's contents are shown.

Gold_Window: A Window_Gold object. This window is nil unless the message text contains the "\g" control code. In this case, the gold window is shown until the message window is closed.

Methods


Regular Expressions

This class uses a pattern-matching scheme called Regular Expressions to parse the control codes contained within the message. Statements beginning with "text.gsub!" are statements that check for a specific set of characters, such as "\g". In this particular script, the control codes are converted to special escape characters, such as "\002", so that when the main loop encounters them, it can process them easily. Regular Expressions are not particularly easy for a beginner to understand, and Ruby's syntactic handling of them doesn't help matters. Because Regular Expressions require an extensive tutorial in themselves, the pattern-matching for control codes will not be explained here. For a tutorial on the basics, please go [ here ].



Initialize

Arguments: None
Local Variables: None

How it Works: This method initializes the window. The window's x coordinate is set to 80, its y coordinate is set to 304, its width is set to 480, and its height is set to 160. The message window is intended to show above all other windows, so its z-index is set at 9999. The next four statements initialize various window properties. @fade_in and @fade_out are used to determine if the window is fading in or out. The @contents_showing is set once the text has been drawn in the window, and @cursor_width is initially set to 0. This value is only set to a nonzero value if this message window includes choices generated by a "Show Choices" event command. The window is then set to be inactive and its index is set to be -1 (nothing selected).

Dispose

Arguments: None
Local Variables: None

How it Works: This method cleans up the window and frees the memory allocated to the object. First, the method terminate_message is run to ensure that the temporary variables are reset properly and that the gold window is disposed of, if necessary. The global variable $game_temp.message_window_showing is set to false, and if this message window used a number input window, that window's dispose method is also called.

Terminate_Message

Arguments: None
Local Variables: None

How it Works: This method is executed when the player terminates the message window. I does a little cleanup on the window object itself, but exists mostly to reset the many global variables that are used as intermediaries between the event command interpreter and the message window object. First, the window is set to be inactive, unpaused, and not selecting anything. The window's contents are then cleared. The values of nine global variables dealing with message window functioning are set to their default of "null" values. If this message used the "\g" control code to create a gold window, that window's dispose method is called at this time.

Refresh

Arguments: None
Local Variables:
x: The current x coordinate of the text to be drawn.
y: The current y coordinate of the text to be drawn. By default, this is 32 times the line number on which the text will be drawn, with the top line being line 0.
c: The current character of text being processed by the method. "Processed" meaning either being drawn, or, if the character is a control code, executing the effects of the control code.
text: The text string to be processed by the method. The method first isolates control codes within the string, and then draws each character of text.

How it Works: This method draws the message text within the message window. First, the window's contents are cleared, and the font is set to the normal color. The local variables x and y are both set to 0 to begin with. Note that unlike most other text processing methods, the value of y is a logical value representing the line number (with the top line being line 0). This value is converted into a y coordinate when the text is actually drawn. These two variables describe the location at which the next letter in the message will be drawn. If the value of $game_temp.choice_start is 0 (meaning that this window is being used only for a "Show Choices" event command without any preceding message text, then the value of x is changed to 8. The global variable text is then loaded with the value of the global variable $game_temp.message_text, if there is any message text to display. The variable $game_temp.message_text acquires its value when the event command interpreter encounters a "Show Message" command, and is used to pass the text to the message window object. The begin...end loop goes through and finds each instance of the "\v[n]" control code and replaces it with the value of variable n. The loop terminates when there are no more instances of the "\v[n]" control code to replace. The next text.gsub! loop goes through the message text and finds each instance of the \n[n] control code and substitutes the name of the proper actor, or "" (null string) if the actor doesn't exist. The next text.gsub! command checks for instances of the \c[n] control code. It replaces these with the special character "\001". The next one replaces instances of the "\g" control code with the special character "\002". The last one replaces instances of the "\\" control code with the "\" character. After all that is done, we come to main loop for this method. The syntax for the loop condition is a bit strange, so I'll explain. The statement while ((c = text.slice!(/./m)) != nil) executes the "slice!" method, which removes the first character from the string and returns that character to the caller, in this case, the assignment statement for c. The loop then processes the character that is stored in c. So, the result is that one character in the string is cut off with each iteration of the loop. Once the string is nil (that is, empty), there is no more text to process. The first two if statements in the loop check to see if the character being processed is one of the two special characters generated by control code processing. If the character being processed is "\001", then the next thing done is processing the characters "[0-9]" to see which color should be changed to. The local variable color is set to the value of $1, which is a special variable that holds the last method return, in this case, the number returned by the sub! method. The color value is then evaluated by the Window_Base#text_color method, and the font color is changed to the color returned. If the character being processed is "\002", then @gold_window is set. The x coordinate is set at 560 minus the length of the gold window, which will be 400 by default. The y coordinate of the gold window depends on the message window's y coordinate. If the message window's y coordinate is 128 or greater, then the gold window's y coordinate is 32. If not, then the gold window's y coordinate is 384. The gold window's opacity and back opacity are set equal to those of the message window. If the character being processed is "\n" (newline character), then the method checks to see if the current y value (prior to going to the next line) is greater than or equal to the line number on which the choices start. If it is, then the cursor width is set equal to the maximum of the current cursor width or x. The effect of this is that the cursor width will be set to the width of the longest choice. The value of x is reset to 0, and the y value is incremented, meaning the message is advancing to the next line. If the y value is now greater than or equal to the line on which the choices start, the value of x is set to 8. If the text is none of these control codes, then the letter stored in c is drawn at the current x coordinate, and the y line indicator, times 32 (where the top line is line 0). The x coordinate is then increased by the width of the letter in the current font, in pixels, in preparation for drawing the next letter. This ends both the if $game_temp.message_text != nil statement and the while ((c = text.slice!(/./m)) != nil) loop. The last part of this method processes. If $game_temp.choice_max is greater than or equal to 0 (that is, one or more choices are to be shown in this message window), then the window becomes active and its index is set to 0 (cursor pointing at the first choice). If the value of $game_temp.num_input_variable_id is greater than 0, which means that there's an "Input Number" event command associated with this message window, then the values for the maximum number of digits in the variable and the number are set. The @input_number_window object is then instantiated with the digit maximum. The x coordinate of the number window within the message window is set to 8, and y coordinate is set to 32 times the value of $game_temp.num_input_start, which is the line number within the message window on which the number input begins, with the top line being line 0.

Reset_Window

Arguments: None
Local Variables: None

How it Works: This method sets the window's position and transparency state in response to the "Message Display Options" event command. First, if the player is in battle, the message window's y coordinate is always 16. On the map, the position is set according to the value of $game_system.message_position. If the value is 0 (top), then the y coordinate is set at 16. If the position is 1 (middle), then the y coordinate is set at 160. If the position is 2 (bottom), then the y coordinate is set at 304. The transparency state of the window is set according to the value of $game_system.message_frame. If the value is 0 (opaque), then the window's opacity is set at 255. If the value is 1 (transparent), then the window's opacity is set at 0. The back opacity is then set at 160.

Update

Arguments: None
Local Variables: None

How it Works: This method updates the window each frame. First, this method calls the superclass method to perform update operations common to all windows. The first check is to see if the @fade_in flag is set. If it is, then the opacity of the contents is increased by 24. Looked at in the big picture, this means that the contents will fade in over the course of 11 frames. If the number input window exists, the opacity of its contents also fade in. If this causes the opacity of the contents to be 255, then the @fade_in flag is set to false and the method returns. The next block of code is executed only if the number input window has been instantiated. The number input window is updated, and the input is checked. If the player has pressed key "C" (decision key), then the decision sound effect is played, and the variable of ID stored in $game_temp.num_input_variable_id is set to the value of the @number instance variable in the number input window object. The $game_map_need_refresh flag is then set, since the change in the variable could cause the conditions for other events to either be satisfied or no longer satisfied. The input number window is then disposed and the message is terminated. If if @contents_showing block checks to see if the choice max is 0 (no choices are to be shown in this message window). If that's the case, then the pause flag for the window is set. The if Input.trigger?(Input::B) block handles cancellation of choices. If the choice max for this window is greater than 0, and the "cancellation type" is not 0 (cannot cancel), then the cancel sound effect is played and the choice cancellation procedure for the choice numbered equal to the cancellation type, minus 1, is called (since the top choice is labelled 0 internally). The if Input.trigger?(Input::C) block handles selection of choices. If the choice max is above 0, then the procedure for the choice with the internal identifier equal to the window's index is called, and the message is terminated. The if @fade_out == false and $game_temp.message_text != nil block handles what happens before the window fades in. First, the @contents_showing flag is set. The $game_temp.message_window_showing flag is set in order to stop other processes from proceeding while the message window is showing. The reset_window method sets the proper position for the window. The refresh method then draws the text in the window. The window is then made visible, but the opacity of its contents is set to 0, since the contents are meant to fade in over the course of 11 frames. If the number input window has been instantiated, the opacity of its contents is also set to 0. Then the @fade_in flag is set. The if self.visible block is a bit deceptive, since at first glance, it would seem that as soon as the block above made the window visible, this block would fade it back out without giving the player an opportunity to read the message, but this is not the case. Before this can happen, the window will be paused, which halts all activity, meaning that this method won't get past the call to the superclass method. Once the player unpauses the window by pushing the decision key, this block will set the @fade_out flag and reduce the opacity of the window contents by 48. If the opacity of the contents is 0, then the visibility flag is cleared and the $game_temp.message_window_showing flag is cleared, so that other processes will now continue. The effect of this is that when the player unpauses the window, the contents will fade out over the course of six frames.

Update_Cursor_Rect

Arguments: None
Local Variables: None

How it Works: This method updates the cursor rectangle in the event that the message window is being used for a "Show Choices" event command. If the index is greater than 0 (that is, the choice selection is active), then the cursor rectangle's y coordinate is set to be 32 times the index of the choice selected, plus the value of $game_temp.choice_start, which is the line number on which the first choice is shown, with the top line being line 0. If there is no choice selection in this message window, then the cursor rectangle is set to be invisible. 
Syntax
@
@@
$
alias
[array index]
attr_accessor
attr_reader
attr_writer
class
def
do
ensure
for
if
[iterator]
key => value
new
next
nil
redo
require
return
rescue
self
super
undef
unless
until
while
yield

Classes
Arrow_Actor
Arrow_Base
Arrow_Enemy
Game_Actor
Game_Actors
Game_BattleAct
Game_Battler
Game_Character
Game_Common
Game_Enemy
Game_Event
Game_Map
Game_Party
Game_Picture
Game_Player
Game_Screen
Game_SlfSwitch
Game_Switches
Game_System
Game_Troop
Game_Variables
Interpreter
Scene_Debug
Scene_End
Scene_Equip
Scene_File
Scene_Gameover
Scene_Item
Scene_Load
Scene_Map
Scene_Menu
Scene_Name
Scene_Save
Scene_Shop
Scene_Skill
Scene_Status
Scene_Title
Sprite_Battler
Sprite_Character
Sprite_Picture
Sprite_Timer
Spriteset_Battle
Spriteset_Map
Window_Base
Window_Battleresult
Window_Battlestatus
Window_Command
Window_DebugLeft
Window_DebugRight
Window_EquipItem
Window_EquipLeft
Window_EquipRight
Window_Gold
Window_Help
Window_InputNumb
Window_Item
Window_MenuStatus
Window_Message
Window_NameEdit
Window_NameInput
Window_PartyCom
Window_PlayTime
Window_SaveFile
Window_Selectable
Window_ShopBuy
Window_ShopCom
Window_ShopNum
Window_ShopSell
Window_ShopStatus
Window_Skill
Window_SkillStatus
Window_Status
Window_Steps
Window_Target

Other
Class Hierarchy
Global Variables


RPG RPG Revolution
RPG RPG Revolution is your #1 stop for game development and console RPG games, as well as those created by people like you. Link to us to support us, so we may grow to be better website community for you.

RPG RPG Revolution is an Privacy Policy and Legal