The Script Builders' Tutorials:
----Lesson 2: Selectable Windows----
I. Introduction
II. The Window Creation Story
III. Set-Up
IV. Making Our Window
V. Showing Our Window
VI. Conclusion
VII. Homework
I. IntroductionGreetings! Welcome to the second lesson by the Script Builders (the first being found
here).
By this stage, you should have an idea of how to make a window with text, and if you did the homework you'll know how to reposition (& resize) the window

We'll start off slowly, and make plenty of references to the last tutorial to help you process it all, but today we're looking at Selectable Windows!
II. The Window Creation StoryYou may recall, Window_Selectable is the son of Window_Base. Window_Selectable shares many traits with his father (Window_Base) such as the draw_text command that we used last time. He also has an awesome sense of personal hygiene : D However, Window_Selectable can also have selectable items; such as New Game, Continue, Items, Equipment, Status, Save etc which was why he was kicked out of his family.
III. SetupOkey dokey, I believe the stage has been set, so like last time, we're going to save the outline of a normal window that is inherited from Window_Selectable into Notepad and call it Window Selectable Outline. Here it is:
CODE
#==============================================================================
# **
#------------------------------------------------------------------------------
#
#==============================================================================
class
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(x, y, width, height)
self.index = 0 # Initial Option
@item_max = 2 # Number of options
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
end
end
You may notice, it looks much like the same guy that was on last week, unfortunately though, we have a no refunds policy ; )
Windows all share the same basic structure, Ruby was kind in its original creation, and had consistency. But if you look closely, you'll see two new items added under the initialize method.
Window_Selectable, much like a nice restaurant, needs to know how many seats you would like, and where the birthday boy would like to sit.
Except in programming, the number of seats is how many choices you would like in your list (@item_max; the amount of choices), and the birthday boy, the one in the spotlight, is representative of the highlighted object, it's index if you will (self.index; the highlighted object).
For this introduction tutorial, we will have two choices (
@item_max = 2), and when you first load it up, have the first item in the list highlighted (
self.index = 0).
Now onto the fun bit, adding in new stuff
IV. Making Our WindowFirst, let's start off by naming our window in the second line of code next to the comment symbol. Write this: Window_Pet.
Then two lines down, write a brief description like we did last time. Something like: This window allows you to make selections between two different items.
Now, let's look at the line of code that starts with
Class.
We remember from last time that we can name our class whatever we want (provided it's not already in use!) and it needs to take its inheritance from our subject of the week.
I plan on calling my window Window_Pet since we already named it like that in our comment line and it's taking its inheritance from Window_selectable:
CODE
Class Window_Pet < Window_Selectable
Let's face it, when it comes to pets, there are only real two options, a Puppy Dog, or a Ninja Turtle

So down in the refresh area, we need to do a draw_text for our two options, but Window_Selectable assumes a couple things about its options.
Firstly, it assumes that option #1 is in the top left corner (coordinates 0,0), and secondly that the options are lined up vertically going down, spaced 32 pixels apart.
It's not that restricting, and it can easily be changed, but for the moment our text is only 32 pixels anyway, so we'll work with it

Keeping all this in mind, and the stuff that you learnt with The Law, if I were to ask you to come up with a window, hopefully you would come back with something like this:
CODE
#==============================================================================
# ** Window_Pet.
#------------------------------------------------------------------------------
# This window allows you to make selections between two different items.
#===============================================================================
class Window_Pet < Window_Selectable
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(100, 100, 640-200, 480-200)
self.index = 0 # This is what item is selected when the window is first made
@item_max = 2 # Number of selections available.
self.contents = Bitmap.new(width-32,height-32)
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
#self.contents.draw_text(x_position_from_edge , y_position_from_edge,
# width, height, "Text", alignment)
self.contents.draw_text(0,0,100,32,"Puppy Dog")
self.contents.draw_text(0,32,100,32,"Ninja Turtle")
end
end
Now, if we make an event the same as last time, we get: (open up your game maker and take a look!)

The same as last time, a static window

This is where Window_Selectable differs from Window_Base.
Window_Base you could make a window, it doesn't need to respond to inputs, so after it's made, you can leave it

Window_Selectable needs to be updated, to check if it should move the cursor up or down, and if it should select the highlighted item.
By default, Window_Selectable has the scripts to check if up or down is pressed, but it is up to us to tell it what to do if your player presses enter

This will require a new method (a method being the thing that starts with def), and I plan on calling mine: check_input.
CODE
#==============================================================================
# ** Window_Pet.
#------------------------------------------------------------------------------
# Based on the Script Builder's Guide, this is a selectable window :)
#==============================================================================
class Window_Pet < Window_Selectable
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(100, 100, 640-200, 480-200)
self.index = 0 # This is what item is selected when the window is first made
@item_max = 2
self.contents = Bitmap.new(width-32,height-32)
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
#self.contents.draw_text(x_position_from_edge , y_position_from_edge,
# width, height, "Text", alignment)
self.contents.draw_text(0,0,100,32,"Puppy Dog")
self.contents.draw_text(0,32,100,32,"Ninja Turtle")
end
#--------------------------------------------------------------------------
# * Check_Input
#--------------------------------------------------------------------------
def check_input
if Input.trigger?(Input::C)
$window.dispose
if self.index == 0
$window = Window_Text.new
elsif self.index == 1
print "You have selected option two"
$window = Window_Text.new
$window.y = 0
$window.back_opacity = 0
end
end
end
end
You should all be familiar with the refresh; it's the same as The Law G14's one, but the check_input I will explain though.
CODE
if Input.trigger?(Input::C)
This checks if the the "C" input is pressed, if it is, continue : )
CODE
$window.dispose
Window_Selectable has served it's purpose, so we let it get back to perfecting it's new cologne.
CODE
if self.index == 0
If the first item in the list is selected
CODE
$window = Window_Text.new
Then make the Window_Text from the last tutorial
CODE
elsif self.index == 1
If the first item isn't selected, but the second one is:
Then make a pop up, make the Window_Text from last time, move it around, and change it's back opacity

CODE
end
End looking at which item from our selection was picked
End the stuff that will happen if the input "C" was pressed
End the module ( def check_input)
End the class (class Window_Pet < Window_Selectable)
Ok done! We have made a selectable window, yay!
V. Showing Our WindowThis requires a bit of thought, we need to address two things, we need to call
$window.update (the default bit of script that moves the cursor up/down), and
$window.check_input every frame, and we need to stop after we have selected something.

To make sure that it gets updated every frame, we use a
for loop.
That code inside the conditional branch is a bit scary, but what it does is it looks at your $window, when we made it on the first line we define it as
$window = Window_Pet.new, and once we select something,
$window becomes a
Window_Text. What the conditional branch does, is check if the $window is still a Window_Pet.
If it is a Window_Pet, then run the update method (inside Window_Selectable) to check if up/down is pressed, and then run the check_input method (inside Window_Pet) to tell the program what to do if the player has selected an option : )
VI. ConclusionI realize that Window_Selectable isn't easy, and there are a quite a few things that will seem daunting at first, but on the flip side, if you can vaguely understand what's going on, you know A LOT about windows, and could probably do more than I could when I first started lurking around the Script_Support section : )
I hope that people have found this useful, and am looking forward to any feedback you may have

Also, I need to stress that you will probably NOT understand this tutorial the first time through. Be sure to post any concerns you have about the tutorial because Window_Selectable is a hard concept to grasp.
VII. HomeworkFor your homework, try making a more interesting selectable window, something that has a few more options, starting on say the 3rd item, and for the love of God, add some colour to the text!