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.

[Resolved] Window disposal at new scene

Status
Not open for further replies.
I made a @display_window in map scene. Everytime I need to, I'll use a script event to specify a text for it to display. Either an area name or just empty. I did this because I need a display that can be modified without player button input.

When the player press up button, the area on the top is enlarged a bit and the @display_window shows the name of the area. If he presses the C button, he will go to that area. If he presses left button, left picture enlarges and @display_window shows the name of that area, etc.

http://img522.imageshack.us/img522/1955 ... ectht0.jpg[/IMG]

Now, my problem is, if a player presses up and then goes to menu and exit again, the 'up' input is still stored and the up picture enlarged but the text is gone. if he presses C, he will go to the 'up' area.

http://img521.imageshack.us/img521/8761 ... xitma1.jpg[/IMG]

The text dissapears because I disposed the window when I shift to menu. I'm wondering if I don't dispose the window everytime i change scene into menu back and forth, will there be only one instance of the window or multiples of it (since @display_window = Window_Display.new is in def main)? How do I work around this?
 
I am not sure what you are asking, but maybe this will answer your question...

Code:
class Window_Something
  @@saved_word = ''
  def initialize
    # your initialize
  end
  def set_text(text)
    @@saved_word = text
    refresh
  end
  def refresh
    # draw your word here
  end
end

Class variables (@@variable) are saved in every object of that class.


I think that is what you are asking. If not, can you please clerify?
 
This is what is in my Window_Display class. I used a global because I thought it's easier.
Code:
#==============================================================================
# ** Window_Display
#------------------------------------------------------------------------------
#  This window displays various messages
#==============================================================================

class Window_Display < Window_Base
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    super(0, 320, 640, 160)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.opacity = 0
    $display = ""
    refresh
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    Rect.new(0, 0, 999, 999)
    self.contents.font.color = normal_color
    self.contents.font.size = 30
    self.contents.draw_text(0, 40, 608, 32, $display,1)
  end
end

Then in Scene_Map's def main I put @display_window = Window_Scene.new.
Then in Scene_Map's def update I put @display_window.refresh
Then in Scene_Map's def main, under Graphics.freeze I put @display_window.dispose

Whenever I need to change it in events, I put in event script $display = "area name". I also have a common event that is called whenever a player presses C during area select to set $display = "" and clear the area pictures. I think that's everything.
 
Here is what I recommend. It reduces lag, and saves on a global variable.

Code:
class Game_System
  attr_accessor :main_display_word
  alias vinsagi_display_gmsys_init initialize
  def initialize
    vinsagi_display_gmsys_init
    @main_display_word = ''
  end
end

#==============================================================================
# ** Window_Display
#------------------------------------------------------------------------------
#  This window displays various messages
#==============================================================================

class Window_Display < Window_Base
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    super(0, 320, 640, 160)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.size = 30
    self.opacity = 0
    update
  end
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
    super
    if @display_word != $game_system.main_display_word
      self.contents.clear
      @display_word = $game_system.main_display_word
      self.contents.draw_text(0, 40, 608, 32, @display_word,1)
    end
  end
end

Now, instead of $display, you use the $game_system.main_display_word as your variable. I changed your refresh method, as Rect.new(0, 0, 999, 999), does nothing, setting font color & size every frame isn't needed, so I deleted the color = normal_color (is default for all windows) and moved the size up into the initialization.

I changed the refresh method to update since you plan to call it every frame, there is no reason to call update and refresh every frame. I created an instance variable for the sole purpose that it will only clear and redraw the words when the $game_system.main_display_word changes.

If you wanted to make things real easy, you could do this as well:
Code:
class Scene_Map
  alias vinsagi_display_scnmap_main main
  alias vinsagi_display_scnmap_updt mupdate
  def main
    @display_window = Window_Display.new
    vinsagi_display_scnmap_main
    @display_window.dispose
  end
  def update
    @display_window.update
    vinsagi_display_scnmap_updt
  end
end

That's the basic format of adding a window to Scene_Map, in a copy and paste manner. It uses the alias (check Me(TM)'s tutorial in the Tutorials section for more), which basically allows you to add commands in methods without overwriting them.

Let me know if you still have trouble.

PS: Good scripting format.
 
While I tried replacing window horizontal with your solution and made it work, I read the tutorial on aliasing like you suggested. I have some questions about it.

Code:
class MyFirstScript
  def initialize
    p "Hello world"
    do_message
  end

  def do_message
    p "This is a test script"
  end
end

This is the first class that is supposed to be the default right? and then the next is the one below it that we are going to add without modifying the original?

Code:
class MyFirstScript
  alias the_old_init initialize
  def initialize
    p "Yay, it works"
    the_old_init
    p "Roxors"
  end
end

So ruby will read the original class and encounter a second copy at which point it makes a copy of the original (the alias). Then the second class overwrites the original and slip in the copy of the original?. That doesn't sound like "adding instead of overwriting" to me. Does the alias become method of its own then? Can it be regarded as one? Like an alias of an alias if need be? I guess ruby only scrolls down to the lowest method of the same name before performing it, ignoring previous methods?

PS: I didn't script any of those. I just copied a window, changed the class name, editted the content accordingly. I only understand the basic concepts, what the lines do. Tell me to write from scratch, I'll start scratching my head.
 
The alias does nothing more than change a methods name.

Remember, all those little methods are constantly being invoked, from the first and main loop in the game
Code:
while $scene != nil
  $scene.main
end
to all the objects and such being created. Everything that happens is just methods doing their jobs.

Anyways, since we don't want to alter methods like main, since they are already being called, we instead want to rename the method the recreate it with our mods and recall the original call. When you alias some method, you rename it.

Code:
class Something
  def some_method
  end
end

p :Something.methods -> ["some_method", <all methods in class object>]

class Something
  alias oldsomemethod some_method
  def some_method
    # blah
    oldsomemethod
  end
end

p :Something.methods  -> ['some_method', 'oldsomemethod', <all methods in class object>]

Theres nothing really magical about it, but many just don't understand what the alias does, nor methods for that matter.
 
Basically.

You have A.
You want A + B.
So you alias A to C.
Call a New "A".
Call Old A (which is no C).
Add your new B.

The best structure for an alias is
Code:
class <your class>
  alias <yourname>_<scriptname>_<classname>_<method_name> <orignal_mehod_name>
  def <orignal_mehod_name>
    <yourname>_<scriptname>_<submethod_name1>
    <yourname>_<scriptname>_<classname>_<method_name> 
    <yourname>_<scriptname>_<submethod_name2>
  end
  def <yourname>_<scriptname>_<submethod_name1>
  end
  def <yourname>_<scriptname>_<submethod_name2>
  end
end

A = <orignal_mehod_name>
B = <yourname>_<scriptname>_<submethod_name1> and/or <yourname>_<scriptname>_<submethod_name2>
C = <yourname>_<scriptname>_<classname>_<method_name>

What you are doing is creating new sub-methods. It is better when you alias a method, even if you are adding a 1-line edit, to create a new sub-method. The reason for this is just compatabilty. By creating a new sub-method, you make it that much easier to make additions to.

So in your above exampe:

Code:
class MyFirstScript
  def initialize
    p "Hello world"
    do_message
  end

  def do_message
    p "This is a test script"
  end
end

Code:
class MyFirstScript
  alias the_old_init initialize
  def initialize
    it_works
    the_old_init
    roxors
  end
  def it_works
    p "Yay, it works"
  end
  def roxors
    p "Roxors"
  end
end

Probably not a good example, but for complex scripts this is usually a good idea. Yes, creating all those methods will create a slight and usually un-noticed decline in performance, but this is Ruby. Ruby wasn't designed for speed. It was designed for simplicity.
 
I don't know what I should feel. It's good that I learn something new and useful, on the other hand I already I butchered the default scenes of my current project so much. I guess I'll start from scratch.

Thanks though, SepirothSpawn.
 
As a scripter, you should always be learning. I learn new tips and tricks all the time. I am constantly going back over my old scripts and fixing them to be better coded. Strive for perfection.

This topic has been resolved. If vin.sagi or any other users have any questions or further problems regarding this topic, please create a new thread about them.

Thank you!
 
Status
Not open for further replies.

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