Creating a Custom Window by RPG Advocate
#1
Creating a Custom Window
by RPG Advocate
saved from Phylomortis.Com


Introduction
This tutorial explains how to create custom windows for your game using RGSS. The example used in this tutorial is of a window that shows a custom window when you acquire an item.


Here we go
The first thing you should know about creating a custom window is that in order to look like all the other windows in your game, your new window class should inherit from Window_Base (or Window_Selectable if the user is supposed to select something in the window). In this case, I've inherited from Window_Base, since this window is designed to simply show information. The skeleton of your window should look something like the one in Code Sample 1. The image below the code sample shows what you get when you show this skeleton window. In this case, the Initialize function takes two arguments, one for the type of item to be displayed (item, weapon, or armor), and the other for the ID of the item within that category. The first statement in the Initialize function should always be a call to super (comment 1 in Code Sample 1). The four arguments are, from left to right, the X coordinate of the window's upper-left pixel on the screen, the Y coordinate of the window's upper-left pixel on the screen, the width of the window in pixels, and the height of the window in pixels. The second thing you should notice is that when a window is initialized, the last statement should always be a call to the window's Refresh method (comment 2 in Code Sample 1), so the window's contents have been initialized (at this point, the window is just empty). Finally, for this example, the type and ID instance variables are attr_accessors, since we are going to have to be able to set them and compare with them when the window is inserted into the Scene_Map class (comment 3 in Code Sample 1)

Code Sample 1
CODE
class Window_ItemGet < Window_Base
# ------------------------
attr_accessor :type # 3
attr_accessor :id
# ------------------------
def initialize(type, id)
super(220, 180, 220, 96) # 1
self.contents = Bitmap.new(width - 32, height - 32)
self.back_opacity = 255
self.contents.font.name = "Arial"
self.contents.font.size = 18
@type = type
@id = id
refresh # 2
end
# ------------------------
def refresh
self.contents.clear
end
# ------------------------
def update
super
end
end


The next step is to put the information we want to show in the window's Refresh function. The first statement in almost any refresh method should be to clear the window's contents. Since we want the text to show in the normal color, the font color is first changed to the normal color. In the case of this example, I want the word "Acquired" to always show on the first line. To draw any string within a window, you can use the self.contents.draw_text method. The five parameters, from left to right, are the X coordinate within the window bitmap to draw the text, the Y coordinate within the window bitmap to draw the text, the width of the space alloted for the text, the height of the space allotted for the text, and the text itself. What appears below the word "Acquired" depends on the type and ID instance variables. The three "if" statements determine which type of item I'm dealing with. If the type is 1, I'm dealing with an item. If the type is 2, I'm dealing with a weapon. If the type is 3, I'm dealing with a defensive item. Once I know which type of item I'm dealing with, I use the Window_Base#draw_item method to draw that item's icon and name. The code for all this is shown in Code Sample 2. The picture below Code Sample 2 shows what happens when I show the window with a weapon called "Sword of Scripting".

Code Sample 2
CODE
def refresh
self.contents.clear
self.contents.font.color = normal_color
self.contents.draw_text(4, 0, 180, 32, "Acquired")
if @type == 1
self.draw_item_name($data_items[@id], 4, 32)
end
if @type == 2
self.draw_item_name($data_weapons[@id], 4, 32)
end
if @type == 3
self.draw_item_name($data_armors[@id], 4, 32)
end
end


The next step is to plug the window into the Scene_Map class so that it can be displayed when the player acquires a new item. The first thing that needs to be done is change the Main function so that the proper variables are initialized. The Main function for Scene_Map is shown in Code Sample 3, with the changes from the default highlighted in red. The first thing to notice is that a new instance variable, @acquire_window, has been added. This is an instantiation of the class just defined above (comment 1 in Code Sample 3). Since we don't want it to show until we want to use it, the new window's visibility is set to false (comment 2 in Code Sample 3). The "@itemdelay" instance variable will be used later to tell the class how long to show the item window (comment 3 in Code Sample 3). The "@item_acquired" instance variable will be used to feed the type and ID of the item to the window (comment 4 in Code Sample 3). We need to be able to modify this array from outside the class, so it is made an attr_accessor (comment 5 in Code Sample 3). Finally, any new windows placed in a Scene should have a dispose statement placed at the end of the Main method (comment 6 in Code Sample 3).

Code Sample 3
CODE
class Scene_Map
# ---------------------
attr_accessor :item_acquired # 5
# ---------------------
def main
@spriteset = Spriteset_Map.new
@message_window = Window_Message.new
@acquire_window = Window_ItemGet.new(1, 0) # 1
@acquire_window.visible = false # 2
@itemdelay = -1 # 3
@item_acquired = [0, 0] # 4

Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@spriteset.dispose
@message_window.dispose
@acquire_window.dispose # 6
if $scene.is_a?(Scene_Title)
Graphics.transition
Graphics.freeze
end
end


In order to manage actually showing the window, the Update method of the Scene_Map class needs to be changed. The changes to the class are shown in red in Code Sample 4 (the entire method isn't shown). The changes are set up so that only a couple of scripting commands are required to make the window appear, and the Scene_Map class takes care of making it disappear after a few seconds. When event commands like the ones shown in the image below are used, it triggers the statement at comment 1 in Code Sample 4, refreshing the item acquisition window and making it visible. It also sets the @itemdelay instance variable to 125, meaning that the window should stay visible for 125 frames. The statement at comment 2 in Code Sample 4 decrements @itemdelay each frame. The statement at comment 3 makes the window invisible and resets @itemdelay to the sentry value of -1. The type and ID of the item to show are reset to 0, to wait for the next time the item acquisition window needs to be shown.

Code Sample 4
CODE
def update
loop do
$game_map.update
$game_system.map_interpreter.update
$game_player.update
$game_system.update
$game_screen.update
unless $game_temp.player_transferring
break
end
transfer_player
if $game_temp.transition_processing
break
end
end
@spriteset.update
if @itemdelay > 0
@itemdelay -= 1 # 2
end
if @itemdelay == 0 # 3
@itemdelay = -1
@acquire_window.visible = false
@item_acquired[0] = 0
@item_acquired[1] = 0
end

@message_window.update
if @item_acquired[0] != 0 &&
@item_acquired[1] != 0 && @itemdelay < 0 # 1
@acquire_window.type = @item_acquired[0]
@acquire_window.id = @item_acquired[1]
@acquire_window.refresh
@acquire_window.visible = true
@itemdelay = 125
end

[...]

Which scene you need to modify will depend on where you want the window to appear and what you're using it for. The steps above are, however, generally applicable to any information window you might want to make. Windows from which the user must select a command are a bit more complicated, and will be covered later.
Reply }


Possibly Related Threads…
Thread Author Replies Views Last Post
   Creating a Proper Game Doc United Washcloth Express 2 6,718 02-22-2010, 11:33 PM
Last Post: Ace
   Creating a perfect storm MagitekElite 0 3,806 02-17-2010, 07:07 AM
Last Post: MagitekElite
   Creating Your Own Scripting System DerVVulfman 3 7,473 10-12-2009, 03:37 PM
Last Post: Alpha-Mad
   YERD for Lunatics: Custom Damage Formula's RD Lowell 0 4,286 09-05-2009, 05:52 PM
Last Post: Lowell
   Element Tagging for Complex Effects by RPG Advocate DerVVulfman 1 4,121 03-12-2009, 12:45 AM
Last Post: Charlie Fleed
   Selectable Window Fundamentals by RPG Advocate DerVVulfman 0 3,813 03-11-2009, 06:39 PM
Last Post: DerVVulfman
   Simple Window Skins Xilef 0 6,329 12-07-2008, 04:27 AM
Last Post: Xilef
   Creating Believable Characters ccoa 0 4,257 12-06-2008, 05:13 PM
Last Post: ccoa



Users browsing this thread: 1 Guest(s)