Group: +Gold Member
Posts: 1,521
Type: Scripter
RM Skill: Undisclosed
The Script Builders' Tutorials: ----Lesson 4: Command Windows----
I. Introduction II. The Window Creation Story III. Creating a Window_Command IV. Showing a Window_Command V. Making a child of the Command Window with Icons. VI. Showing our Child VII. Conclusion VIII. Homework
I. Introduction
Welcome to the fourth lesson by the Script Builders. So far we've looked at Basic Windows, Selectable Windows, Debugging Windows, and Advanced Windows. Today I'm going to be writing about the wonderful world of Command Windows.
Command Windows are a type of selectable windows. You can think of them as a child of the Selectable Window Class much like how the Selectable Window class is a child of the Window Base Class. Command Windows are generally a lot easier to use, due to their rigid nature. You basically input your commands, can move it if you need to, and it will work exactly as you expect. It will draw the options at the correct intervals, and fixes bits we found difficult earlier in selectable windows. Selectable Windows, are a lot more flexible, and let you have windows exactly how you want, but you have to define exactly how you want everything, and is kinda overkill for the simple windows that we were making last time.
With Command Windows we'll be looking at how to make one, how to create a child of one, and how to insert icons into our child one.
So without further ado, a refresher of The Window Creation Story:
II. The Window Creation Story
You may recall from the first tutorial, that there was a grandfather named Window, who had his children Window_Base and Window_Selectable. Today we'll be looking at Window_Selectable's first born child, Window_Command. Window_Command is lucky, it's quite far down the tree, and can inherit all his father's, grandfather's, and grandmother's methods (such as initialize, update, dispose, draw_picture, draw_actor_hp, etc). Since it can inherit all this, the code for Window_Command is quite small and very easy to use
III. Creating a Window_Command
This is the fun bit! Making a Command Window is easy. What I'll ask you to do is go into your script editor and have a look at Window_Command. I'm doing this so when I initialize or create one, I know what inputs I need to make, and know what new methods I can use.
Big Image
Inside are 4 methods, the first being initialize, which needs two inputs: the width of the command window, and the array of commands. I'm assuming that there are quite a few blank stares when I mention arrays, so I'll make a spoiler, and give a quick overview as to what an array is:
Overview of Arrays
Arrays are amazingly useful, think of them as an infinitely long line of pockets. In the first pocket (pocket 0) you can store your name In the second pocket (pocket 1) you can store your age. In the third pocket (pocket 2) you can store your pet's names. In the fourth pocket (pocket 3), you can store your hero's name. In the fifth pocket (pocket 4), you can store your hero's level. Basically, you can store just about anything inside your pockets, for the entire length of infinity (or until you run out of RAM). Why do we do this? Well for one, it's easier to organize all your data for hero 1 in one array, and all the data for enemy 1 in another array. For two, it's a lot easier to edit mass amounts of data if they're in arrays
If I were to create a normal variable, named night_runners_variable, and told it to hold the value 32, the syntax would be: night_runners_variable = 32
If I were to create an array, named night_runners_array, and told it to hold my name, age, and my oldest pets name, the syntax would be: night_runners_array = ["Night_Runner", 20, "Puppy"]
If you want to find out what my oldest pets name (the third item, but pocket 2) is, then night_runners_array[2] Would return "Puppy", so if you went back into the first tutorial, made that array, and make a command: self.contents.draw_text(150, 0, 100, 100, night_runners_array[2]) it would write 'Puppy' in which you can also write night_runners_array[0] which would draw 'Night_Runner'
Most people may not have been there, but we actually have a topic which has links to all our tutorials as well as links to some introductions to RGSS. One is by RPG called RGSS for Dummies, which go over things like variables, arrays, the print command, methods, and classes which are useful in situations like this, but by themselves, don't show the practical applications of scripting in RPG Maker. If you want to head over to The Script Builders - Recruitment Page, it has these tutorials linked, which I point out if you would like an explanation from another perspective.
Now on to making the actual Command Window, itself. Make a new script, and we'll call it My_Window_Command.
CODE
#============================================================================== # ** My_Window_Command #------------------------------------------------------------------------------ # This method will create a command window, and store the result in a variable. #==============================================================================
class Interpreter def my_command_window # For conventions sake, we'll define all the strings first: s1 = "Yes" s2 = "No" s3 = "Maybe" s4 = "I don't know" # And here we make the Window_Command. # = Window_Command.new(width, array_of_commands) @window = Window_Command.new(200, [s1, s2, s3, s4]) # Loop the following loop do # Update the graphics Graphics.update # Check the inputs Input.update # Update the Command_Window @window.update # Break the loop if the player presses C break if Input.trigger?(Input::C) end Input.update $game_variables[2] = @window.index @window.dispose end end
We always start with the comments up at the top: naming our script and giving a brief description of what we intend it to do. In this case, making a command window.
The Class is the interpreter, which holds all the evented commands like "Show Text", "Start Battle Processing", and so on, and we're going to use this because all events have simple access to our window (as shown later).
The def my_command_window is making a command (like draw_text), which the event will call.
Onto the actual coding which I'm introducing it in the same style RPG Maker uses, which is define all the commands first. So we're storing the string "Yes" in s1, "No" in s2, "Maybe" in s3, and "I don't know" in s4 so everything is setup to make the command window. The first input in the Window_Command.new is the width of the command window, and then the second input is the array of commands.
That is pretty much all you need to make a command window. This next section is to be covered in the next tutorial, and can be summarized as updating the Graphics, Input, and our window, but if you want more detail, I'll go over it here:
Next we want to make it continuously update the Graphics, the Input, and the command window, and to break out of the loop if the player has selected their option. The loop do is the same as the evented loop, it will just keep doing what's inside itself until you break out. Graphics.update updates the image on the screen, so if you pressed down, it needs to show the second item being highlighted. Input.update updates the input, checking to see if any of the keys are being pressed. @window.update updates the window, checks where the highlighted option should be, etc. break if Input.trigger?(Input::C) says break out of the loop if the player has just started pressing the C button. If you replace trigger with press, you need to have held it down last time we checked, and still being pressed this time. I make the distinction because we do a Input.update as soon as we leave the loop, just to let the system know that the Input.trigger was used already to escape the loop.
$game_variables[2] = @window.index sets in in-game variable 2 to the index of the selected option, just a simple way to let our events interact with your chosen result, and @window.dispose gets rid of the window.
Please do keep in mind, to make the command window is easy, all you need is @window_name = Command_Window.new(width, ['Option 1', 'Option 2', 'Option 3', 'Option 4']), and to update it every frame. The rest is shared code that everything will use, and will be discussed in the next tutorial, so try not to worry too much about it.
With all that learning behind us, let us now show our window!
IV. Showing a Window_Command
Lovely, so now onto making the event show the window, which I promise is easy. Since we used the Interpreter for our class, have an event run the code
and it will refer to the bit of code we just made, making the window, getting the option, and returning it in the in-game variable Fiddle around with this before you move on, try using things like your @window.x = (640-@window.width)/2 to centre the window, change the back opacity, things from previous tutorials to psych yourself up for this next bit
V. Making a child of the Command Window with Icons
Okay, in this section we will be going through an example problem, and make our own type of command window as the solution.
In the last section, we made a window with four options. We want to give these options icons associated with them, based on their number, not their specific text. The first option (index 0) is to have the icon '048-Skill05' The second option (index 1) is to have the icon '047-Skill04' The third option (index 2) is to have the icon '046-Skill03' The fourth option (index 3) is to have the icon '049-Skill06' You are to create a child of the command window which has these icons
In The Law's last tutorial, he taught you all how to make icons, using the draw_picture command, we want to make something similar, but this one will change for each input.
Something to note, our window will be a child of window_command, which is awesome because we only need to code up what we want changed from our father (window_command), so everything we don't want to change, such as initialize, update, etc, doesn't need to be mentioned, and will be inherited from Command_Window.
Things that we do want changed though, we need to re-code up. We want to have an icon for each option, so we need to edit whatever is drawing the options text, and we'll need to edit the drawing of the text itself to allow some room for the icons....
After careful inspection, we need to edit refresh. We'll also edit draw_item so that we have some room to draw the icons in.
So insert a new scripting page, write up the name of your window, a description of what it's meant to do, and hopefully if I asked you to copy refresh and draw_item out of Window_Command and into our new script, you would be happy to edit the draw_item to start at about 32 pixels across.
Try this yourself, first, use what The Law taught you last time to draw just an icon, in this blank template (copied straight from Window_Command) for the skeleton code:
CODE
#============================================================================== # ** Window_Command_Icons #------------------------------------------------------------------------------ # This window is a type of Command Window, which we will be using to # make command windows with icons! #==============================================================================
class Window_Command_Icons < Window_Command #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max draw_item(i, normal_color) end end #-------------------------------------------------------------------------- # * Draw Item # index : item number # color : text color #-------------------------------------------------------------------------- def draw_item(index, color) self.contents.font.color = color rect = Rect.new(4, 32 * index, self.contents.width - 8, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.draw_text(rect, @commands[index]) end end
- A few hints for those still reading here, we need to make a new method, mine's called draw_icon, and we need the refresh to show it with the draw_item. - We need to redefine draw_item so that the command can be drawn 28 pixels to the right of where it normally is. - Have the Law's tutorial open in another tab, it'll help - You will need to know how an if statement works:
CODE
x = rand(20) # Make x a random variable, between 0 and 20 if x == 0 # If x is equal to 0 print "Thats young!" elsif x <= 5 # If x is between 1 - 5 (inclusive) print "Its between 1 and 5" end # End if if x < 15 # If x is less than 15 (not inclusive) print "Youre fourteen and under" else # # If the last condition is not satisfied. print "Youre fifteen and over" end # End if
Welcome back, hopefully you managed to do the first couple of points, and with the help of the last tutorial, fingers crossed you managed to get a chunk of the icon method done
Your final code could look nothing like this, but hopefully works the same as:
CODE
#============================================================================== # ** Window_Command_Icons #------------------------------------------------------------------------------ # This window is a type of Command Window, which we will be using to # make command windows with icons! #==============================================================================
class Window_Command_Icons < Window_Command #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max draw_item(i, normal_color) # Draw the icon associated with the index. draw_icon(i) end end #-------------------------------------------------------------------------- # * Draw Item # index : item number # color : text color #-------------------------------------------------------------------------- def draw_item(index, color) self.contents.font.color = color # rect = Rect.new(x, y, width, height) Note the x is 32, not the default 4. rect = Rect.new(32, 32 * index, self.contents.width - 8, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.draw_text(rect, @commands[index]) end #-------------------------------------------------------------------------- # * Draw Icon # index : item number #-------------------------------------------------------------------------- def draw_icon(index) # A case statement looks at the input, in this case index. case index # If the index is equal to 0: when 0 # Set the icon name to '048-Skill05' icon = '048-Skill05' when 1 icon = '047-Skill04' when 2 icon = '046-Skill03' when 3 icon = '049-Skill06' # If there are more than 4 commands: else # Don't draw anything. icon = '' end # Create the bitmap image for the icon, defined above bitmap = RPG::Cache.icon(icon) # Make the rectangle for the image to be in src_rect = Rect.new(0, 0, bitmap.width, bitmap.height) # Draw the bitmap inside the rectangle, at 4 pixels across, # and down according to the index self.contents.blt(4, 32*index+5, bitmap, src_rect) end end
As you can see, I called mine Window_Command_Icons. Under refresh, by default, it draws the item (the string / command name), and I've got it drawing an icon while it's there.
The draw_icon method I've made has a new command, the case statement. Basically, we only want this window to be called by the "Yes", "No", "Maybe", "I don't know" script we made earlier, otherwise we'd want a second input, something like
CODE
def draw_icon(index, icon_name)
to tell us what icon to draw, but we're keeping it simple, it's only called with "Yes", "No", etc, so we know which icon to draw with each index.
Enough of that, back to case statements. The case block is useful for people who don't want to do if statements for the same thing several times, so instead of doing:
CODE
if index == 0 icon = .... if index == 1 icon = ...
We can say
CODE
case icon
and every time we make reference to when, it's checking if index is equal to whatever is after the when, and then running the code underneath, just like in an if statement.
The
CODE
bitmap = RPG::Cache.icon(icon)
at the bottom, is taken almost identically from The Law's last tutorial, if it's confusing, please reread tutorial 3, Advanced Windows.
So, unfortunately, it's not much new, but it's tying together everything you've done so far quite nicely
Now, onto displaying our window!
VI. Showing our Child
Ahh, children grow up so quickly...
We're going to go back into the III. Creating a Window_Command what we made earlier, but this time, instead of
That was quick As you may have noticed, showing command windows is easy, setting them up mostly is just making an array, inputting it into the command window, and making sure to update the Graphics, Input, and the command window itself.
We went over some stuff that's extra-curriculum, like $game_variables, and the Interpreter that I didn't go into quite so much detail for, but bring up because it's useful to know they exist, and I like the connection they bring between the scripting world and the eventing world.
I'd like to point out that at this stage, you guys and girls actually know quite a lot about windows. Even if you need to reread this a few times to grasp some of the trickier concepts, at the moment, I would happily let you run loose in the Script Support section, helping people with their re-arranging of menus, moving of title options, and icon-ating of any window.
And on that note, your homework for tonight:
VIII. Homework
Now, to separate the mice from the men, your homework, if you dare
I want you to make a new Command_Window_Icons (possibly with a different name), which has icon's for New Game, Continue, and Game Over, try not to just edit it, but remake it from scratch and use what you learned in the Debugging tutorial if errors arise.
Just like we did in Part VI., change it to include your icons. And if you want advanced homework, go into Scene_Menu and do the same for the @command_window, there.
__________________________
K.I.S.S. Want help with your scripting problems? Upload a demo! Or at the very least; provide links to the scripts in question.
Group: Member
Posts: 11
Type: Mapper
RM Skill: Intermediate
Nice tutorial!
Here's what I'm busy with,
I only need to know if its possible to add a text below which shows the number from a variable,, I tried alot but I cant do it. I would like some hints
Basically, you would use the normal code you would use to draw text. However, in the 5th parameter of the draw_text method, instead of writing a string of text, we would write out what game variable we want to draw. 'x' would represent the number of the variable you want to draw. That make any sense to you?
This post has been edited by The Law G14: Dec 7 2009, 02:10 PM
"When you first come, no one knows you. When help them out, they all know you. When you leave, they all love you. When you come back, they've already forgotten you." -- copy into your sig if you think this quote speaks true!
If you are one of the very few teenagers that know what real rap is and don't blindly listen to the hate statements (rap is crap), then put this in your sig. I say this in the name of Common, Mos Def, Lupe Fiasco, 2Pac, Nas, Talib Kweli, Eminem, and many others. -Exiled One
Basically, you would use the normal code you would use to draw text. However, in the 5th parameter of the draw_text method, instead of writing a string of text, we would write out what game variable we want to draw. 'x' would represent the number of the variable you want to draw. That make any sense to you?
Where should I place it,? I tried using that code but I keep getting an error.
"When you first come, no one knows you. When help them out, they all know you. When you leave, they all love you. When you come back, they've already forgotten you." -- copy into your sig if you think this quote speaks true!
If you are one of the very few teenagers that know what real rap is and don't blindly listen to the hate statements (rap is crap), then put this in your sig. I say this in the name of Common, Mos Def, Lupe Fiasco, 2Pac, Nas, Talib Kweli, Eminem, and many others. -Exiled One
class Window_Command_Icons < Window_Command #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max draw_item(i, normal_color) draw_icon(i) end end #-------------------------------------------------------------------------- # * Draw Item # index : item number # color : text color #-------------------------------------------------------------------------- def draw_item(index, color) self.contents.font.color = color rect = Rect.new(38, 32 * index, self.contents.width - 8, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.draw_text(rect, @commands[index]) self.contents.draw_text(38, 32 * 7, 120, 32, "Location")
end #-------------------------------------------------------------------------- # * Draw Icon # index : item number #-------------------------------------------------------------------------- def draw_icon(index) case index when 0 icon = 'hp up' when 1 icon = 'sp up' when 2 icon = 'str up' when 3 icon = 'dex up' when 4 icon = 'agi up' when 5 icon = 'int up' else icon = '' end bitmap = RPG::Cache.icon(icon) src_rect = Rect.new(0, 0, bitmap.width, bitmap.height) end end
class Interpreter def my_command_window s1 = "Hp" s2 = "Sp" s3 = "Str" s4 = "Dex" s5 = "Agi" s6 = "Int" s7 = "close" @window = Window_Command_Icons.new(200, [s1, s2, s3, s4, s5, s6, s7]) loop do Graphics.update Input.update @window.update break if Input.trigger?(Input::C) end Input.update @window.dispose end end
#============================================================================== # ** Window_Command_Icons #------------------------------------------------------------------------------ # This class takes care of icons in the command window #==============================================================================
class Window_Command_Icons < Window_Command #-------------------------------------------------------------------------- # * Refresh #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max draw_item(i, normal_color) draw_icon(i) end end #-------------------------------------------------------------------------- # * Draw Item # index : item number # color : text color #-------------------------------------------------------------------------- def draw_item(index, color) self.contents.font.color = color rect = Rect.new(38, 32 * index, self.contents.width - 8, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.draw_text(rect, @commands[index]) self.contents.draw_text(38, 32 * 7, 120, 32, "Location") end #-------------------------------------------------------------------------- # * Draw Icon # index : item number #-------------------------------------------------------------------------- def draw_icon(index) case index when 0 icon = 'hp up' when 1 icon = 'sp up' when 2 icon = 'str up' when 3 icon = 'dex up' when 4 icon = 'agi up' when 5 icon = 'int up' else icon = '' end bitmap = RPG::Cache.icon(icon) src_rect = Rect.new(0, 0, bitmap.width, bitmap.height) end end
#============================================================================== # ** Window_Variable #------------------------------------------------------------------------------ # This window displays a variable. #==============================================================================
"When you first come, no one knows you. When help them out, they all know you. When you leave, they all love you. When you come back, they've already forgotten you." -- copy into your sig if you think this quote speaks true!
If you are one of the very few teenagers that know what real rap is and don't blindly listen to the hate statements (rap is crap), then put this in your sig. I say this in the name of Common, Mos Def, Lupe Fiasco, 2Pac, Nas, Talib Kweli, Eminem, and many others. -Exiled One
Group: Member
Posts: 11
Type: Mapper
RM Skill: Intermediate
I don't know if i'm doing it wrong or if there is another problem but it doesnt understand the ' cx ' from self.contents.draw_text(4, 0, 120-cx-2, 32, $game_variables[2], 2)
I dont really understand this enough to fix it myself, so whats going on here?
"When you first come, no one knows you. When help them out, they all know you. When you leave, they all love you. When you come back, they've already forgotten you." -- copy into your sig if you think this quote speaks true!
If you are one of the very few teenagers that know what real rap is and don't blindly listen to the hate statements (rap is crap), then put this in your sig. I say this in the name of Common, Mos Def, Lupe Fiasco, 2Pac, Nas, Talib Kweli, Eminem, and many others. -Exiled One
"When you first come, no one knows you. When help them out, they all know you. When you leave, they all love you. When you come back, they've already forgotten you." -- copy into your sig if you think this quote speaks true!
If you are one of the very few teenagers that know what real rap is and don't blindly listen to the hate statements (rap is crap), then put this in your sig. I say this in the name of Common, Mos Def, Lupe Fiasco, 2Pac, Nas, Talib Kweli, Eminem, and many others. -Exiled One
Group: Member
Posts: 11
Type: Mapper
RM Skill: Intermediate
QUOTE (Night_Runner @ Dec 7 2009, 11:31 PM)
@> Amnesiah: That's looking really good I'd be very happy with it
Thanks !
And thanks to law aswell, Im at school right now so I cant try that code yet, I will show you guys a demo of the entire attribute point thingy when it's done.. I haven't found something like it yet so I hope it's going to be great !
"When you first come, no one knows you. When help them out, they all know you. When you leave, they all love you. When you come back, they've already forgotten you." -- copy into your sig if you think this quote speaks true!
If you are one of the very few teenagers that know what real rap is and don't blindly listen to the hate statements (rap is crap), then put this in your sig. I say this in the name of Common, Mos Def, Lupe Fiasco, 2Pac, Nas, Talib Kweli, Eminem, and many others. -Exiled One
Group: +Gold Member
Posts: 1,521
Type: Scripter
RM Skill: Undisclosed
@> Red Knight: Did you put that icon for the gold in yourself? Does it move left when you get more gold? If so, that's awesome Nice job on the homework as well
@> Amnesiah: Let us know as soon as possible, it sounds awesome
__________________________
K.I.S.S. Want help with your scripting problems? Upload a demo! Or at the very least; provide links to the scripts in question.