RMMV - Small setClickHandler problem.

Lady_Blackpearl

Villager
Member
Joined
May 25, 2018
Messages
27
Reaction score
15
First Language
Italian
Primarily Uses
RMMV
Hi!
first thing first I hope this is the right place to ask. I have been all day wondering, trying and smashing my head on desk, wall and almost jumping myself outt he window. XD
In short I have a problem (or two probably) with setClickHandler. I made a menu with custom icons that does replace the commands, and they are working, until you press on the "skill", "equip" and "status" buttons. If I click one of this buttons in fact, it does bring me to the Scene_Menu.prototype.commandPersonal (where you have to select with cursor the character), but then is a dead end. Pressing again mouse after selected one of the characters does nothing. My guess at this point is that the script doesn't know which button was pressed and which character was selected. And I have no clue how to tell him this. I followed in part this guide. Thank you to any that can help. I'm gonna post the main part of the code in case need. Perhaps could have cut a lot of coding with a different method :x

Code:
Scene_Menu.prototype.createCommandImages = function() {
        
        this._menuCmdBackground = new Sprite();
        this._menuCmdBackground2 = new Sprite();
        
        this._itemButton = new Sprite_Button();
        this._skillsButton = new Sprite_Button();
        this._equipButton = new Sprite_Button();
        this._statusButton = new Sprite_Button();
        this._formationButton = new Sprite_Button();
        this._saveButton = new Sprite_Button();
        this._optionsButton = new Sprite_Button();
        this._endButton = new Sprite_Button();

        this._menuCmdBackground.bitmap = ImageManager.loadSystem(menuCommandBackground);
        this._menuCmdBackground2.bitmap = ImageManager.loadSystem(menuCommandBackground2);
        
        this._itemButton.bitmap = ImageManager.loadSystem("cmdBtn_A1");
        this._skillsButton.bitmap = ImageManager.loadSystem("cmdBtn_A2");
        this._equipButton.bitmap = ImageManager.loadSystem("cmdBtn_A3");
        this._statusButton.bitmap = ImageManager.loadSystem("cmdBtn_A4");
        this._formationButton.bitmap = ImageManager.loadSystem("cmdBtn_A5");
        this._saveButton.bitmap = ImageManager.loadSystem("cmdBtn_A6");
        this._optionsButton.bitmap = ImageManager.loadSystem("cmdBtn_A7");
        this._endButton.bitmap = ImageManager.loadSystem("cmdBtn_A8");
        
        this._itemButton.x = 496;
        this._skillsButton.x = this._itemButton.x + 36;
        this._equipButton.x = this._skillsButton.x + 36;
        this._statusButton.x = this._equipButton.x + 36;
        this._formationButton.x = this._statusButton.x + 36;
        this._saveButton.x = this._formationButton.x + 36;
        this._optionsButton.x = this._saveButton.x + 36;
        this._endButton.x = this._optionsButton.x + 36;
        this._itemButton.y = this._skillsButton.y = this._equipButton.y = this._statusButton.y
        = this._formationButton.y = this._saveButton.y = this._optionsButton.y = this._endButton.y = this._endButton.y = 51;
        
        this.addChild(this._itemButton);
        this.addChild(this._skillsButton);
        this.addChild(this._equipButton);
        this.addChild(this._statusButton);
        this.addChild(this._formationButton);
        this.addChild(this._saveButton);
        this.addChild(this._optionsButton);
        this.addChild(this._endButton);
    
};

Scene_Menu.prototype.createCommandWindow = function() {
        this._commandWindow = new Window_MenuCommand(0, 0);
        this._commandWindow.visible = false;
        this._commandWindow.x = Graphics.boxWidth;
        this._commandWindow.y = Graphics.boxHeight;
        this._commandWindow.setHandler('item',      this.commandItem.bind(this));
        this._commandWindow.setHandler('skill',     this.commandPersonal.bind(this));
        this._commandWindow.setHandler('equip',     this.commandPersonal.bind(this));
        this._commandWindow.setHandler('status',    this.commandPersonal.bind(this));
        this._commandWindow.setHandler('formation', this.commandFormation.bind(this));
        this._commandWindow.setHandler('options',   this.commandOptions.bind(this));
        this._commandWindow.setHandler('save',      this.commandSave.bind(this));
        this._commandWindow.setHandler('gameEnd',   this.commandGameEnd.bind(this));
        this._commandWindow.setHandler('cancel',    this.popScene.bind(this));
        this.addWindow(this._commandWindow);
        
};

Scene_Menu.prototype.update = function() {
        Scene_MenuBase.prototype.update.call(this);
        
            // item image button
                this._itemButton.setClickHandler(this.commandItem.bind(this));
            // skill image button
                this._skillsButton.setClickHandler(this.commandPersonal.bind(this));
            // equip image button
                this._equipButton.setClickHandler(this.commandPersonal.bind(this));
            // status image button
                this._statusButton.setClickHandler(this.commandPersonal.bind(this));
            // formation image button
                this._formationButton.setClickHandler(this.commandFormation.bind(this));
            // save image button
                this._saveButton.setClickHandler(this.commandSave.bind(this));
            // options image button
                this._optionsButton.setClickHandler(this.commandOptions.bind(this));
            // end image button
                this._endButton.setClickHandler(this.commandGameEnd.bind(this));
};

// This is the part where my code having trouble

Scene_Menu.prototype.commandPersonal = function() {
        this._statusWindow.setFormationMode(false);
        this._statusWindow.selectLast();
        this._statusWindow.activate();
        this._statusWindow.setHandler('ok',     this.onPersonalOk.bind(this));
        this._statusWindow.setHandler('cancel', this.onPersonalCancel.bind(this));
    };
   
Scene_Menu.prototype.onPersonalOk = function() {
        switch (this._commandWindow.currentSymbol()) {
        case 'skill':
            SceneManager.push(Scene_Skill);
            break;
        case 'equip':
            SceneManager.push(Scene_Equip);
            break;
        case 'status':
            SceneManager.push(Scene_Status);
            break;
        };
    };
   
    Scene_Menu.prototype.onPersonalCancel = function() {
        this._statusWindow.deselect();
        this._commandWindow.activate();
    };
 

Lady_Blackpearl

Villager
Member
Joined
May 25, 2018
Messages
27
Reaction score
15
First Language
Italian
Primarily Uses
RMMV
Well theorically I know where is problem but can't fix it. The fact is that if I first move cursor with left or right and place on top of equip for example and then press mouse button for enter in the select part and then again press mouse button on one of the characters work. I guess pressing with mouse directly to one of the command buttons (images that I did) doesn't tell to the code either the index of the command or
this._commandWindow.currentSymbol().
 

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
First, one piece of advice:
I would advise not to set the clickHandlers inside the 'update' function.
Why? Well this 'update' function runs every single frame (60x per second), but you only need to set the click Handler once. In fact, we want to keep the 'update' functions as empty as possible to reduce lag and memory.
My advice is to set the click Handlers inside your 'createCommandImages' function (or create a new function and execute it from 'createCommandImages').


Next, your issue.
So the tricky part is that Equip, Status, Skill all leads to 'commandPersonal', correct? When we are inside 'commandPersonal', we need to know which button brings us there.
Take a close look at the documentation for bind().

Notice anything useful? We have to supply the definition of 'this', but we can also supply any amount of arguments. Useful!

For example, pass an argument into the commandPersonal for each of the buttons.
Code:
this._skillsButton.setClickHandler(this.commandPersonal.bind(this, "skill"));
this._equipButton.setClickHandler(this.commandPersonal.bind(this, "equip"));
this._statusButton.setClickHandler(this.commandPersonal.bind(this, "status"));
Receive the argument in 'commandPersonal' and pass the argument to 'onPersonalOk':
Code:
Scene_Menu.prototype.commandPersonal = function(type) {
       this._statusWindow.setFormationMode(false);
       this._statusWindow.selectLast();
       this._statusWindow.activate();
       this._statusWindow.setHandler('ok',     this.onPersonalOk.bind(this, type));
       this._statusWindow.setHandler('cancel', this.onPersonalCancel.bind(this));
   };
Receive the argument and use it to set the next scene in 'onPersonalOk' :
Code:
Scene_Menu.prototype.onPersonalOk = function(type) {
        switch (type) {
        case 'skill':
            SceneManager.push(Scene_Skill);
            break;
        case 'equip':
            SceneManager.push(Scene_Equip);
            break;
        case 'status':
            SceneManager.push(Scene_Status);
            break;
        };
    };
 
Last edited:

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,299
Reaction score
11,713
First Language
English
Primarily Uses
RMVXA
[move]Learning Javascript[/move]
 

Lady_Blackpearl

Villager
Member
Joined
May 25, 2018
Messages
27
Reaction score
15
First Language
Italian
Primarily Uses
RMMV
First, one piece of advice:
I would advise not to set the clickHandlers inside the 'update' function.
Why? Well this 'update' function runs every single frame (60x per second), but you only need to set the click Handler once. In fact, we want to keep the 'update' functions as empty as possible to reduce lag and memory.
My advice is to set the click Handlers inside your 'createCommandImages' function (or create a new function and execute it from 'createCommandImages').


Next, your issue.
So the tricky part is that Equip, Status, Skill all leads to 'commandPersonal', correct? When we are inside 'commandPersonal', we need to know which button brings us there.
Take a close look at the documentation for bind().

Notice anything useful? We have to supply the definition of 'this', but we can also supply any amount of arguments. Useful!

For example, pass an argument into the commandPersonal for each of the buttons.
Code:
this._skillsButton.setClickHandler(this.commandPersonal.bind(this, "skill"));
this._equipButton.setClickHandler(this.commandPersonal.bind(this, "equip"));
this._statusButton.setClickHandler(this.commandPersonal.bind(this, "status"));
Receive the argument in 'commandPersonal' and pass the argument to 'onPersonalOk':
Code:
Scene_Menu.prototype.commandPersonal = function(type) {
       this._statusWindow.setFormationMode(false);
       this._statusWindow.selectLast();
       this._statusWindow.activate();
       this._statusWindow.setHandler('ok',     this.onPersonalOk.bind(this, type));
       this._statusWindow.setHandler('cancel', this.onPersonalCancel.bind(this));
   };
Receive the argument and use it to set the next scene in 'onPersonalOk' :
Code:
Scene_Menu.prototype.onPersonalOk = function(type) {
        switch (type) {
        case 'skill':
            SceneManager.push(Scene_Skill);
            break;
        case 'equip':
            SceneManager.push(Scene_Equip);
            break;
        case 'status':
            SceneManager.push(Scene_Status);
            break;
        };
    };
Hmm right, I haven't try it yet but will check later. And I was guessing right. The click on button didn't give any info on which one was, like the command code does. (I was just simply trying to learn it following youtube videos and making my own part and not sure why in youtube videos they placed handler in the update. :p Thank you. I will try later.

[move]Learning Javascript[/move]
Ops sorry. I swear I went once in that forum and wasn't loading or giving error. But now is working.
 
Last edited:

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
It's good that your guess was correct! It means you are able to see the real meaning of the code, and you can adapt the tutorials to learn new things. I am sure you will figure it out!

If you are stuck, just let me know.


Oh, and don't worry about the blue text from moderators, it is automatically-generated and used for information. If you ever see red text, then something is wrong.
 

Lady_Blackpearl

Villager
Member
Joined
May 25, 2018
Messages
27
Reaction score
15
First Language
Italian
Primarily Uses
RMMV
Well is working fine thank you! The only problem is with this code pressing the mouse button doesn't make any sound effects. I guess it miss a part of code where it tell once pressed button it should play the default sound effect . So I have try a different way:

Cuttted a piece of code to add bitmap images since doesnt need it in this thread
Code:
Scene_Menu.prototype.createCommandImages = function() {
    
        // item image button
            this._itemButton.setClickHandler(this.onButtonDown.bind(this, "item"));
        // skill image button
            this._skillsButton.setClickHandler(this.onButtonDown.bind(this, "skill"));
        // equip image button
            this._equipButton.setClickHandler(this.onButtonDown.bind(this, "equip"));
        // status image button
            this._statusButton.setClickHandler(this.onButtonDown.bind(this, "status"));
        // formation image button
            this._formationButton.setClickHandler(this.onButtonDown.bind(this, "formation"));
        // save image button
            this._saveButton.setClickHandler(this.onButtonDown.bind(this, "options"));
        // options image button
            this._optionsButton.setClickHandler(this.onButtonDown.bind(this, "save"));
        // end image button
            this._endButton.setClickHandler(this.onButtonDown.bind(this, "endGame"));

    };
 
    Scene_Menu.prototype.onButtonDown = function (type) {
    SoundManager.playOk();
 
        switch (type) {
            case 'item':
                SceneManager.push(Scene_Item);
                break;
            case 'skill':
            
                break;
            case 'equip':
            
                break;
            case 'status':
            
                break;
            case 'formation':
            
                break;
            case 'save':
                SceneManager.push(Scene_Save);
                break;
            case 'options':
                SceneManager.push(Scene_Options);
                break;
            case 'endGame':
                //this._commandWindow.close();
                SceneManager.push(Scene_GameEnd);
                break;
        };
    };
I just need to guess how to call the commandPersonal now and formation but at least the sound effect and other buttons are working XD
The only big problem I have is now the onmouseover this buttons. The only thing I know is how to get mouse pos x and y with TouchInput.x and y. But I dont think touchinput is fine because yes in console log it show the pos of the mouse but only after I clicked the left button (I have try place console.log(X: " + x + "Y: " + y); after assigned the variables and it was showing X: 0 Y: 0 until LMB was pressed or hold LMB and I guess because eh "Touch" Input. XD but I'm ignorant in certain things :p

The problem is that rainbow cursor around the buttons , while I move mouse over the one of them it should move.
Well one thing at time tho or Im gonna suicide for real XD

EDIT: Forgot to mention, your code is working, I just modified a bit because no sound options and de eventuality to move that cursor.
 
Last edited:

Lady_Blackpearl

Villager
Member
Joined
May 25, 2018
Messages
27
Reaction score
15
First Language
Italian
Primarily Uses
RMMV
Ok I managed to make it work somehow (I'm not sure is the correct way). But I still have some small graphic bugs specially with the formation screen. When select formation from menu, the rect that highlight the actual character selected size doesn't cover the full window height and the selectable goes all so wrong. While the cursor move exactly on the 4 characters area, the selectable under is still default size which make all a mess like in the images below. I have search whole both window and scene code but no clue where I need to modify. Also clicking in the center part of screen activate one of the 2 characters despite your cursor is out the character column.

But lets return to the command script... before I get kileld from mod to go off-topic. :x
This is how I made it work. However I'm not sure if is correct. The menu is working fine apart the selectable bug, but I was like forced to add this._commandWindow.close() somehow because the comamnd window was keep moving with left and right while activating buttons with mouse and using the mouse for selecting characters. Then had to add .open() again because cancelling with mouse ( RMB ) was either freezing window or I had the menu closing and going back to the scene map...
Bear in mind that I'm still new in coding and such specially with javascript, despite I watch and read tutorials and info about it is still a bit hard for now to memorize everything XD
I feel like I should restart everythign from new :X

Code:
Scene_Menu.prototype.onButtonDown = function (type) {
    SoundManager.playOk();
    this._commandWindow.close();
        switch (type) {
            case 'item':
                SceneManager.push(Scene_Item);
                break;
            case 'skill':   
                this.commandPersonal("skill");
                break;
            case 'equip':
                this.commandPersonal("equip");
                break;
            case 'status':
                this.commandPersonal("status");
                break;
            case 'formation':
                this.commandFormation();
                break;
            case 'save':
                SceneManager.push(Scene_Save);
                break;
            case 'options':
                SceneManager.push(Scene_Options);
                break;
            case 'endGame':
                SceneManager.push(Scene_GameEnd);
                break;
        };
    };

    Scene_Menu.prototype.commandPersonal = function(type) {
        this._statusWindow.setFormationMode(false);
        this._statusWindow.selectLast();
        this._statusWindow.activate();
        this._statusWindow.setHandler('ok',     this.onPersonalOk.bind(this, type));
        this._statusWindow.setHandler('cancel', this.onPersonalCancel.bind(this));
    };
   
    Scene_Menu.prototype.onPersonalOk = function(type) {
        switch (type) {
        case 'skill':
            SceneManager.push(Scene_Skill);
            break;
        case 'equip':
            SceneManager.push(Scene_Equip);
            break;
        case 'status':
            SceneManager.push(Scene_Status);
            break;
        };
    };

   Scene_Menu.prototype.onFormationCancel = function() {
        if (this._statusWindow.pendingIndex() >= 0) {
            this._statusWindow.setPendingIndex(-1);
            this._statusWindow.activate();
        } else {
            this._statusWindow.deselect();
            this._commandWindow.activate();
// the part where I had to reopen the comamnd window
            this._commandWindow.open();
        }
    };
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

Day 9 of giveaways! 8 prizes today :D
He mad, but he cute :kaopride:

Our latest feature is an interview with... me?!

People4_2 (Capelet off and on) added!

Just beat the last of us 2 last night and starting jedi: fallen order right now, both use unreal engine & when I say i knew 80% of jedi's buttons right away because they were the same buttons as TLOU2 its ridiculous, even the same narrow hallway crawl and barely-made-it jump they do. Unreal Engine is just big budget RPG Maker the way they make games nearly identical at its core lol.

Forum statistics

Threads
106,038
Messages
1,018,466
Members
137,821
Latest member
Capterson
Top