Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

How do I use a less than mathematical comparision with a loop?

Alright, you people are the experts here. Well atleast some of you ^_^

What I want is to put a timer in using a variable such as count.
Ie
Count=0
Until count=1000
count=count+1
Loop


As far as I understand it, in rmxp with the rgss you'd express it like this right?
@count==1
    while @count <100
@count=+1
    end

I am very determined to master the rgss. It's a challenge that I am tackling head first. I have nothing to lose but free time. However.. many of the commands, and the other such things like internal variables are not well defined...

 
Almost. You used @count==1 at first. This is comparison, not actually setting the value. Use = instead of ==.
So your code would be:
Code:
@count = 1
while @count < 100
  @count += 1
end

However, if you use a while loop with no Graphics update, it will result in Script Hanging if you do it for too long.
 
Also, your code will run as fast as the processor can go, and interrupt the rest of the game from running.

If your code is in one of the methods that are already looping once per frame (update, etc..) , you do not need the loop statement. You need to initialize the @count variable somewhere else, like in the initialize method, or even from a event
command.  Setting @count to anything other than 100 (1000, whatever your max is) could be the trigger that starts the timer.

It would be helpful if you explained what you want to use this timer for. Then we can make a recommendation as to the best way to implement it.

Be Well
 
Thanks. What I really need is a way to make text auto clear. I stumbled upon the self.dispose command, and put it into a custom window class in the refresh method. The problem is I need a way to count the amount of time the custom window is on the screen for. Otherwise I end up with this:

def refresh
self.contents.clear
self.contents.draw_text(0,0,150,150, "lol lol lol!!!", 1)
self.dispose
end

Which causes the window to dispose too quickly.
 
refresh only gets called when something in the window changes.
In your example, you are disposing of the window right after you draw the text.
You want to test your timer variable in the update method.

Here is an example of the default Window_Message class, modified to accept a "\w[n]" code,
which will wait n frames, then terminate the window.
To see the code I added, do a "Match Case" search on "WAIT"

Code:
#==============================================================================
# ** Window_Message
#------------------------------------------------------------------------------
#  This message window is used to display text.
#==============================================================================

class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  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
    # WAIT   initialize the wait variable to -1 (inactive)
    @wait = -1
    self.active = false
    self.index = -1
  end
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  def dispose
    terminate_message
    $game_temp.message_window_showing = false
    if @input_number_window != nil
      @input_number_window.dispose
    end
    super
  end
  #--------------------------------------------------------------------------
  # * Terminate Message
  #--------------------------------------------------------------------------
  def terminate_message
    self.active = false
    self.pause = false
    self.index = -1
    self.contents.clear
    # Clear showing flag
    @contents_showing = false
    # Call message callback
    if $game_temp.message_proc != nil
      $game_temp.message_proc.call
    end
    # Clear variables related to text, choices, and number input
    $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
    # Open gold window
    if @gold_window != nil
      @gold_window.dispose
      @gold_window = nil
    end
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    self.contents.font.color = normal_color
    x = y = 0
    @cursor_width = 0
    # Indent if choice
    if $game_temp.choice_start == 0
      x = 8
    end
    # If waiting for a message to be displayed
    if $game_temp.message_text != nil
      text = $game_temp.message_text
      # Control text processing
      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
      # Change "\\\\" to "\000" for convenience
      text.gsub!(/\\\\/) { "\000" }
      # Change "\\C" to "\001" and "\\G" to "\002"
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" }
      # Change "\\W" to "\011" - WAIT
      # we change the escape sequence to a single character for the next section
      # that cycles through the text one character at a time.
      text.gsub!(/\\[Ww]\[([0-9]+)\]/) { "\011[#{$1}]" }
      # Get 1 text character in c (loop until unable to get text)
      while ((c = text.slice!(/./m)) != nil)
        # If \\
        if c == "\000"
          # Return to original text
          c = "\\"
        end
        # If \C[n]
        if c == "\001"
          # Change text color
          text.sub!(/\[([0-9]+)\]/, "")
          color = $1.to_i
          if color >= 0 and color <= 7
            self.contents.font.color = text_color(color)
          end
          # go to next text
          next
        end
        # If \W[n] - WAIT
        if c == "\011"
          # Set the wait variable to the number of frames specified
          text.sub!(/\[([0-9]+)\]/, "")
          @wait = $1.to_i
          # go to next text
          next
        end
        # If \G
        if c == "\002"
          # Make gold window
          if @gold_window == nil
            @gold_window = Window_Gold.new
            @gold_window.x = 560 - @gold_window.width
            if $game_temp.in_battle
              @gold_window.y = 192
            else
              @gold_window.y = self.y >= 128 ? 32 : 384
            end
            @gold_window.opacity = self.opacity
            @gold_window.back_opacity = self.back_opacity
          end
          # go to next text
          next
        end
        # If new line text
        if c == "\n"
          # Update cursor width if choice
          if y >= $game_temp.choice_start
            @cursor_width = [@cursor_width, x].max
          end
          # Add 1 to y
          y += 1
          x = 0
          # Indent if choice
          if y >= $game_temp.choice_start
            x = 8
          end
          # go to next text
          next
        end
        # Draw text
        self.contents.draw_text(4 + x, 32 * y, 40, 32, c)
        # Add x to drawn text width
        x += self.contents.text_size(c).width
      end
    end
    # If choice
    if $game_temp.choice_max > 0
      @item_max = $game_temp.choice_max
      self.active = true
      self.index = 0
    end
    # If number input
    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
  #--------------------------------------------------------------------------
  # * Set Window Position and Opacity Level
  #--------------------------------------------------------------------------
  def reset_window
    if $game_temp.in_battle
      self.y = 16
    else
      case $game_system.message_position
      when 0  # up
        self.y = 16
      when 1  # middle
        self.y = 160
      when 2  # down
        self.y = 304
      end
    end
    if $game_system.message_frame == 0
      self.opacity = 255
    else
      self.opacity = 0
    end
    self.back_opacity = 160
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If fade in
    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 inputting number
    if @input_number_window != nil
      @input_number_window.update
      # Confirm
      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
        # Dispose of number input window
        @input_number_window.dispose
        @input_number_window = nil
        terminate_message
      end
      return
    end
    # If message is being displayed
    if @contents_showing
      # If choice isn't being displayed, show pause sign
      # add:  and if we're not waiting - WAIT
      if $game_temp.choice_max == 0 && @wait < 0
        self.pause = true
      end
      # Cancel
      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
      # Confirm
      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
      # WAIT - if our wait counter hits 0, terminate the message
      if @wait > 0
        @wait -= 1
        if @wait == 0
          @wait = -1
          terminate_message
        end
      end
      return
    end
    # If display wait message or choice exists when not fading out
    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 message which should be displayed is not shown, but window is visible
    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
  #--------------------------------------------------------------------------
  # * Cursor Rectangle Update
  #--------------------------------------------------------------------------
  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

Here's an example of a text message:
Code:
@>Text: This message will self destruct
 :        : in 5 seconds \w[100]
@>

Credit to Ccoa, as it was done this way in her UMS script
 
Well...that's odd. It doesn't seem to work for me.
Also I took a few minutes to skim over the code. The first thing I notice is the @wait Variable here in the object initialization of window_message class

Code:
# WAIT   initialize the wait variable to -1 (inactive)
    @wait = -1
The second thing I notice that you changed or added to is here:

Code:
# If \W[n] - WAIT
        if c == "\011"
          # Set the wait variable to the number of frames specified
          text.sub!(/\[([0-9]+)\]/, "")
          @wait = $1.to_i
          # go to next text
          next
        end
How does this work exactly? I'm not satisfied with simply using a script. I want to understand the inner workings of the rgss as much as possible. My first question is where does the
Code:
=$1.to_i
Come from?

And also, where is this variable getting it's value from? It doesn't seem clear.
Code:
if c == "\011"

I'll be very grateful if somone could help me understand what this code is doing to itself. Thanks!

EDIT: I got that command working. However it doesn't solve my problem. What I want is a window that displays itself and then closes itself. I don't want the player to have to press a button. I want it to auto clear. Normally the arrow thing shows and it waits for the action button to be pressed. I want that to go away and get replaced by a timer command...
 
Strange, it worked for me. Did you replace your Window_Message script, or paste this in a new script above Main?  (either should work)

Sorry, I'll try to explain better...

the first change:

     @wait = -1

I initialize the variable to -1 to indicate that it's not being used. When you use it, valid values are >= 0

You missed one section, around line 97 in the refresh method

      text.gsub!(/\\[Ww]\[([0-9]+)\]/) { "\011[#{$1}]" }

what this does is replace the "\W" (2 characters), with a single character "\011"
so that when we cycle through the text one character at a time in the next section,
it makes it easier to determine that we have a "wait" code.
the second part of the gsub command [#{$1}],  just transfers the numeric part of the wait code "\W[100]"

The next part,

# If \W[n] - WAIT
        if c == "\011"
          # Set the wait variable to the number of frames specified
          text.sub!(/\[([0-9]+)\]/, "")
          @wait = $1.to_i
          # go to next text
          next
        end

when we are cycling through the text one character at a time, and we encounter the "\011" character,
we do a text.sub! to extract the numeric part of the code & it gets stored in $1 as a text string.
so, the @wait = $1.to_i is to convert it to an integer. So, the number you put in brackets after the '\w'
is now stored in @wait as an integer.

Last, in the update method, which executes once every frame,

      # WAIT - if our wait counter hits 0, terminate the message
      if @wait > 0
        @wait -= 1
        if @wait == 0
          @wait = -1
          terminate_message
        end
      end

first we test to see if the @wait variable has a value greater than 0.
if it does, then we subtract one from it.  @wait -= 1
Then we check to see if it is now equal to 0
if it is, we set it to -1 (inactive), and terminate the message window.

I hope that helps explain it a little better.

Be Well
 
Huh. I found a much simpler method to do what I need. And I can make it wait as long as I want by changing the @Wait variable if I add a loop.

My Solution seems more practical ^_^

0_0 I figured it out myself... It took some ninja skillz.[/
b]

First in Window_Base change the initialize line to add the @wait=-1

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
    @wait=-1
    self.active = false
    self.index = -1
  end

Now, the tricky part that I wanted to know originally and had to dig through code myself to find...
# Confirm
      if @wait <=1
        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

Instead of using the If input.trigger?[Input::C] If statement with the end statment before the "terminate_message" method call. You just do what I did. ^_^
 
I created another method for that, and tried calling it. I'm stuck yet again.
I decided to create a multiplier variable for this event (Defualt variable 50).

Code:
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
    @wait=game_variables.@data[50] #The intent here is to multiply it by variable 50.. 0_0 how do I use a variable in a script?? I'm trying everything..
    self.active = false
    self.index = -1
  end
The intent here is to multiply it by variable 50.. 0_0 how do I use a variable in a script?? I'm trying everything...I want to use a multiplier to make the amount of time the timer runs for, changable through an event.

Code:
def wait_timer
@wait-=1 until wait=1
end
And this above, is my decrement method.



 
You want to multiply @wait by variable 50? If so, use the line:
Code:
@wait *= $game_variables[50]
And about your decrement method. You're back to where you started. By using 'until', it will loop forever, causing nothing else to update. It would be wise to look into what Brewmeister posted earlier.
 
Actually "until" is a loop, so what will happen is @wait will decrement until it reaches 1
This will all happen as fast as the processor can go, which will be about 0.0001 seconds.
So,

@wait-=1 until wait=1

would basically have the same effect as

@wait = 1

except it will generate 0.00001276453 more joules of heat in your processor.

Goofing aside,  you need to decrement @wait once in update method (or another method called by update. or another method called within the loop in the 'main' method of your scene class.  That way, it gets decremented once per frame. (20 frames = 1 second)

Be Well
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top