How to call which command a cursor is currently over

Status
Not open for further replies.

TragicNumberOne

Veteran
Veteran
Joined
Feb 9, 2018
Messages
32
Reaction score
3
First Language
English
Primarily Uses
RMMV
Hi, I'm trying to create a custom game menu, but I've run into a challenge that I haven't been able to solve myself:

How do I call which command a cursor is over.

Right now I have a menu consisting of multiple screen. What I want is one window to list multiple commands, and the other to display a description of the command the cursor is over. I have been able to set everything else up, but am now stuck on how to call which command a cursor is over.

Example:

Window 1:
Command 1
Command 2
Command 3
Command 4

Window 2:
Blank Description

If the cursor is currently over command 1, then description will become description 1.
If the cursor is over command 2, then description will become description 2.
etc.

If anyone needs more info to answer, just ask. Thanks in advance for the help!
 

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
This first response will be with general pointers, you'll learn most by doing trial & error. But there's no use if it makes no sense at all, if you need more detail just reply and I'll give more.

I'm making this reply assuming that your Window1 is of class Window_Command or at least a child of Window_Command.

You need to do two general things:

  1. Add Window2 as a property of Window1. In JavaScript, if you add the object of Window2 as a property of Window1, it is "added by reference". That means that any change to the property of Window1 affects Window2, and vice-versa.
  2. Hook into the Window_Selectable.prototype.select method. If your Window1 is a child of Window_Command (which is a child of Window_Selectable), then it will already have the method.

This is a generalization of part 1.
Code:
//I don't know how you are adding Window2 to the scene
//But it probably looks something like this.
Scene_YourScene.prototype.createWindow2 = function() {
   var x = something something;
   var y = something something;
   this._window2 = new Window2(x, y);
   this._window1._descriptionWindow = this._window2;
   //^^^ This is important! Now Window2 is also a property of Window1.
   //In JavaScript this means that any change to ._descriptionWindow is
   //exactly the same as a change to _window2 and vice-versa.
   //Obviously, you need to add Window1 to the scene BEFORE Window2
   console.log(this._window1._descriptionWindow === this._window2);
   //^^ This should be true since they are actually the same object
}
And for Part 2 (which depends on Part 1 being done right):
Code:
//Assuming Window1 is a child of Window_Selectable then it already has this method
//We'll modify it slightly to update Window2
//Now, Window2 get's updated every time the cursor moves on the Window1
Window1.prototype.select = function(index) {
    Window_Selectable.prototype.select.call(this, index);
   //^^This is necessary to perform the usual functions when selecting a command.
    this.updateWindow2();
   //^^This is a new method to update the text of Window2
};

//Let's define a new method to update Window2
//currentSymbol() is going to be an important method here
Window1.prototype.updateWindow2 = function() {
   this._window2.setText(this.currentSymbol());
   //^^You'll have to define a method like this to draw the text corresponding to the
   //current symbol of the command window
   //this._window2.refresh(); //EDIT You don't need this because setText also does refresh
};
 
Last edited:

TragicNumberOne

Veteran
Veteran
Joined
Feb 9, 2018
Messages
32
Reaction score
3
First Language
English
Primarily Uses
RMMV
This first response will be with general pointers, you'll learn most by doing trial & error. But there's no use if it makes no sense at all, if you need more detail just reply and I'll give more.

I'm making this reply assuming that your Window1 is of class Window_Command or at least a child of Window_Command.

You need to do two general things:

  1. Add Window2 as a property of Window1. In JavaScript, if you add the object of Window2 as a property of Window1, it is "added by reference". That means that any change to the property of Window1 affects Window2, and vice-versa.
  2. Hook into the Window_Selectable.prototype.select method. If your Window1 is a child of Window_Command (which is a child of Window_Selectable), then it will already have the method.

This is a generalization of part 1.
Code:
//I don't know how you are adding Window2 to the scene
//But it probably looks something like this.
Scene_YourScene.prototype.createWindow2 = function() {
   var x = something something;
   var y = something something;
   this._window2 = new Window2(x, y);
   this._window1._descriptionWindow = this._window2;
   //^^^ This is important! Now Window2 is also a property of Window1.
   //In JavaScript this means that any change to ._descriptionWindow is
   //exactly the same as a change to _window2 and vice-versa.
   //Obviously, you need to add Window1 to the scene BEFORE Window2
   console.log(this._window1._descriptionWindow === this._window2);
   //^^ This should be true since they are actually the same object
}
And for Part 2 (which depends on Part 1 being done right):
Code:
//Assuming Window1 is a child of Window_Selectable then it already has this method
//We'll modify it slightly to update Window2
//Now, Window2 get's updated every time the cursor moves on the Window1
Window1.prototype.select = function(index) {
    Window_Selectable.prototype.select.call(this, index);
   //^^This is necessary to perform the usual functions when selecting a command.
    this.updateWindow2();
   //^^This is a new method to update the text of Window2
};

//Let's define a new method to update Window2
//currentSymbol() is going to be an important method here
Window1.prototype.updateWindow2 = function() {
   this._window2.setText(this.currentSymbol());
   //^^You'll have to define a method like this to draw the text corresponding to the
   //current symbol of the command window
   this._window2.refresh();
};
Thanks for the help! I tried implementing your suggestion and am getting the error "cannot read property of 'drawtext' of undefined" Do you have any idea what might be wrong?

My part one:
Code:
//this creates the trait description window
Scene_Menu.prototype.createTraitDescWindow = function() {
    this._traitDescWindow = new Window_Trait_Desc(0, 0);
    // Below is the change vv
    this._traitsWindow._traitDescWindow = this._traitDescWindow;
    this._traitDescWindow.x = this._commandWindow.x;
    this._traitDescWindow.y = this._commandWindow.y + this._commandWindow.height;
    this.addWindow(this._traitDescWindow);
};
My part two:
Code:
//number is just for testing purposes. The idea is that if this works, every time I select a new item, the value in the description will go up
var number = 0;
Window_Traits.prototype.updateTraitDesc = function() {
    number++;
    this._traitDescWindow.drawText("test " + number, 0, 0, 0, 'left' );
    //this._traitDescWindow.refresh();
};
I don't know if this is necessary, but since I'm creating a custom window, here is the window that's being created:

Code:
//this is a super generic window. I doubt it's effecting anything, but here it is in case it matters.
function Window_Trait_Desc() {
    this.initialize.apply(this, arguments);
}

Window_Trait_Desc.prototype = Object.create(Window_Base.prototype);
Window_Trait_Desc.prototype.constructor = Window_Trait_Desc;

Window_Trait_Desc.prototype.initialize = function(x, y) {
    var width = this.windowWidth();
    var Height = this.windowHeight();
    Window_Base.prototype.initialize.call(this, x, y, width, Height);
};

Window_Trait_Desc.prototype.windowWidth = function() {
    return 480;
};

Window_Trait_Desc.prototype.windowHeight = function() {
    return 200;
};
Thanks for all the help! I don't know how clear my original question was but you answered perfectly! If you want any more code snippets, feel free to ask.
 

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
Change your Window_Trait_Desc to inherit from Window_Help instead of Window_Base and it will inherit the 'setText' method, you can use that like I described above.
The way I have it, it will draw the text of the 'symbol' of the command the player is currently on, but you can build a simple cross-reference object to turn that symbol into the text you want.

For the error message, without being able to see your whole code, I'm guessing that it's this line:
Code:
this._traitDescWindow.drawText("test " + number, 0, 0, 0, 'left' );
You can also open the console with F8 and it will tell you exactly which line gave an error. The error means that whenever that line was executed, "this._traitDescWindow" was 'undefined'.

It's probably just an issue of when all the windows are created, like it's trying to draw text on a window that doesn't exist. You could try to create the Window_Trait_Desc before the Window_Trait .
Then move this line:
this._traitsWindow._traitDescWindow = this._traitDescWindow;
Inside the Scene Menu . Traits Window Create function

Either that or wrap it in a conditional that checks whether the window is defined before trying to draw text on it.
 

TragicNumberOne

Veteran
Veteran
Joined
Feb 9, 2018
Messages
32
Reaction score
3
First Language
English
Primarily Uses
RMMV
Change your Window_Trait_Desc to inherit from Window_Help instead of Window_Base and it will inherit the 'setText' method, you can use that like I described above.
The way I have it, it will draw the text of the 'symbol' of the command the player is currently on, but you can build a simple cross-reference object to turn that symbol into the text you want.

For the error message, without being able to see your whole code, I'm guessing that it's this line:
Code:
this._traitDescWindow.drawText("test " + number, 0, 0, 0, 'left' );
You can also open the console with F8 and it will tell you exactly which line gave an error. The error means that whenever that line was executed, "this._traitDescWindow" was 'undefined'.

It's probably just an issue of when all the windows are created, like it's trying to draw text on a window that doesn't exist. You could try to create the Window_Trait_Desc before the Window_Trait .
Then move this line:
this._traitsWindow._traitDescWindow = this._traitDescWindow;
Inside the Scene Menu . Traits Window Create function

Either that or wrap it in a conditional that checks whether the window is defined before trying to draw text on it.
I think that this is very close to working, the error is gone. However, now, nothing is printing in the description window. Here is the new code:
Code:
//nothing here was changed. I just included it for reference.

//this creates the trait description window
Scene_Menu.prototype.createTraitDescWindow = function() {
    this._traitDescWindow = new Window_Trait_Desc(0, 0);
    this._traitsWindow._traitDescWindow = this._traitDescWindow;
    this._traitDescWindow.x = this._commandWindow.x;
    this._traitDescWindow.y = this._commandWindow.y + this._commandWindow.height;
    this.addWindow(this._traitDescWindow);
};
Code:
//////////////////////////////////////////////////////////////////////////////////////////////
// Window_Traits
//
// The window for selecting which trait description to view.


var totalTraits = 0;
function Window_Traits() {
    this.initialize.apply(this, arguments);
}

Window_Traits.prototype = Object.create(Window_Command.prototype);
Window_Traits.prototype.constructor = Window_Traits;

Window_Traits.prototype.initialize = function() {
    Window_Command.prototype.initialize.call(this, 0, 0);
    var width = this.windowWidth();
    var Height = this.windowHeight();
    //this.openness = 0;
    //this.open();
};

Window_Traits.prototype.windowWidth = function() {
    return 240;
};

Window_Traits.prototype.windowHeight = function() {
    return this.fittingHeight(4);
};

Window_Traits.prototype.makeCommandList = function() {
    totalTraits = 0;
    this.addCommand("back", 'back', true);
    totalTraits ++;
    if ($gameSwitches.value(11) === true) {
        this.addCommand("Articulate", 'articulate', true);
        totalTraits ++;
    }
    if ($gameSwitches.value(12) === true) {
        this.addCommand("Campaigner", 'campaigner', true);
        totalTraits ++;
    }
    if ($gameSwitches.value(13) === true) {
        this.addCommand("Generous", 'generous', true);
        totalTraits ++;
    }
}

Window_Help.prototype.select = function (index) {
    Window_Selectable.prototype.select.call(this, index);
    this.updateTraitDesc();
};

var number = 0;
Window_Traits.prototype.updateTraitDesc = function() {
    number++;
    this._traitDescWindow.setText("test ");
    this._traitDescWindow.refresh();
};

Scene_Menu.prototype.activateTraitsWindow = function () {
    this._traitsWindow.activate();
}

Scene_Menu.prototype.deactivateTraitsWindow = function () {
    this._commandWindow.activate();
}
Thank you so much for all of this help. I really appreciate it.
 

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
I think you have a mistake here:
Code:
Window_Help.prototype.select = function (index) {
   Window_Selectable.prototype.select.call(this, index);
   this.updateTraitDesc();
};
This should be your custom window, not Window_Help. The one where you have the cursor and select the commands, I think for you it's Window_Trait.

When I said this:
Change your Window_Trait_Desc to inherit from Window_Help instead of Window_Base and it will inherit the 'setText' method, you can use that like I described above.
Hopefully I didn't confuse you. What I meant was:
Code:
//this is a super generic window. I doubt it's effecting anything, but here it is in case it matters.
function Window_Trait_Desc() {
   this.initialize.apply(this, arguments);
}

Window_Trait_Desc.prototype = Object.create(Window_Base.prototype);
//Change to Window_Trait_Desc.prototype = Object.create(Window_Help.prototype);
//Now it inherits everything that Window_Help already has
Window_Trait_Desc.prototype.constructor = Window_Trait_Desc;
 

TragicNumberOne

Veteran
Veteran
Joined
Feb 9, 2018
Messages
32
Reaction score
3
First Language
English
Primarily Uses
RMMV
I think you have a mistake here:
Code:
Window_Help.prototype.select = function (index) {
   Window_Selectable.prototype.select.call(this, index);
   this.updateTraitDesc();
};
This should be your custom window, not Window_Help. The one where you have the cursor and select the commands, I think for you it's Window_Trait.

When I said this:


Hopefully I didn't confuse you. What I meant was:
Code:
//this is a super generic window. I doubt it's effecting anything, but here it is in case it matters.
function Window_Trait_Desc() {
   this.initialize.apply(this, arguments);
}

Window_Trait_Desc.prototype = Object.create(Window_Base.prototype);
//Change to Window_Trait_Desc.prototype = Object.create(Window_Help.prototype);
//Now it inherits everything that Window_Help already has
Window_Trait_Desc.prototype.constructor = Window_Trait_Desc;
I think I successfully applied your changes, but now I have the error again.
Code:
//////////////////////////////////////////////////////////////////////////////////////////////
// Window_Traits
//
// The window for selecting which trait description to view.


var totalTraits = 0;
function Window_Traits() {
    this.initialize.apply(this, arguments);
}

Window_Traits.prototype = Object.create(Window_Command.prototype);
Window_Traits.prototype.constructor = Window_Traits;

Window_Traits.prototype.initialize = function() {
    Window_Command.prototype.initialize.call(this, 0, 0);
    var width = this.windowWidth();
    var Height = this.windowHeight();
    //this.openness = 0;
    //this.open();
};

Window_Traits.prototype.windowWidth = function() {
    return 240;
};

Window_Traits.prototype.windowHeight = function() {
    return this.fittingHeight(4);
};

Window_Traits.prototype.makeCommandList = function() {
    totalTraits = 0;
    this.addCommand("back", 'back', true);
    totalTraits ++;
    if ($gameSwitches.value(11) === true) {
        this.addCommand("Articulate", 'articulate', true);
        totalTraits ++;
    }
    if ($gameSwitches.value(12) === true) {
        this.addCommand("Campaigner", 'campaigner', true);
        totalTraits ++;
    }
    if ($gameSwitches.value(13) === true) {
        this.addCommand("Generous", 'generous', true);
        totalTraits ++;
    }
}

Window_Traits.prototype.select = function (index) {
    Window_Selectable.prototype.select.call(this, index);
    this.updateTraitDesc();
};

var number = 0;
Window_Traits.prototype.updateTraitDesc = function() {
    number++;
    this._traitDescWindow.setText(currentSymbol());
    this._traitDescWindow.refresh();
};

Scene_Menu.prototype.activateTraitsWindow = function () {
    this._traitsWindow.activate();
}

Scene_Menu.prototype.deactivateTraitsWindow = function () {
    this._commandWindow.activate();
}

//////////////////////////////////////////////////////////////////////////////////////////////
// Window_Trait_Desc
//
// The window displaying trait descriptions.

function Window_Trait_Desc() {
    this.initialize.apply(this, arguments);
}

Window_Trait_Desc.prototype = Object.create(Window_Help.prototype);
Window_Trait_Desc.prototype.constructor = Window_Trait_Desc;

Window_Trait_Desc.prototype.initialize = function(x, y) {
    var width = this.windowWidth();
    var Height = this.windowHeight();
    Window_Base.prototype.initialize.call(this, x, y, width, Height);
};

Window_Trait_Desc.prototype.windowWidth = function() {
    return 480;
};

Window_Trait_Desc.prototype.windowHeight = function() {
    return 200;
};
I've also been playing with a bunch of different combinations of changes. Right now, changing Window_Traits.prototype.select to Window_Help.prototype.select works.
However, while this change does prevent the error from popping up, it fails to actually print anything to the description window.

Another possible change is doing both Window_Traits.prototype.select to Window_Help.prototype.select AND turning Window_Trait_Desc into a child of Window_Help . However, this has the same issue in that nothing gets printed. AND the window is now the wrong shape due to having to use a different initialize
 
Last edited:

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
For the error, there's a mistake:
currentSymbol()
should be
this.currentSymbol()

Try that first. If it doesn't get rid of the error, go ahead and wrap that part with a conditional check for truthy.
Like this:

Code:
var number = 0;
Window_Traits.prototype.updateTraitDesc = function() {
   number++;
   if(this._traitDescWindow) {
      this._traitDescWindow.setText(this.currentSymbol());
   }
   //this._traitDescWindow.refresh(); // refresh is already included in setText we don't need it again
};
Right now, changing Window_Traits.prototype.select to Window_Help.prototype.select works.
However, while this change does prevent the error from popping up, it fails to actually print anything to the description window.
Of course this won't print anything, gotta understand conceptually what this is doing.
If you define a 'select' method on Window_Help, your custom window Window_Trait_Desc will inherit it. But this doesn't do anything for you. The Window_Trait_Desc window is never selecting anything, there's never a cursor over there. You only are selecting and moving the cursor on your Window_Traits.

That's why you have to define the 'select' method on the Window_Traits prototype.
 

TragicNumberOne

Veteran
Veteran
Joined
Feb 9, 2018
Messages
32
Reaction score
3
First Language
English
Primarily Uses
RMMV
For the error, there's a mistake:
currentSymbol()
should be
this.currentSymbol()

Try that first. If it doesn't get rid of the error, go ahead and wrap that part with a conditional check for truthy.
Like this:

Code:
var number = 0;
Window_Traits.prototype.updateTraitDesc = function() {
   number++;
   if(this._traitDescWindow) {
      this._traitDescWindow.setText(this.currentSymbol());
   }
   //this._traitDescWindow.refresh(); // refresh is already included in setText we don't need it again
};

Of course this won't print anything, gotta understand conceptually what this is doing.
If you define a 'select' method on Window_Help, your custom window Window_Trait_Desc will inherit it. But this doesn't do anything for you. The Window_Trait_Desc window is never selecting anything, there's never a cursor over there. You only are selecting and moving the cursor on your Window_Traits.

That's why you have to define the 'select' method on the Window_Traits prototype.
Good news: it works!

Thank you so much for the help, I really appreciate it. I should be able to do everything else on my own from here on it. This one was just really stumping me. Thanks again!
 

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
Awesome! Glad to hear it. Good job pushing through and hopefully you learned something.

If the issue is solved, go ahead and click "report" on the first post and mention that the issue is solved. A moderator will come by and marked the thread as solved.
 

TragicNumberOne

Veteran
Veteran
Joined
Feb 9, 2018
Messages
32
Reaction score
3
First Language
English
Primarily Uses
RMMV
Awesome! Glad to hear it. Good job pushing through and hopefully you learned something.

If the issue is solved, go ahead and click "report" on the first post and mention that the issue is solved. A moderator will come by and marked the thread as solved.
I did (Learn and report the thread). And as I keep saying: thanks for the help!
 

mlogan

Global Moderators
Global Mod
Joined
Mar 18, 2012
Messages
15,354
Reaction score
8,533
First Language
English
Primarily Uses
RMMV

This thread is being closed, due to being solved. If for some reason you would like this thread re-opened, please report this post and leave a message why. Thank you.

 
Status
Not open for further replies.

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

Latest Threads

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,867
Messages
1,017,062
Members
137,575
Latest member
akekaphol101
Top