The objectives of this lesson are to learn how superclasses and subclasses work, use a superclass, how to make a subclass, to find the root of a variable, where to find needed information and build a series of windows and a scene by yourself.

Superclasses and Subclasses

Ok, so by now you have made your own class, which by definition can be considered a script that serves no real purpose. Now, we will explore how parent classes (superclasses) and child classes (sub classes) work, and the best way I can think of to do this is with Window, Window_Base, Window_Selectable, and Window_Command. Now, the objectives of this lesson are:

  • Learn how superclasses and subclasses work.
  • Learn how to use a superclass.
  • Learn how to make a subclass.
  • Be able to find the root of a variable (where it is defined.).
  • Learn where to find needed information (This sounds hard, but it is really quite easy once you learn how.)
  • Build a series of windows and a scene by yourself.
All of that may sound difficult, but in reality, it is basically taking what already exists in RGSS and adding to or modifying what can be found there. Also, you may be intimidated by building your own windows and scenes, but once you learn how to find the information you are looking for, it is all (relatively) smooth sailing from there. In fact, by the end of this lesson, I hope you can build your own basic CMS.

 

Now, don't expect to be able to build anything like Diego's CMS just yet... He uses some unique techniques that require diving deeper into RPG Maker XP's scripts such as drawing rectangles and stuff. What we are doing here is the basics. Walk before you run type thing. But, you will be able to make a series of windows and use them as a new menu rather than the default menu.

 

Ok, shall we get started? Before we actually build some windows and before I show you how, there are a few things I would like to cover. This includes the whole superclass and subclass thing. This would be a nice thing to know before we get started. We covered the basics of this in lesson 1, but a short review here can't hurt.

 

Basically, superclasses and subclasses works on a hierarchy scale, and the best example, again, is with the Window commands:

 

Window < Window_Base < Window_Selectable < Window_Command
RGSS has Window built into the system, and you can actually find information on it in the help file. Next, Window_Base. It has the superclass of Window. TO find this information, pull up the Window_Base script in your scripts of a project. (New preferably so we don't destroy a project.) The first coded line (non commented line) should read like this:

 

class Window_Base < Window
what this means is Window_Base has the superclass of Window. If you go to Window_Selectable, you will find it has the superclass of Window_Base, and Window_Command's superclass is Window_Selectable.

 

How a superclass works is pretty simple: All commands availble to the superclass(es) is availible to the subclass of it. So Window_Selectable can use any method found in Window_Base and Window. This means Window_Command gets all methods from Window_Selectable, Window_Base AND Window. Pretty neat, right?

 

You are probably thinking by now "Ok, so make all windows Window_Command, and skip the whole remembering which class will cover what i need." I hate to break it to you, but it isn't quite that simple. And for a few good reasons too:

  • Window_Base won't lag up the system as much as Window_Command.
  • Window_Command is only useful in scenes.
  • Window_Selectable can have selectable objects, and Window_Base cant.
So, in brief, with this, it is pretty easy to discover which windows to use for what it needs. For example:
  • Window_Base is perfect for displaying information, and won't have a cursor, so even better for windows that have no options. Can be reused in different scenes.
  • Window_Selectable is great for any window that will have options, and can easily be reused any number of times in different scenes.
  • Window_Command is great for any menu that will instantly be active at the beginning of the scene, and will have some options disabled. Was intended for use with CMS systems, basically. They can NOT be reused.
This isn't too hard to remember, right? Good. Now you know how the hierarchy of superclasses and subclasses work, and that methods can be called from a class's subclass. For example: Window_Selectable can use a method found in Window_Base. This really beats rewriting methods for each class.

 

With superclass and subclass covered, we can move on to the structure of a window, and include the 'calling of variables' into methods. The calling of methods is both tricky, yet vital, and pretty neat.


Structure of a Window

There are 2 types of windows we will cover here, because the third is made using a scene. For now, sure, we can make a window, but remember, a window, and scene should always be preplanned before created. I have some small rules to windows that I follow, but it doesn't mean you have to. I just follow them because of how text is used. My own way of standardizing my windows. The rules are very simple:

  • A window's width AND a window's height must both be divisible by 32.
Man, those rules are hard to follow... Another thing I would like to make clear is I follow how the old PKE version ran, back before I even knew there was a legal version. In the script 'Main', after begin, I put in two variables; one for the text font, the other for the text size. I do this because it is much easier for me to change them in an event or script this way, rather than remember the whole: Font.default_name B.S. There are some nice things about the Font object, but that is later. For windows, I use the variables same to PKE:
$defaultfonttype = "Tahoma"
$defaultfontsize = 24
THis is just for simplicity for me, though many think i use the 'illegal' version.

 

With all of that out of the way, let's get started. We will start with Window_Base:

 

Window_Base usually uses two basic methods in it's structure:

def initialize
def update
Now, this may seem like little, but with them, we can do a whole lot more than just draw a window, we can also make it update. (obvious, right?)

 

Now, to get started, we need to open our class, give it a name, use the superclass Window_Base, use the method initialize, and set up the parameters:

class Window_Info < Window_Base #Line 1
  def initialize  #Line 2
    super(0, 0, 640, 64)  #Line 3
    self.contents = Bitmap.new(width - 32, height - 32)  #Line 4
    self.contents.font.name = $defaultfonttype  #Line 5
    self.contents.font.size = $defaultfontsize  #Line 6
  end  #Line 7
Lines:
  • 1. Names the class, and shows by the '<' the superclass is Window_Base.
  • 2. Calls the initialize method.
  • 3. Calls the superclass, and defines the window as: (x, y, ox, oy)
    x = Location right of the upperleft corner.
    y = Location down from the upperleft corner.
    ox = How wide the window is.
    oy = How tall the window is.
  • 4. self means this class, the contents is a new Bitmap (the window.), and the viewport of it is the width of the window - 32, and the height of the window - 32. We subtract 32 from each for the border of the window.
    (Note: The classes Bitmap and Viewport can be found in the help file.)
  • 5. The window's font name is the variable I set in 'Main'. Not needed in the legal version, honestly.
  • 6. The window's font size is the variable i set in 'Main'. Not needed in the legal version, honestly.
  • 7. Ends the initialize method.
If you notice, I didn't end the class. That is because we will add one more method to the window: Update. SO after that coding, put:
def update(info_text) #Line 1
    self.contents.clear  #Line 2
    self.contents.draw_text(0, 0, 618, 32, info_text, 1) #Line 3
  end #Line 4
end #Line 5
Lines:
  • Line 1: Calls the update method. It also shows any time the method 'update' is called for this class, it needs parentheses and a variable inside them.
  • Line 2: Clears the window.
  • Line 3: calls the 'draw_text' method of Window_Base. The breakdown is like this: (x, y, lx, ly, text, alignment)
    x = how far to the right the text is.
    y = How far down the text is.
    lx = The allowed space for the text. (Because the window cuts off 32 pixels early, we too the window's width and subtracted 32 for this.
    ly = How much height is allowed for the text.
    text = well, the text.
    alignment = The number to ID the alignment. If this doesn't exist, it is assumed to be 0. 0 = Left, 1 = Center, 2 = Right.
  • Line 4:Ends the update method.
  • Ends the class.
Now, you see at line 1 where we have '(info_text)' after the method? This means if the update method of this class is called without that, we'll get an argument error. And, in line 3, when it draws the text, we have text as info_text. This means that info_text, which is a LOCAL VARIABLE, if you remember right, and since it is here, it NEEDS to be a string. A string is a line of text enclosed in quotes.

 

With that, you have a window that can be updated in a scene. This is just an example of how you can use it. I mean, you can call in a whole item as a variable and draw every little detail of the item in the window, but this will be taught later, where we pick at the built in information. Right now, we are studying how to make windows, then a scene.

 

Now, we went over the simplicity of Window_Base, we'll move on to Window_Selectable. This is a rather larger subject to cover, so I'll probably touch base with you really briefly on this in this section, nothing too spectacular, just a basic list of options. I will teach you the quick way to make a list of predefined options, but things such as a list of items we'll do later in Lesson 3.

 

Right now, here we go on a simple 4 option list. The options won't pertain to anything, really, just four options as an example:

class Window_Example < Window_Selectable
  def initialize
    super(0, 64, 192, 160)
    @options = ["Option 1", "Option 2", "Option 3", "Option 4"]  #New Line 1
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.name = $defaultfonttype
    self.contents.font.size = $defaultfontsize
    self.index = 0  #New Line 2
    refresh  #New Line 3
  end

 

Now, most of this you have seen before, but there are 2 new lines:

  • New Line 1: This line is merely an array named '@options' that says that item 0 is option 1, item 1 is option 2, etc. Just remember to put these in quotes, and separate them by commas.
  • New Line 2: This line is to set the index of the window. there are other lines similar to this one, and we'll cover those in the next section, which will tell about the common commands in Window_Base and such.
  • New Line 3: This line calls up the method 'refresh'. Refresh is just the name of a method, it could be called trout and still work, but refresh describes it.
On to the method of refresh. This is real simple example to do, for a short menu:
def refresh
    self.contents.clear
    for i in 0...@options.size #New Line 1
      x = 4 #New Line 2
      y = i * 32 #New Line 3 
      self.contents.draw_text(x, y, 160, 32, @options[i]) #New Line 4
    end #New Line 5
  end
end
The new lines are described here:
  • New Line 1:
    This includes a new keyword for you: for. For is a loop word. Then, i is the local variable that will resemble a number. The number is defined by the following piece, and it also says how much it loops: 0...@options.size.
    The way that works is 0 is the starting number, the number of dots tells whether or not to exclude the last number. 2 dots means to include the last number, 3 means to exclude it. Well, the size of the array is 4, but there is nothing in @options[4], because that is place number 5. So, we use 3 dots, so it loops like this: 0, 1, 2, 3. So, i will equal that each time, and when it equals 3, it will end the loop.
  • New Line 2: The local variable x equals 4. We make it 4 to make room for the selecting rectangle.
  • New Line 3: The local variable y equals the local variable i multiplied by 32. As you recall, i will equal 0, 1, 2, and 3. This means, y will equal, every time it loops, 0, 32, 64, then 96.
  • New Line 4: This line is another draw text, but instead, we use variables for x and y. We use y because this means it will make each line drawn down one 'space', so that we have a list. A neat trick, no?
  • New Line 5: Not really a new line, but we do have to end the 'for' statement.
Just a quick review: a 'for' statement is set up like this:
for i in x...y
2 dots to include the last number, 3 to exclude it. And x is the number we start at, y is the ending number.

 

Doggone, that is alot of information to go over. In the next section, we'll cover the syntax's we can use in a window. This list can actually be found as the names of the methods in Window_Base and Window_Selectable, but I would like to describe a little bit more how they work. Go ahead and review all of this, because it is a lot of information.

 

Also, you can try these if you want, just call them using call script by doing: Class_Name.new
Of course, Class_Name would have to be the name of the windows we made. But, test them, and even change them around a bit. Learn a little. Just remember, you have to call the update method of the info window to show anything, so save that one for a scene.


Window_Base

Now, I am going to explain the different commands that each of the three, and show you how each can be used. Shall we get started with the basics?

 

Since Window_Base is the highest one we can access, we'll start there. Also, we'll cover 'Font', because it is entwined with windows.

 

We need to look at each method in Window_Base, and I'll explain how it works, and for what purpose. Remember, to use these in the window, you need to put: self.method name) or just the method's name.

 

We will skip the methods 'initialize' and 'dispose'. They aren't needed to know, it just shows how the window is made, and how it disposes. Anyway, next method is 'text_color'.

 

Now, for windows, there are a few things we need to go over before the methods. That is you can do certain things, such as:

 

self.windowskin = RPG::Cache('windowskin_name')
self.x = the placement, horizontally, of the upper left pixel.
self.y = the placement, vertically, of the upper left pixel
self.z = for layering, the higher the number, the closer to the top of the pile.
self.width = the width of the window
self.height = the height of the window
self.visible = Whether or not the window can be seen by the player.
self.contents.font.(command) will edit the font. We'll cover this with the whole 'Font' explanation.

 

Now, the method 'text_color' has a 'n' in parentheses next to it. This means you must call up a variable if you ever call up the method 'text_color', you have to put something in the parenteses. What though? Well, let's look a little in the method:

def text_color(n)
    case n
    when 0
      return Color.new(255, 255, 255, 255)
    when 1
      return Color.new(128, 128, 255, 255)
    when 2
      return Color.new(255, 128, 128, 255)
    when 3
      return Color.new(128, 255, 128, 255)
    when 4
      return Color.new(128, 255, 255, 255)
    when 5
      return Color.new(255, 128, 255, 255)
    when 6
      return Color.new(255, 255, 128, 255)
    when 7
      return Color.new(192, 192, 192, 255)
    else
      normal_color
    end
  end
Well, the 'case' is a statement is new, isn't it? Well, the way it works is you put 'case', then a variable after it. Then, you put 'when' and what the variable could mean, and after that, what it would do, like above. Then, you use an 'else' statement in case the variable doesn't meet the requirements of any of 'when' statements. Consider it as a conditional branch, but you can have many more options.

 

So, according to this, there is 0-7 options, and each one does the same thing. returns a color. Now, to define the color, we have 'Color.new(Red, Green, Blue, Opacity)', each is a number between 0-255. If the number isn't one of these, it will trigger 'normal_color'. Well, since this hasn't been defined, it must be a method.

 

Any of the ones that deal with the color, you use: self.contents.font.color = text_color(n)

 

In fact, the next method:

 

def normal_color
    return Color.new(255, 255, 255, 255)
  end

 

This method here, is the 'normal_color' method. This is used to make the text color white, as you can see. It maxes out the red, green, and blue; as well as the 'alpha', or, opacity, as you will. Anyway, that is pretty simple, just make

 

self.contents.font.color equal to normal_color to equal white.

 

def disabled_color
    return Color.new(255, 255, 255, 128)
  end

 

This here is a lot like the normal_color, but the alpha is halved.

 

def system_color
    return Color.new(192, 224, 255, 255)
  end

 

Ok, you know that blue-colored text? That is the 'system_color'. As you can see, this is just like the ones before.

 

Ok, crisis_color and knockout_color are the same as disabled, normal, and system. I won't explain them.

def update
    super
    if $game_system.windowskin_name != @windowskin_name
      @windowskin_name = $game_system.windowskin_name
      self.windowskin = RPG::Cache.windowskin(@windowskin_name)
    end
  end
This updates the windowskin. Simple, no?

 

Ok, from here in, I am going to just give the method's name, and describe how to use it, not how it works. I don't want this too long.

 

draw_actor_graphic(actor, x, y)
Draw's the actor's sprite. To use it, you specify the actor, x position, and y position in the parentheses, like this: draw_actor_graphic(@actor, 10, 10)

 

NOTE: x is always horizontal, y is always vertical. keep that straight. Sure, they are just variables, but still important to keep straight.

 

Now, in addition to draw_actor_graphic, there is a plethora of other 'draw_actor' things you can do. Here is a list:

 

draw_actor_name(actor, x, y)
draw_actor_class(actor, x, y)
draw_actor_level(actor, x, y)
draw_actor_state(actor, x, y, width = 120)
draw_actor_exp(actor, x, y)
draw_actor_hp(actor, x, y, width = 144)
draw_actor_sp(actor, x, y, width = 144)
draw_actor_parameter(actor, x, y, type)

 

Wait, wait, wait... There are a few of these with added things. Three of them has a

 

'width = x', and one with 'type'. What the hell is th-... sorry, anyway, to explain, if you ever aren't sure if the variable will be called in parenthesis, you can always set it equal to something like the width is. If there is a variable, in this case, a number there, it will set the width to that rather than what is show above.

 

But, one of them has a fourth thing: type. What is that? Well, for parameter, there are 7 different types, numbered 0-6. It is easier than drawing up 7 different methods.

 

The types can be found in window_base, but I'll list them for you:
0 - attack
1 - physical defense
2 - magical defense
3 - strength
4 - dexterity
5 - agility
6 - intellect

 

Now, make_battler_state_text sets the compilation of the names of all of the statuses that can affect the hero. You don't need to use this, really, because draw_actor_state does this for you.

 

Well, this is it for Window_Base, in the way of methods. It is a long explanation, so soak it all in. I recommend a notepad and taking notes on some stuff, it tends to help. At any rate, I will continue with Window_Selectable and Window_Command in the next section.

 

Credits to Trickster for correcting some of my errors and Kiriashi for reformatting.


Window_Selectable

All right, we have made some progress with Window_Base. There was one thing someone asked, so I think I'll clear that up first:

 

The correct structure of a 'Window_Base' window, much like the status window, would be:

class Window_Status < Window_Base
  def initialize(actor)
    super(0, 0, 640, 480)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.name = "Tahoma"
    self.contents.font.size = 22
    @actor = actor
    update
  end

  def update
    self.contents.clear
    # Insert commands for whatever you want here.
    # This includes stats, names, labels, and even text colors.
  end
end

 

Not too hard, eh? Yeah, that also has the parentheses there too, at the initialize method. This means, when we call it, we need a variable there. For something like the status window, we want an actor as a variable. For testing, we would use:
$game_party.actors[0]
This is because it will call up the array of actors in the party, and the first actor (0 position actor) into the window. Also, don't forget to add the 'update' to call the update method. Many forget this... including me. Believe it or not, you can make a status window by now, if you want to give it a try.

 

Now, with that out of the way, how about we look at the methods we can use for Selectable.

 

Initialize tells us it adds @item_max, @column_max, and @index.

 

Now, not many of them do much, just explain how the class works. If you want to know that, read the 'comments' in the script. (Sorry for all of you using an illegal version. If you have that, you may have to learn how to read the code, to understand it.)

 

Anyway, back to the other three:

 

When you make a window that is selectable, you need to specify the commands, as well as the maximum number of selectable items, the amount of columns, and yes, where the cursor begins.

 

Now, we are going to predetermine options. Later, we'll get into the process of pulling them from a list, but not now. It is more of a 'advanced' technique. Anyway, I'll build a class and show you how this can be achieved, quickly, easily, and efficiently:

class Window_Name < Window_Selectable
  def initialize
    super(0, 0, 160, 192)
    @commands = ["Items", "Skills", "Equipment", "Status", "Save Game", "End Game"]
    @item_max = @commands.size
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.name = "Tahoma"
    self.contents.font.size = 22
    refresh
  end
I am sure, if anyone is looking for errors, will notice 2: no end to the class, and no refresh method. We'll add these later, don't worry. At any rate, let's pick this apart, with the new things:
The array called '@commands'
The @item_max variable

 

Well, These are easy to pick apart. The array gives us 'strings' of each command. The reason we want them in string form is if they weren't, they would be considered variables. Of course, arrays will be explained in more detail later, but for now, we have 6 commands.

 

Now, the @item_max = @commands.size means it makes the maximum number of selectable items equal to the array '@commands' size. This is important, otherwise the item max would be 1.

 

The @item_max, more specifically, tells us how many 'selectable' items there are in the window. Very handy. Now, @column_max tells us how many columns are allowed for the selection. So, for a horizontal menu, rather than a vertical menu, we could set @column_max = @item_max after @item_max has been defined as @commands.size. The reason is everything triggers in order:

 

@commands
@item_max
@column_max
That simple. Now, the @index, also known as self.index when in the window, is where the cursor begins. in the initialize method, set it to '0' of the window is automatically active. This puts it on the first item. If you want the window inactive, set it to '-1'.

 

The other way to make a window active, is to use: self.active = true I recommend putting this into the selectable window, incase you need to have that item selected while another window is active (sort of like for a CMS).

 

Ok, now we have to go over the 'refresh' method. Believe it or not, depending on if you are making a command window or an item/skill/etc window, this can be long or short. We'll go over the latter of the two later, but for now, concentrate on a command window.

def refresh
    self.contents.clear
    for i in 0...@commands.size
      x = 4
      y = i * 32
      self.contents.draw_text(x, y, 128, 32, @commands[i])
    end
  end
end

 

Now, we define or refresh method, put in 'self.contents.clear' because this clears the window before re-printing everything inside (keeps the text from looking fuzzy), then do a for statement. The for statement starts at 0, and goes to ...@commands.size
If you remember, 3 dots means it is that number -1, basically. So, in this case, @commands.size - 1, a.k.a. 5. The reason why? 0, 1, 2, 3, 4, 5 will call up the commands, but 6 will yield a 'nil' error, something that sucks.

 

Now, why start at 0? because arrays start at 0. I think I all ready covered that before... but that is a refresher. Next, position x equals 4, because we need to make room for the cursor (the blinking rectangle thingy.). Since it is just '4', we can assume this is a vertical menu.

 

Next, y = i * 32. Well, i is a local variable defined by the for statement. it says i = 0...@commands.size. So it will loop for 0, 1, 2 etc. So, i will equal each in turn, give us the numbers 0, 32, 64, 96, 128, and 160.

 

Then, we draw the self.contents.draw_text, put in x and y variables, then give it the width of the window minus 32, make oy = 32, simply because this is standard for the default font size (it is centered.), then the text is @commands[i]. Well, the first time this is called, that will equal "Items".

 

How?! Simple, it calls up the '0' location of the array @commands that we defined, as a string called 'items'. Then it will call each in turn, and end. That is a basic selectable window. Simple, no?

 

Now, i said I wouldn't cover the other commands, but maybe I will when we get into editing the pre-existing bits of script that are in the game. Mainly because we can have some fun and fix a couple small glitches, making the program run easier for you.


Scenes and Window_Command

Ok, we have gone over everything with in Window_Base, and a good bulk in Window_Selectable, so now we must go over Scenes, which includes Window_Command. Now, personally, I don't use Window_Command very often, but it is very useful. Every now and then, I do use it. Anyway, here we go.

 

Now, there is one thing Window_Selectable can do, that Window_Command doesn't. That is making more than one column. Since I use columns, I don't like using Window_Command. But, there are some advantages as well. For instance, they are drawn up a LOT faster than Window_Selectable, and you can make options disabled a lot easier as well. Anyway, you use these in a scene, so why don't we build a scene with a Window_Command inside of it? This way, we kill two birds with a stone...Poor birds...

 

Anyway, Scenes are still a member of the whole 'Object' class that almost everything is built. But, we must adhere to some specifics to this scene. For instance, not every Scene uses the method 'initialize', but by using it, you can call in information. There are some tricks I will teach you, but first, the structure.

 

The structure of a scene is super-basic:

  • Initialize (if you need to call in something like the actor's information.)
  • Main (Where all variables are initialized.)
  • Update (Where the scene constantly updates.)
Now, this sounds a lot like a window! But, there is a catch, if we put the whole scene's works in the 'update' method, we'll begin to lag, which is bad, so we split it up into other methods. (One of my latest scripts has about 9 or 10 methods for one scene.) The upside to splitting a scene into so many methods is it is easier to manage.

 

Ok, let's get into the nitty-gritty of each method in detail, and I'll show you how to do things. As with all things, we start with the beginning; Initialize.

 

Initialize
Here we are, at the beginning. The initialize method of a scene may, on the surface, look like 'ok, i am going to define the scene, like the initialize method id's windows. WRONG! Don't feel bad though, that was good logic, and i thought the same thing at first. Anyway, the only time you really use initialize with a scene is if you have to call in information. For example, if it is a status screen, you need to call in the actor.

 

NOTE: To call a scene, you MUST use:

$scene = Scene_Name.new

 

Now, the way it works is:

class Scene_Name
  def initialize(actor_index = 0)
    @actor_index = actor_index
  end
NOTE: I didn't add the last end.

 

As you see, it looks similar to when we call in information to a window... but we added a '= 0' at the end. What this means is if this window is called, but there is no parentheses with a number inside of it, it will automatically equal 0. Nifty, no? Now, the information we call here is a number, but it can call in any variable. Granted, with this, we'll probably be calling a number where the actor is in the party. This, by default is 0-3 (1, 2, 3, 4). Don't worry if you feel confused. By the end, you should understand this. If not, go to the Question and Answer section, and I can answer anything, and amend this. Back on topic!

 

Next, we take that local variable actor_index, and make an instance variable equal it. Now, we have a variable that will equal whatever value is called in. This is important for scenes that need information. It is easy to do, but may seem confusing now. It may be best to come back to this during a review. That reminds me, take notes, your review and test deal with making a scene. By the end of this Lesson (lesson 2), you can make your own status scene, along with a couple others.

 

But, this covers the 'initialize' method, shall we move on?

 

Main
This is where we identify the variables, and look the 'update' method. This is where things get cool. First, we'll take a look at what we did before with the whole 'initialize' thing. If you have a variable like that one, that has to be an actor, you can do this:
@actor = $game_party.actors[@actor_index]
Since in a CMS you will pre-plan things, you cannot get a bad value unless you screw up. Hopefully, you won't do that. But, let's look at a scene's structure for 'main':

 

def main
  @actor = $game_party.actors[@actor_index]
  
  s1 = "Line 1"
  s2 = "Line 2"
  s3 = "Line 3"
  s4 = "Line 4"
  @other_window = Window_Other.new
  @actor_needed_window = Window_Actor.new(@actor)
  @command_window = Window_Command.new(192, [s1, s2, s3, s4])
  
  Graphics.transition
  loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    Graphics.freeze
    @command_window.dispose
  end
Here we go, alot of new stuff. First, we have our @actor = thing that i discussed earlier. Then, the following s1-s4 bit is all making local variables. Following that, we have a window that we have named @other_window. This calls just a basic window. (The variable name you give a window doesn't matter, just make it an instance variable.) After that, a window that has a set of parentheses by the initialize method, so we add our own here in the scene, and put in @actor, because this 'Actor' window shows actor information. (We are assuming this window exists. Assuming we drew up this window earlier, and that it will draw actor information.)

 

Then we have the next big step. @command_window = Window_Command.new(192, [s1, s2, s3, s4]). We'll come back to the Graphics bit, i want to explain the Window Command.

 

With other windows, you made them in a separate class, this one, you call the window straight up, then it has 2 preconditions:
(width, [options]). In this case, we ID'ed the options, and put the variable names in, and the width is 192. After taht, you can change it's location from (0, 0) by doing the following:

 

@command_window.x = x  (Moves the window to the right 'x' pixels.)
@command_window.y = y  (Moves the window down 'y' pixels.)
@command_window.z = z  (For layering. If this window is at the same place of another, and you want this on top, it needs a higher 'z' value.)
@command_window.height = ly (Sets the length of the window, set this equal to a multiple of 32)
@command_window.opacity = x (Sets the opacity of the window. 0 is transparent.)
@command_window.active = true/false (Makes the window active/inactive)
@command_window.visible = true/false (Shows/hides the window.)
@command_window.index = 0 (Sets the cursor of the window.)
@command_window.disable_item(x) Disables the item at the 'x' position.
The great thing is the 'disable_item'. This comes in handy for options you dont want the player to use unless they meet a specific requirement. To do this, we use an if statement. For example, in the default Scene_Menu, you have:

 

    if $game_system.save_disabled
      @command_window.disable_item(4)
    end
This means if $game_system.save_disabled is true, it disables item number 5 (0, 1, 2, 3, 4) which is 'Save game'. It is pretty sweet.
Pretty much, everything is done for you in the way of 'building' the options window, but you don;'t have a whole lot of freedom with it. For instance, you can't make multiple columns. But, on to the 'Graphics' information:

 

Graphics.transition
  loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    Graphics.freeze
    @command_window.dispose
  end
This is the basic thing in every scene. I'll explain it, but you don't need to know it in detail, really.
Graphics.transition means it will execute the transition, then loops, updating the graphics and input modules,(NOTE: A module is just something that holds generic information for the game. A lot like a constant variable, but more versatile.) then calls the update method, and checks if $scene still equals this scene. If not, it will break the loop, freeze the graphics for a second, and disposes whatever you define to be disposed (which should be all windows, pictures, etc.)

 

Now, we have covered teh initialization, and the main methods. This is where things get tricky. You need to know different commands to make a scene work, and basic commands. You will need to know, mainly, the Input module, if statements, and other things. I will teach you the basic ones, so you can make a basic scene, but nothing really fancy yet. We will have to examine other classes first. I will, however, teach you the basics right now:

  • if
  • case
  • Input
  • return
  • $game_system.se_play
That is all you will need to know to make a basic scene. sound simple enough? Well, I'll explain how each works, then you can fiddle with it. Just remember: The best way to learn is look at examples.

 

if
Ok, with if, you have 3 different keywords to work with: if, elsif, and else.
The way these work is rather simple:

 

if (statement) == x
  trigger a
elsif (statement) == y
  trigger b
else
  trigger c
end
Basically, if is the initial statement, elsif means if the same thing equals something else, and else means if the if isn't true, it will go to that instead. Granted, you could just use if, without elsif or else, and you can make one with only using if and else. There is also specific things you must remember about if statements, the 'conditions'. These comparison statements compatible with 'if' are:

 

== equals
!= or <> does not equal
<= is less than or equal to.
>= is greater than or equal to.

 

The opposite of if is unless, and is used in the same fashion, but kind of reverse. Sort of like:

 

unless baby?
  feed_meat
else
  feed_milk
end
so unless it is a baby, you do would feed it meat, else you would feed it milk.
That is if and unless.

 

Next: case

 

case
Ok, this is a fun thing here, It is like an if statement with a ton of options. It's structure is:

 

case variable
when 0
  if it equals 0, trigger.
when 1
  if it equals 1, trigger.
when 2
  if it equals 2, trigger.
else
  if it equals none of the above, trigger.
end

 

Ok, that is how it works. If the variable equals 0, it will trigger that first one, if 2, it will trigger the one that says 'when 2'. If it is 7, it will trigger the 'else' statement. Now, let's say you want to do something based on age:

 

case $age
when 0 .. 2
  p "baby"
when 3 .. 6
  p "little child"
when 7 .. 12
  p "child"
when 13 .. 18
  p "youth"
else
  p "adult"
end
Case statement doesn't need a whole lot of explaination, but the '..' means from 0..2 it will be a baby. if it is 13 .. 18, it will be a youth. See how that works? Next!

 

Input
This is a module built into the game. It is used to identify the keys used in the game when pressed. For a basic scene, you only need to concern yourself with 'B' and 'C', but there are many others. to use this, we use an if statement to see if it was pressed. The best thing is you don't have to check if it is true, that is automatic. To do this, we use:

 

if Input.trigger?(Input::C)
This goes into the module 'Input', to the 'trigger' command, to see if the the input is 'C'. The different buttons are:

 

A, B, C, X, Y, Z, L, R, DOWN, LEFT, RIGHT, UP, SHIFT, CTRL, ALT, F5, F6, F7, F8, F9
All of those are different buttons you can use. Just remember, they must all be capped. So, you can use:
Input.trigger?(Input::SHIFT) to see if shift has been hit. Now, in addition to different keys, there is also different types of pressing a key. After the first Input, use:
.press? means the button is being held down.
.trigger? means the button was pressed down once.
.repeat? Checks if it was pressed multiple times.

 

Next, you have the parentheses, where you put: (Input:: B) , B being the button.

 

return
return takes you back to the beginning of the method, if not followed by something. If it is followed by a variable, every time that method is called, it will bring back the value of the variable. This is nice after putting in the input button, because it stops the processing of the method, and goes right back to teh beginning THAT frame.

 

$game_system.se_play()
This right here, will play a sound effect that is defined in the parentheses. The most common to put in the parentheses are:

  • $data_system.cancel_se
  • $data_system.decision_se
  • $data_system.buzzer_se
These are all defined in the database, and are standardized through the menus in the game. They are pretty self explanatory:
cancel is used for the 'B' button, decision is used for the 'C' button, and buzzer is used whenever an action isn't allowed.

 

Ok, so we went through a LOT of information. In the review, we will take alot of this information, and build a simple scene together. After that, try to build your own scenes for a while, until Lesson 3, when we get into the default scripts and how to utilize their powers, including adding actor information, party information, system information, and so forth.

 

Until then, you can still toy around with building a scene, and I encourage that. Again, don't forget, you must call a scene using:
$scene = Scene_Name.new


Assignment

So, we have looked at windows, we have looked at scenes, and we have seen all the data we can put into a window. Now, we are going to build a status window, something you can actually use without having to build a new CMS.

 

This one will be a basic one, so please, If you have any questions, post them in the Q&A.

 

First, build a window that contains just basic information. Remember: This is to teach you to make your own scene for status. Do what you know you can do, and maybe 1 or 2 things you don't know. Experiment until you can do what you want.

 

Next, build a scene, using what i showed you in Section V. Bear in mind you don't need a command window. In fact, you don't even NEED a window to build a scene, but for this one, we need at least 1 window telling about the actor.

 

Stuff to include would be: Name, Class, Status, Exp, Level, Stats, Equipment

 

There are many other things you can include if you want. Also, even though you can just copy/paste from the original Window_Status class found in the default scripts, I HIGHLY recommend trying this on your own before referring to that class.

 

Next, Look into Scene_Status and look at how the Input::B, Input::C, and Input::L? if statements work. There are some things there that will confuse you (mainly in L and R) and we'll discuss those later.

 

Lastly, Name your class Scene_Status
(for example: class Scene_Status)
and use initialize and call up your actor information (An example of this can be found in Scene_Status). If you have any questions, please PM me. If it is a question, the subject should be: Lesson 2 Assignment Help. If you are turning it in, use: Lesson 2 Assignment

 

After this lesson, we will be looking closely at Numeric and String before moving onto actor information. These 2 parts are harder to learn, and i will only touch them briefly, but they will show you some of the more fancy things you can do with text than just showing the words.

 

After that, I'll explain in detail how to make a CMS, but believe it or not, with everything I have told you, you should be able to make one.

Share


About the Author

No Comments

Quick Reply

Guest

Enter a username

Security check: What is 8 plus 2?