autodidact

Veteran
Veteran
Joined
Nov 13, 2020
Messages
78
Reaction score
62
First Language
English
Primarily Uses
RMMV
Hello, I am trying to work on making multiple windows for a HUD display.
It works to display the windows and images, but only one of the windows will update (the last one).

I can't for the life of me figure out why only one of my windows will update when every other window in the map scene seems to update.

Of course, there is more code than I pasted below, but this refresh function seems to be the only problem. I have an "id" variable attached to every instance of a HUD_Window, but the console.log line shows that only the second window will run the refresh method. The first one never runs the refresh method.

I would love some help figuring this out.

JavaScript:
var smstart = Scene_Map.prototype.start;
    Scene_Map.prototype.start = function() {
        smstart.apply(this, arguments);
        this.arrayOfHUDs = [];
        for (let i = 0; i < HUDwindowsArray.length; i++) {
            var hw = new Hud_Window(i);
            console.log(hw);
            this.arrayOfHUDs.push(hw);
            console.log(this.arrayOfHUDs.length+'i'+i);
            this.addChild(this.arrayOfHUDs[i]);
        }

    Hud_Window.prototype.refresh = function() {
        if (true) {
            this.contents.clear();
            console.log(this.hudID);
            this.drawHUDicon(this.image_HUDicon, 0,0,32,32);
            this.drawDamageImage($gameVariables.value(2), 1, 200, 200);
        } //end if showing
        else {
            this.contents.clear();
        }
    }

EDIT: Okay, I feel a little better now. I entered the game menu and exited and the first window updated itself (though it is stuck until I reenter and exit the menu). It looks like I need to manually call an update method for this. But I don't know where and I don't know why since the second one updates perfectly fine.

I forgot some important code:
JavaScript:
   //declare the new window class
    function Hud_Window() {
        this.initialize.apply(this, arguments);
        referenceToMenu = this;
    }
    
    //Inherit from Window_Base and set constructor to Hud_Window (?the declaration of my class)
    Hud_Window.prototype = Object.create(Window_Base.prototype);
    Hud_Window.prototype.constructor = Hud_Window;

 Hud_Window.prototype.initialize = function(hudnumber) {
        Window.prototype.initialize.call(this);
        ...
 }
 
Last edited:

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
3,063
Reaction score
2,375
First Language
EN
Primarily Uses
RMMZ
Some quick notes:
  • You're missing a } on your Scene_Map#start method. I guess that's just a forum post typo.
  • I assume HUDwindowsArray is properly defined somewhere.
  • I'm not sure what that referenceToMenu variable is for but it looks like a bad idea.

Typically windows do not call their refresh method every frame. In this particular case, Window_Base does not even have a refresh method, so you will need to define your window's update method to refresh when appropriate, e.g.
JavaScript:
Hud_Window.prototype.update = function() {
    Window_Base.prototype.update.apply(this, arguments);
    if (/* display value has changed */) {
        this.refresh();
    }
};

Also, windows are usually added to the window layer, not directly to the scene itself, e.g.
JavaScript:
this.addWindow(this.arrayOfHUDs[i]);
 

autodidact

Veteran
Veteran
Joined
Nov 13, 2020
Messages
78
Reaction score
62
First Language
English
Primarily Uses
RMMV
EDIT: I make the stupidest mistakes when I program. When implementing the update method, I typed this.update() in place of this.refresh(), creating an infinite loop. I fixed that and it works perfectly, for both HUDs. Thanks, Caethyril!

Yay, the Cae-valry has arrived! I don't remember where I learned to make windows, but I have some bad practices it seems. Thanks for taking a peak.
  • You're missing a } on your Scene_Map#start method. I guess that's just a forum post typo.
  • I assume HUDwindowsArray is properly defined somewhere.
  • I'm not sure what that referenceToMenu variable is for but it looks like a bad idea.
  • Yeah, just a forum post typo. My code is inundated with comments, I'm afraid it will be very messy to read for anyone else; so I just pasted and cleaned the parts that were particularly relevant.

  • Yes, "var HUDWindowsArray = JSON.parse(HUDwindowsJSON);" is defined at the top the plugins self-invoking function, which parses a RPG MV struct parameter.

  • I had read that it is very difficult to close windows without a reference, but in this case I was using it to manually refresh a window from plugin command. Should I be doing "this.arrayOfHUDs.refresh();" instead of referencing "this"?

this.addWindow(this.arrayOfHUDs);
So, I just do a simple replacement of addChild() to addWindow() ? Just asking because I don't know better.

Typically windows do not call their refresh method every frame. In this particular case, Window_Base does not even have a refresh method, so you will need to define your window's update method to refresh when appropriate, e.g.
That is really nice to know. I was confused because my one HUDs updated when it was supposed to.
I added a new property to the initialization method to define this.hudData = 0;
I have added the update method to the prototype:
JavaScript:
Hud_Window.prototype.update = function() {
        Window_Base.prototype.update.apply(this, arguments);
        if (this.hudData != $gameVariables.value(2)) {
            this.refresh();
        }
    };

EDIT: The error below was because I had this.update(); in the above update method instead of this.refresh(); I blame it on being too excited to try the new code.

So, I ran into this error when I implemented your suggestions. I must be doing something wrong. Exactly when the HUD should have updated its value, I get RangeError - Maximum call stack size exceeded

1633880208014.png

Line 314 is Window_Base.prototype.update.apply(this, arguments);
Line 316 is this.update();
 
Last edited:

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
3,063
Reaction score
2,375
First Language
EN
Primarily Uses
RMMZ
I had read that it is very difficult to close windows without a reference, but in this case I was using it to manually refresh a window from plugin command. Should I be doing "this.arrayOfHUDs.refresh();" instead of referencing "this"?
I was talking about the referenceToMenu variable defined in your Hud_Window constructor: it looks like a global variable, but you're already storing references on the active scene. Also, if there are multiple HUD windows, that would only store the most recently-constructed one. :kaoswt:

For a "manual HUD refresh" plugin command, I would consider something like this:
JavaScript:
var huds = SceneManager._scene.arrayOfHUDs;
if (huds) {
  for (var hud of huds) {
    hud.refresh();
  }
}
I.e. get the current scene's arrayOfHUDs property; if it exists, then (assuming it is an array) iterate through and refresh each HUD referenced in that array.


So, I just do a simple replacement of addChild() to addWindow() ?
Yep! addWindow just does this:
JavaScript:
Scene_Base.prototype.addWindow = function(window) {
    this._windowLayer.addChild(window);
};
I mentioned it because usually windows are added like this; depending on how you want the HUD to look, you might want to stick with addChild. The window layer is hidden when taking a map snapshot, for example. :kaophew:
 

autodidact

Veteran
Veteran
Joined
Nov 13, 2020
Messages
78
Reaction score
62
First Language
English
Primarily Uses
RMMV
Yes, that "referenceToMenu" was old code when I only wanted 1 window.

I love how your "manual HUD refresh" plugin command looks. But I'm not sure if I'll need it now that I know how to write a proper update method.

Oh and that is really good to know about addChild and addWindow.
I really can't say thanks enough, I've learned alot!
 

Latest Profile Posts

Lord's Reincarnation III (LR3) MOBILE is coming!!!
iu_534706_7630675.png
ScreenShot_1_20_2022_2_19_41.png
Juice FX is amazing... the portal in the middle is actually animated and moves thanks to Juice FX. so I edited part of a map I have and then drew the portal around it. threw it into Juice FX and now it's lively instead of static.
Another thumb update. The nail is beginning to break away, along with the aforementioned hard and blackened dead skin. The final join has regained some of its flexibility, tho it's a bit stiff after being held still for so long. The very tip of my thumb has a strange dry and somewhat tingly feeling to it when I touch it to something, but at least it isn't numb. I am so ready for this to be over. :o
Can I get away with calling a "shortsword" a dagger and not a sword?

Forum statistics

Threads
118,709
Messages
1,118,072
Members
155,842
Latest member
gxoulz
Top