[Tutorial] Window Class Creation and Adding Windows To Scenes

Discussion in 'Learning Javascript' started by Kino, Aug 2, 2016.

  1. Kino

    Kino EIS Game Dev Veteran

    Messages:
    515
    Likes Received:
    669
    Location:
    United States
    First Language:
    English
    Primarily Uses:
    RMMV
    Introduction


    Hello; this is a tutorial on how to create your own window class and addings windows to a scene of your choice.


    Before we can really get started, it's important to have a basic understanding of how windows function in RMMV.


    Windows


    Every window in RMMV is an extension of the Window Class, however most of the ones you see in game are all extensions of the Window_Base Class.


    Both of these window classes provide a lot of basic functionality for any kind of window you'd want to create.


    How Do Windows Work?


    Windows are classes that are instantiated in game to display information for you, or provide ways to interact with the game, usually on a scene; this usually happens in a scene's 'createAllWindows' method.


    //Generally how a window is created by calling this method or another create method
    Scene_Map.prototype.createAllWindows = function() {
    this.createMessageWindow();
    this.createScrollTextWindow();
    };

    //The actual creation looks more like this
    Scene_Map.prototype.createMapNameWindow = function() {
    //The window is instantiated and stored as a part of the scene
    this._mapNameWindow = new Window_MapName();
    //The window is then added as a child to the scene, which is when you're finally able to see it on screen
    this.addChild(this._mapNameWindow);
    };


     Once these windows are instantiated, and added to a scene like the above, you can finally interact with them. Once that happens, this is where the window's update method comes into play.


    Window Update


    Every window has an update method; this method is what allows the window to really handle any sort of processing. If the update method didn't exist; the window would simply sit there after executing your code once. In that regard, it's important to think of any code that you put into your update method as a loop, and to keep in mind the order of execution for things like drawing to the window. Consider the update function the core of your window, and keep it in mind at all times.


    //Window Selectables Update Method -- handles all processing for user input such as scrolling, arrow inputs, etc
    Window_Selectable.prototype.update = function() {
    Window_Base.prototype.update.call(this);
    this.updateArrows();
    this.processCursorMove();
    this.processHandling();
    this.processWheel();
    this.processTouch();
    this._stayCount++;
    };




    Now that we know these important pieces, we can create our own window class.


    Window Class Creation Pattern


    The window classes in RMMV all have useful functions you can make use of; we can do this by creating a window class with any of RMMV's windows as a base.


    We can refer to this as the window class creation pattern.


    function MyWindow() {
    //this function will run whenever we make a new MyWindow object(a new window of this type)
    // arguments is a special keyword, which basically means all the arguments passed into MyWindow upon creation, will be sent to the initialize method
    this.initialize.apply(this, arguments);
    }

    //This line of code gives us all the functionality provided in Window_Base, and makes it a part of our MyWindow class
    MyWindow.prototype = Object.create(Window_Base.prototype)
    //This sets the constructor to be MyWindow; nothing special here
    MyWindow.prototype.constructor = MyWindow;

    //This is the initialize method that's called above when my window is instantiated.
    //The argument keyword essentially passes the information you enter into the parameters x, y, width, height below
    MyWindow.prototype.initialize = function(x, y, width, height) {
    //This call, calls the original code provided in the Window_Base.prototype function, allowing us to make use of it (think of it like copy and pasting instructions)
    //This is only important, because we plan to add more code to when we initialize a window.
    Window_Base.prototype.initialize.call(this, x, y, width, height);
    }

    //The core of any new window class; this is what handles processing for the window while the game is running
    //We call the Window_Base.prototype update method, so we can use that code and also add more to this function.
    MyWindow.prototype.update = function() {
    Window_Base.prototype.update.call(this);
    }




    An important thing to note about this pattern is that the initialize function is not always necessary. Any method that already exists on Window_Base.prototype can now be found on MyWindow.prototype. This means that you only need to add methods you want to make changes to, or add new methods that you want to use in methods provided by the window class you're instantiating from. Just remember to check the methods attached to the window you're instantiating from before you accidentally overwrite it. Either way, this really is the core of making your own window class.


    One thing to note is that prototypes are basically instance methods; they only get used when you create a new object of that type. That means you can have a class with both static methods(methods attached to the class itself) and instance methods for when you create a new object of that type (I'd recommend against mixing though).


    Adding Windows To Any Scene Dynamically


    Although windows are great to have on their own, and you can add them to a scene in a plugin, maybe you want to add them dynamically. Well, there is a way to do that, and it's similar to what's used above when a scene creates a window.


    Add Window To Scene 


    //Get the current scene from the SceneManager
    var scene = SceneManager._scene;
    //Create a new 'MyWindow'
    var myWindow = new MyWindow(200, 200, 300, 300);
    //Use the scene.addChild method to add the new 'myWindow' to the scene at the specified coordinates.
    scene.addChild(myWindow);




    Using that pattern, you can add a window to any scene you want; you can even use it to create pop up windows if you want. However, you'll still need to provide implementation for your window, and it won't be as easy to find a reference of your window to close it if you wanted to. This is because, the window isn't stored as a reference in an easy to get to way.


    The End


    Hopefully this tutorial helps someone with creating windows, and also helps them make more dynamic windows, which can be used on any scene; it's really a nice tool to have in your toolbox.


    Finally, thank you for taking the time out to read this tutorial, and if I can answer any questions, I'll be sure to do so.
     
    #1
    Eliaquim, LTN Games, DoubleX and 4 others like this.
  2. DjBepy

    DjBepy Villager Member

    Messages:
    9
    Likes Received:
    2
    First Language:
    German
    Primarily Uses:
    RMMV
    To close the Window, use the window_base.prototype.close function (https://github.com/swquinn/rmmv-docs/blob/master/docs/Window_Base.md):


    MyWindow.prototype.close = function() {
    Window_Base.prototype.close.call(this);
    }

    So, you can close the window every time with
    myWindow .close();
     
    #2
    Kino likes this.
  3. Eliaquim

    Eliaquim Raze: The Rakuen Zero's Guardian! Veteran

    Messages:
    570
    Likes Received:
    167
    Location:
    Brazil - Rio de Janeiro
    First Language:
    Portuguese - Br
    Primarily Uses:
    RMMV
    I'm trying to do this,. but doenst work.

    Code:
    Window_Confirmation.prototype.close = function() {
        Window_Base.prototype.close.call(this);
    };
    
    Window_Confirmation.prototype.open = function() {
        Window_Base.prototype.open.call(this);
    };
    So i call inside a function
    Window_Confirmation.open();

    but dont work =/
    already tried:

    ConfirmationWindow.open()
    this.ConfirmationWindow.open()
    this._ConfirmationWindow.open()

    =/
     
    #3
  4. Jonforum

    Jonforum Veteran Veteran

    Messages:
    1,568
    Likes Received:
    1,324
    Location:
    Canada / Québec
    First Language:
    French
    Primarily Uses:
    RMMV
    Better way it use real class in js, it will allow you to scope this of the rpgmaker class you extend.

    PHP:
    class _MyWindow extends rpgMakerClassYouWant {
        
    constructor() {
            
    super();

        };

        
    customMethod1(options) {
           
    //stuff
        
    };
        
    customMethod2(options) {
           
    //stuff
        
    };

    let $MyWindow = new _MyWindow();
    };
     
    #4
    Eliaquim likes this.
  5. Eliaquim

    Eliaquim Raze: The Rakuen Zero's Guardian! Veteran

    Messages:
    570
    Likes Received:
    167
    Location:
    Brazil - Rio de Janeiro
    First Language:
    Portuguese - Br
    Primarily Uses:
    RMMV
    wOW! Not sure if i understando but i will test it in the code! I'm already done with this, but to learn, I will try!
    Thanks!!
     
    #5
  6. Aloe Guvner

    Aloe Guvner Walrus Veteran

    Messages:
    1,456
    Likes Received:
    930
    Location:
    USA
    First Language:
    English
    Primarily Uses:
    RMMV
    If your window inherits from Window_Base, there's no need to define the open and close functions, those will be inherited.

    1. You need to identify what the instance of the window is named. Window_Confirmation is the class, the function isn't called on the class it's called on the instance of that class.
    You can open the console and type SceneManager._scene. and then use the autocomplete dropdown to see what it's named.

    2. You need to verify the context of this. If you're trying to do "this._confirmationWindow.open()", then this must be the context of the scene. Or if you were doing "this.open()" then this must be the context of the window. Does that make sense?
     
    #6
    Eliaquim likes this.

Share This Page