MAKING YOUR CUSTOM MENU SYSTEM
A basic guide on how to get started when you make a custom menu.
- narcodis
- 12/10/2010 10:47 PM
- 58396 views
DESIGNING YOUR CUSTOM MENU
So you feel like you want to create a custom menu, do ya? Well, first you want to ask yourself, exactly what is it you want to do with this? Is there some feature you don't want to have only accessible through an item? Do you have an idea for a more accessible interface? Do you think you can honestly make something better than RM2k3's default menu?
Ask yourself these questions first. These are important things to know before going into this sort of thing, because it can quickly overwhelm you if you don't have a clear sense of exactly what you want your CMS to do.
Secondly, you need to have a solid understanding of basic RM2k3 event code. If you don't know how variables, switches, conditionals, key inputs, labels, or the show picture command works, take some time and figure out how these things work before trying to tackle something like this.
Thirdly, let's be clear that we're not making a map-based CMS. They're clunky and cause problems. We're going for pictures only.
Alright, now that we have THAT out of the way, let's start off with the basics! I'm going to start a brand new 2k3 project so you can follow along.
So what's going to happen is:
-Create a key detection event
-Design our menu
-Implement the interface
PART ONE: KEY DETECTION.
First things first. We need to create an event that allows us to access our soon-to-be CMS, something that will detect our keystroke. So, open up your common events. Create two events, one called Key Detection, and one called The Menu. Or call them whatever you want, so long as you remember which is which for further reference in this tutorial.
Now, before we get too ahead of ourselves, we need to make sure the player can't access the default menu. So what I like to do is create what I call an 'initializer' event. This event is an auto-start event, and erases itself at the end, so it never becomes a problem.
First, we're going to disable main menu access.
Second, we're going to turn on a switch, which I'll call 'Key Detection'.
And last, we erase the event.
There, now the player won't be able to access the default menu. No turning back now!
So now on to creating our key detection event. In RM2k3, it's usually best to make sure you have as few parallel processes running at the same time as possible. Our key detection event is going to be one of them.
So go back to our common events. Go to Key Detection, make it Parallel Process, and make the trigger switch the switch we turned on with our 'initializer' event .
Alright, step one:
Enter a Key Input Processing line that DOES wait for the key to be pressed before going (very important), and stores the value into a variable called . Make it detect whatever key you want to be used to access your menu. I'm going to use the 'Cancel' key, which has a value of 6.
Step two:
Create a conditional branch for when the variable 'Keystroke' is equal to 6.
Step three:
Inside the conditional branch, call the common event, 'The Menu', set the variable Keystroke to 0, and 'End Event Processing'.
In the end, your code should look something like this:
I put a 'Wait: 0.0 Sec' at the end for good measure. I'm not sure it actually does anything at all, but I hear it helps with potential lag problems that arise from a parallel process event running constantly.
EDIT: Apparently the added 'Wait: 0.0 Sec" function really doesn't do anything at all.
So now we've successfully created an event that will constantly check for when you press the cancel key, and then call our Menu event! So far so good.
PART TWO: DESIGNING THE MENU
Alright, this part is where precise planning starts coming into play. I'm going to give my menu six different options. ITEM, EQUIP, MAGIC, STATUS, SAVE, and QUIT. These are all pretty arbitrary values, as I'm not really going to go into making any of these options functional.
So, since I have six options, I'm going to organize them into a neat two columns and three rows. It's important you make each menu option the same size. Well, I suppose you don't have to, but it will just make life easier for us when we go to code the menu itself. So I'm going to make my menu 200x120, making each option 100 wide and 40 tall.
It will look something like this:
(Hopefully yours will look like even an ounce of effort was put into it)
And while you're at it, design a nice cursor to go along with our menu. I'm simply going to make a nice yellow rectangle, to serve as sort of a highlighter for the menu options.
So now we've got our menu. Pretty easy! But here is where it starts to get tricky.
PART THREE: IMPLEMENTATION (Really, what the tutorial is for)
Alright, so back to our common events. Go to the one we so aptly named 'The Menu'. Make sure this one stays as a 'Call' event, with no switch to trigger it.
The idea is that we don't want any more parallel process events, since they do a number on most processors. But we're still going to loop this event over and over using labels. The menu event will consist of two parts. First, we will show the cursor and the menu itself. We need to determine where both items need to be. The second part will be another key detection code.
So lets make a flow chart.
THE MENU
The places it says "break" means this is where we'll make the event come to a halt. So here, if the player ever presses enter or cancel, our Menu event will come to an end. Otherwise, we're going to loop back to label 1 and repeat the whole thing over again. This is going to be a basic model for how we'll structure our code from here on out.
Alright, so the first part. To disable Hero control, create a "Move Event" command that moves the hero, with nothing but a "Wait" command, and set it to repeat endlessly. This will prevent the hero from moving around while our menu is open.
After that, Lets make the menu picture 1 and the cursor picture 2.Let's show the menu at 160,120. Make sure the picture does NOT use a transparent color and does NOT scroll with the map. This is the center of the screen and the coordinates that show up by default when using a show picture command.
Next, we need to figure out where the cursor is going to go. But lets not get too ahead of ourselves. First we need to define what each part of the menu is.
As you can see, I've marked each menu option with a number. Item will be 1, Equip will be 2, etc. So, lets make a new variable, called "Cursor Position", and set it to 1.
Remember, we're following the flowchart I made earlier. So according to that, right here we need to put a label, Label 1. We'll use it later.
Now we'll make a series of 6 conditional branches, one for each menu option, each determined by what number the variable 0002:Cursor Position is. If it is 1, if it is 2, ..., and if it is 6.
Your code should look something like this up to this point:
Alright, so now we need to determine exactly where our cursor needs to go. Since my cursor is nothing more than a highlighter, I need to determine the exact center spot of each option on the menu. This is a strenuous process, and I really don't think I've found the most efficient way of doing this, but if you don't have any tricky gadgets or anything to determine coordinates for you, this has to be done. Try to keep up here, now.
EDIT: Darken pointed out that there is a program that serves as a picture coordinator out there, so if you want, you can skip all this stuff about finding coordinates and such and just use this tool. But I'm keeping the coordinate finding info here for good measure. Download link here. http://rpgmaker.net/users/Darken/locker/ImagePositioner.exe
On the menu image itself, the center spot is 100,60 (remember, this is different than the actual coordinates we put into RM2k3). I've also determined that the center point on each menu item is as follows:
1.ITEM: 50,20
2.EQUIP: 50,60
3.MAGIC: 50,100
4.STATUS: 150,20
5.SAVE: 150,60
6.QUIT: 150,100
Now that we have the coordinates of each menu item on the menu image itself, we can now start to determine what the RM2k3 coordinates the cursor will need for each option. For this, we use some basic math, step by step.
The 2k3 coordinates of the menu are 160,120.
The Menu's center point is 100,60.
The difference is +60,+60.
Apply that to each option on our menu.
1. 50,20 = 110,80
2. 50,60 = 110,120
3. 50,100 = 110,160
4. 150,20 = 210,80
5. 150,60 = 210,120
6. 150,100 = 210,160
And we're done! If my math is right, those should be the exact coordinates of my cursor in each position. Easy shmeasy.
So lets go back to our code. Place a Show Picture(2) command for the cursor with the coordinates given for each corresponding conditional branch. Again, make sure it doesn't scroll with the map, and with this particular highlighter-type cursor, make sure it's transparent. Your code should look like this after all is said and done:
EDIT: Instead of having the show picture command for the cursor each time, it would be better to show the picture along with the menu, and simply move the cursor's picture to each position with a 0.0 wait time instead, in order to optimize performance. Thanks, Kazesui!
Alright, now on to part two of our flowchart. The Key detection. Much like our Key detection event from earlier on, except this time, we will mark the box that says "wait until key pressed", because we will be waiting for an input from the player. You can go ahead and re-use the variable Keystroke. We will also mark the keys Down, Left, Right, Up, Decision, and Cancel for processing.
Immediately after the KeyInputProcessing code, make another 6 conditional branches, each with the condition that the variable Keystroke is equal to a number 1, 2, 3, 4, 5, and 6, respectively, which will cover all our bases for whatever key the player presses.
The first four numbers will be the arrow keys:
1 is Down
2 is Left
3 is Right
4 is Up
The Down/1 and Up/4 conditions will work relatively the same. For down, we're going to add 1 to the 0002:Cursor Position variable. For Up, we'll subtract 1.
However, we need to take measures to make sure the variable doesn't go higher than 6 and less than one. So in the Down/1 conditional branch, make a safety net. Make another conditional branch for when 0002:Cursor Position is greater than 6, and within that, set 0002:Cursor Position to 1. Do the same for the Up/4 conditional branch, only making it so it doesn't go less than one, and if it does, set the variable as 6.
Still with me?
Alright, so with the Left/2 condition, we'll be subtracting 3 from Cursor Position, and with the Right/3 condition, we will be adding 3. We will make another safety net, except instead of setting the cursor position as a flat value, we will add or subtract 6.
So with Left/2:
Subrtract 3
If CursorPosition is < 1: Add 6
And with Right/3:
Add 3
If CursorPosition is > 1: Subtract 6
This will make it so the cursor goes horizontally across the menu when you press left or right.
At the end of every conditional branch we've just made, place a "Jump to Label", each one directing to Label 1. This will make sure the menu event continues.
Alright, your code should look something like this up to this point:
Okay! Almost done. Now to code in the conditions for a Decision or Cancel keypress.
For the decision keypress, you'll need to sort of figure out what you'll do with each menu option on your own. But basically you'll create a series of conditional branches within the conditional branch for the decision keypress (If Keystroke = 5) for each position the cursor could be in.
For example, within the Conditional for Keystroke=5, there will be a conditional for If Cursor Position = (1,2,3,4,5 or 6).
When Cursor Position is equal to 5 (our "SAVE" option), you could simply call the SAVE menu.
That's simply an example of what can be done. Ideally you'll have a separate menu for the ITEM, EQUIP, MAGIC, and STATUS options, but I'm not going to go quite into that much detail in this tutorial. You will probably want to erase the menu and things like that, but I'm sure you can get that.
For the Cancel keypress condition (If Keystroke=6), simply Erase pictures 1 and 2, Move Event Hero: Wait (NOT repeating this time), and then End Event Processing.
So lets look at our code.
This is it! This is the end of our code. This should give you a basic framework for making your own menu system.
Let's see how it looks in action.
Damn, is that ugly. Oh well. At least it's functional!
Enjoy! Let me know if you have questions or need clarification. I'm more than happy to make adjustments to the tutorial.
So you feel like you want to create a custom menu, do ya? Well, first you want to ask yourself, exactly what is it you want to do with this? Is there some feature you don't want to have only accessible through an item? Do you have an idea for a more accessible interface? Do you think you can honestly make something better than RM2k3's default menu?
Ask yourself these questions first. These are important things to know before going into this sort of thing, because it can quickly overwhelm you if you don't have a clear sense of exactly what you want your CMS to do.
Secondly, you need to have a solid understanding of basic RM2k3 event code. If you don't know how variables, switches, conditionals, key inputs, labels, or the show picture command works, take some time and figure out how these things work before trying to tackle something like this.
Thirdly, let's be clear that we're not making a map-based CMS. They're clunky and cause problems. We're going for pictures only.
Alright, now that we have THAT out of the way, let's start off with the basics! I'm going to start a brand new 2k3 project so you can follow along.
So what's going to happen is:
-Create a key detection event
-Design our menu
-Implement the interface
PART ONE: KEY DETECTION.
First things first. We need to create an event that allows us to access our soon-to-be CMS, something that will detect our keystroke. So, open up your common events. Create two events, one called Key Detection, and one called The Menu. Or call them whatever you want, so long as you remember which is which for further reference in this tutorial.
Now, before we get too ahead of ourselves, we need to make sure the player can't access the default menu. So what I like to do is create what I call an 'initializer' event. This event is an auto-start event, and erases itself at the end, so it never becomes a problem.
First, we're going to disable main menu access.
Main Menu Access: Forbid
Second, we're going to turn on a switch, which I'll call 'Key Detection'.
Switch Operation: [0001:Key Detection] ON
And last, we erase the event.
Erase Event
There, now the player won't be able to access the default menu. No turning back now!
So now on to creating our key detection event. In RM2k3, it's usually best to make sure you have as few parallel processes running at the same time as possible. Our key detection event is going to be one of them.
So go back to our common events. Go to Key Detection, make it Parallel Process, and make the trigger switch the switch we turned on with our 'initializer' event .
Alright, step one:
Enter a Key Input Processing line that DOES wait for the key to be pressed before going (very important), and stores the value into a variable called . Make it detect whatever key you want to be used to access your menu. I'm going to use the 'Cancel' key, which has a value of 6.
Step two:
Create a conditional branch for when the variable 'Keystroke' is equal to 6.
Step three:
Inside the conditional branch, call the common event, 'The Menu', set the variable Keystroke to 0, and 'End Event Processing'.
In the end, your code should look something like this:
I put a 'Wait: 0.0 Sec' at the end for good measure. I'm not sure it actually does anything at all, but I hear it helps with potential lag problems that arise from a parallel process event running constantly.
EDIT: Apparently the added 'Wait: 0.0 Sec" function really doesn't do anything at all.
So now we've successfully created an event that will constantly check for when you press the cancel key, and then call our Menu event! So far so good.
PART TWO: DESIGNING THE MENU
Alright, this part is where precise planning starts coming into play. I'm going to give my menu six different options. ITEM, EQUIP, MAGIC, STATUS, SAVE, and QUIT. These are all pretty arbitrary values, as I'm not really going to go into making any of these options functional.
So, since I have six options, I'm going to organize them into a neat two columns and three rows. It's important you make each menu option the same size. Well, I suppose you don't have to, but it will just make life easier for us when we go to code the menu itself. So I'm going to make my menu 200x120, making each option 100 wide and 40 tall.
It will look something like this:
(Hopefully yours will look like even an ounce of effort was put into it)
And while you're at it, design a nice cursor to go along with our menu. I'm simply going to make a nice yellow rectangle, to serve as sort of a highlighter for the menu options.
So now we've got our menu. Pretty easy! But here is where it starts to get tricky.
PART THREE: IMPLEMENTATION (Really, what the tutorial is for)
Alright, so back to our common events. Go to the one we so aptly named 'The Menu'. Make sure this one stays as a 'Call' event, with no switch to trigger it.
The idea is that we don't want any more parallel process events, since they do a number on most processors. But we're still going to loop this event over and over using labels. The menu event will consist of two parts. First, we will show the cursor and the menu itself. We need to determine where both items need to be. The second part will be another key detection code.
So lets make a flow chart.
THE MENU
Disable Hero control
Show Menu image
Define default cursor position
Label 1
Establish where cursor will go
-Position 1, 2, 3, 4, 5, 6
Show cursor image
Key detection
-Keypress up, down, left, right
--Define cursor position
-Keypress enter (break)
-Keypress cancel (break)
Goto Label 1
The places it says "break" means this is where we'll make the event come to a halt. So here, if the player ever presses enter or cancel, our Menu event will come to an end. Otherwise, we're going to loop back to label 1 and repeat the whole thing over again. This is going to be a basic model for how we'll structure our code from here on out.
Alright, so the first part. To disable Hero control, create a "Move Event" command that moves the hero, with nothing but a "Wait" command, and set it to repeat endlessly. This will prevent the hero from moving around while our menu is open.
After that, Lets make the menu picture 1 and the cursor picture 2.Let's show the menu at 160,120. Make sure the picture does NOT use a transparent color and does NOT scroll with the map. This is the center of the screen and the coordinates that show up by default when using a show picture command.
Next, we need to figure out where the cursor is going to go. But lets not get too ahead of ourselves. First we need to define what each part of the menu is.
As you can see, I've marked each menu option with a number. Item will be 1, Equip will be 2, etc. So, lets make a new variable, called "Cursor Position", and set it to 1.
Remember, we're following the flowchart I made earlier. So according to that, right here we need to put a label, Label 1. We'll use it later.
Now we'll make a series of 6 conditional branches, one for each menu option, each determined by what number the variable 0002:Cursor Position is. If it is 1, if it is 2, ..., and if it is 6.
Your code should look something like this up to this point:
Alright, so now we need to determine exactly where our cursor needs to go. Since my cursor is nothing more than a highlighter, I need to determine the exact center spot of each option on the menu. This is a strenuous process, and I really don't think I've found the most efficient way of doing this, but if you don't have any tricky gadgets or anything to determine coordinates for you, this has to be done. Try to keep up here, now.
EDIT: Darken pointed out that there is a program that serves as a picture coordinator out there, so if you want, you can skip all this stuff about finding coordinates and such and just use this tool. But I'm keeping the coordinate finding info here for good measure. Download link here. http://rpgmaker.net/users/Darken/locker/ImagePositioner.exe
On the menu image itself, the center spot is 100,60 (remember, this is different than the actual coordinates we put into RM2k3). I've also determined that the center point on each menu item is as follows:
1.ITEM: 50,20
2.EQUIP: 50,60
3.MAGIC: 50,100
4.STATUS: 150,20
5.SAVE: 150,60
6.QUIT: 150,100
Now that we have the coordinates of each menu item on the menu image itself, we can now start to determine what the RM2k3 coordinates the cursor will need for each option. For this, we use some basic math, step by step.
The 2k3 coordinates of the menu are 160,120.
The Menu's center point is 100,60.
The difference is +60,+60.
Apply that to each option on our menu.
1. 50,20 = 110,80
2. 50,60 = 110,120
3. 50,100 = 110,160
4. 150,20 = 210,80
5. 150,60 = 210,120
6. 150,100 = 210,160
And we're done! If my math is right, those should be the exact coordinates of my cursor in each position. Easy shmeasy.
So lets go back to our code. Place a Show Picture(2) command for the cursor with the coordinates given for each corresponding conditional branch. Again, make sure it doesn't scroll with the map, and with this particular highlighter-type cursor, make sure it's transparent. Your code should look like this after all is said and done:
EDIT: Instead of having the show picture command for the cursor each time, it would be better to show the picture along with the menu, and simply move the cursor's picture to each position with a 0.0 wait time instead, in order to optimize performance. Thanks, Kazesui!
Alright, now on to part two of our flowchart. The Key detection. Much like our Key detection event from earlier on, except this time, we will mark the box that says "wait until key pressed", because we will be waiting for an input from the player. You can go ahead and re-use the variable Keystroke. We will also mark the keys Down, Left, Right, Up, Decision, and Cancel for processing.
Immediately after the KeyInputProcessing code, make another 6 conditional branches, each with the condition that the variable Keystroke is equal to a number 1, 2, 3, 4, 5, and 6, respectively, which will cover all our bases for whatever key the player presses.
The first four numbers will be the arrow keys:
1 is Down
2 is Left
3 is Right
4 is Up
The Down/1 and Up/4 conditions will work relatively the same. For down, we're going to add 1 to the 0002:Cursor Position variable. For Up, we'll subtract 1.
However, we need to take measures to make sure the variable doesn't go higher than 6 and less than one. So in the Down/1 conditional branch, make a safety net. Make another conditional branch for when 0002:Cursor Position is greater than 6, and within that, set 0002:Cursor Position to 1. Do the same for the Up/4 conditional branch, only making it so it doesn't go less than one, and if it does, set the variable as 6.
Still with me?
Alright, so with the Left/2 condition, we'll be subtracting 3 from Cursor Position, and with the Right/3 condition, we will be adding 3. We will make another safety net, except instead of setting the cursor position as a flat value, we will add or subtract 6.
So with Left/2:
Subrtract 3
If CursorPosition is < 1: Add 6
And with Right/3:
Add 3
If CursorPosition is > 1: Subtract 6
This will make it so the cursor goes horizontally across the menu when you press left or right.
At the end of every conditional branch we've just made, place a "Jump to Label", each one directing to Label 1. This will make sure the menu event continues.
Alright, your code should look something like this up to this point:
Okay! Almost done. Now to code in the conditions for a Decision or Cancel keypress.
For the decision keypress, you'll need to sort of figure out what you'll do with each menu option on your own. But basically you'll create a series of conditional branches within the conditional branch for the decision keypress (If Keystroke = 5) for each position the cursor could be in.
For example, within the Conditional for Keystroke=5, there will be a conditional for If Cursor Position = (1,2,3,4,5 or 6).
When Cursor Position is equal to 5 (our "SAVE" option), you could simply call the SAVE menu.
That's simply an example of what can be done. Ideally you'll have a separate menu for the ITEM, EQUIP, MAGIC, and STATUS options, but I'm not going to go quite into that much detail in this tutorial. You will probably want to erase the menu and things like that, but I'm sure you can get that.
For the Cancel keypress condition (If Keystroke=6), simply Erase pictures 1 and 2, Move Event Hero: Wait (NOT repeating this time), and then End Event Processing.
So lets look at our code.
This is it! This is the end of our code. This should give you a basic framework for making your own menu system.
Let's see how it looks in action.
Damn, is that ugly. Oh well. At least it's functional!
Enjoy! Let me know if you have questions or need clarification. I'm more than happy to make adjustments to the tutorial.
Posts
author=Link_2112
Forgot about this. Still having trouble?
Try making a new page and recreating the event. It might work. Try putting the key input stuff at the top, followed by the code to determine cursor placement, with picture displays at the end. That's typically how I set them up.
I don't have that version so likely can't open it.
Not anymore. Somebody fixed it for me.
Sorry to post in such an old thread, but I have a custom menu in place that I made a long time ago. I recently added spawnable monsters that initiate battle with you on contact. I tried making the menu an auto start event to stop them from moving, but when I do the game lags horribly. I made sure to use waits and move pic instead of show pic where necessary, but it still lags if it is auto start. Anyone know what the issue might be?
I realize this tutorial is fairly old, but there's a fatal flaw here. You use a Move Event command with a repeated Wait to halt the player's movement, but this doesn't affect other potential moving events on your map. So if you have, say, moving enemies on your map that start a battle when they touch you, and you're in the menu, shit goes wrong.
I feel like making the menu Auto Start is the best way to resolve this, but some people have indicated lag. I'll do some experimenting.
I feel like making the menu Auto Start is the best way to resolve this, but some people have indicated lag. I'll do some experimenting.
author=JustRob
I realize this tutorial is fairly old, but there's a fatal flaw here. You use a Move Event command with a repeated Wait to halt the player's movement, but this doesn't affect other potential moving events on your map. So if you have, say, moving enemies on your map that start a battle when they touch you, and you're in the menu, shit goes wrong.
I feel like making the menu Auto Start is the best way to resolve this, but some people have indicated lag. I'll do some experimenting.
I have a custom menu of sorts and I use auto start, and there is no lag. Just draw all the images separately, then put the key input proc in an auto start that checks for whatever's pressed, then put a label to jump back to the key input proc after each conditional branch.
author=JustRob
I realize this tutorial is fairly old, but there's a fatal flaw here. You use a Move Event command with a repeated Wait to halt the player's movement, but this doesn't affect other potential moving events on your map. So if you have, say, moving enemies on your map that start a battle when they touch you, and you're in the menu, shit goes wrong.
I feel like making the menu Auto Start is the best way to resolve this, but some people have indicated lag. I'll do some experimenting.
It's been a long time since I wrote this tutorial (over seven years, holy heck). There are definitely multiple ways to do things, and I definitely recommend you do what works best for you! In custom menus I've designed in the past, I activate a switch to indicate the menu is open. If there's an event I also want halted, I add a blank event page activated by that menu switch to the event I want halted. You might not want ALL events to halt when you open your menu. But maybe you do!
I know there have been a lot of extremely significant changes made to the RM2k3 editor and runtime engine since its english release, so I guarantee almost all the information in this tutorial is pretty well out of date. Hope it was at least a bit helpful to you, though!