Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.
i want to learn to make a custom menu for my game welcome to Endarium. i don't now how i would go about this. would some one be interested in helping me learn it, or point me in the right direction. (if this is in the wrong place please move it)
ok i know this is his post for help but i just read it and did as you said and i dont understand any of it its like a complete different language to me
my own background and custom buttons......
kind of basic but i want to learn to do it witch is why im asking for instructions i also want an extra button for extras
I wouldn't recommend any CMS that is either poorly documented or the comments are in a different language like Mr. Arbiter said. Especially from a learning point of view. But I'm feeling generous tonight.
*Teacher's Cap On*
What you ask isn't terribly hard to implement so how about we start with the question of getting your own picture in the background. But I'm going to take you through it step by step with little FYI's intermixed. First we are going to create a class to hold constants called Scene_Shared. I use something like this to hold strings and information I want to be able to grab which are often more times that not inside a Scene. Open your script editor(F11) right click Main and insert an empty section right above it. Then in this section paste in the code below.
Code:
#==============================================================================
# ** Scene_Shared
#------------------------------------------------------------------------------
# Constants that are shared across Scenes can be placed here.
#==============================================================================
module Scene_Shared
BACKGROUND_TEX = 'dir/imagename'
end
Set that constant BACKGROUND_TEX to the name of the image you want in the background. We will load the image through the Cache, so place the image in 'Graphics/Pictures/' directory. Go down a few lines below our module and use the code below:
Code:
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
end
From now on we're going to be editing the class Scene_Menu so don't just keep pasting the code I present or something bad might happen.
In Ruby you can do some pretty nifty things in code like extending a class definition without overwriting it. We can create new methods inside Scene_Menu without ever having to edit the default script directly. However if we need to mess with the inner workings of how a method works. We most likely will override the method. Overriding is accomplished by simply redefining the method. But the cool thing is with our picture thing is that we don't need to mess with the inner workings... Anyway we instead can just alias the method we need to alter. And this way we preserve the old code that was defined. To get our picture into this scene we will alias 'main'.
Code:
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# * Alias Methods
#--------------------------------------------------------------------------
alias_method :jkin_learning_main, :main
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
jkin_learning_main
end
end
If you run the game right now nothing will be changed. The old code is still being used. Neat huh. Now we will add code. First we need a Sprite object. I'm naming it back. Notice it isn't proceeded by a '@' or a '$'. In this case because this variable in this case a Sprite is not being used over multiple methods he can stay as a local variable. Local variables begin with a lower case letter and have no prefix character.
Code:
back = Sprite.new
back.bitmap = RPG::Cache.picture(Scene_Shared::BACKGROUND_TEX)
We also will need to dispose of these objects. We release them in the reverse order of their instantiation. First the bitmap then the sprite.
Code:
if !back.bitmap.disposed?
back.bitmap.dispose
end
back.dispose unless back.disposed?
I throw the checks in on every case of resource disposal just to avoid any unnecessary crashes. Also take note of the various ways you can arrange conditional statements. 'if !(not)' equates to the same as 'unless'. So where are we at in the Scene?
Code:
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# * Alias Methods
#--------------------------------------------------------------------------
alias_method :jkin_learning_main, :main
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
back = Sprite.new
back.bitmap = RPG::Cache.picture(Scene_Shared::BACKGROUND_TEX)
jkin_learning_main
back.bitmap.dispose unless back.bitmap.disposed?
back.dispose unless back.disposed?
end
end
Our image is loaded into the scene. And if you run the game right now you will see absolutely nothing but the original code. This is because of those dang windows. Their opacity by default is 255, which is full opacity. How can we go about this. We do have justifiable reasons to override main now. If we do we can just manually adjust every windows opacity to a certain value. Plus you want to also eventually add buttons right? So lets just override main. And add in this bit:
Code:
# Alter the transparency of the windows.
@command_window.opacity =
@playtime_window.opacity =
@steps_window.opacity =
@gold_window.opacity =
@status_window.opacity = 128
That doesn't look right does it? I'm only assigning that last window an opacity of 128. Well in Ruby lines carry over if there is an operand on the previous line suggesting that that line is not yet complete. Like:
Code:
a = 8 +
2
'a' will still be ten. Let's put the code into our overridden main method.
Code:
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
back = Sprite.new
back.bitmap = RPG::Cache.picture(Scene_Shared::BACKGROUND_TEX)
# Make command window
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = $data_system.words.equip
s4 = "Status"
s5 = "Save"
s6 = "End Game"
@command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6])
@command_window.index = @menu_index
# If number of party members is 0
if $game_party.actors.size == 0
# Disable items, skills, equipment, and status
@command_window.disable_item(0)
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
end
# If save is forbidden
if $game_system.save_disabled
# Disable save
@command_window.disable_item(4)
end
# Make play time window
@playtime_window = Window_PlayTime.new
@playtime_window.x = 0
@playtime_window.y = 224
# Make steps window
@steps_window = Window_Steps.new
@steps_window.x = 0
@steps_window.y = 320
# Make gold window
@gold_window = Window_Gold.new
@gold_window.x = 0
@gold_window.y = 416
# Make status window
@status_window = Window_MenuStatus.new
@status_window.x = 160
@status_window.y = 0
# Alter the transparency of the windows.
@command_window.opacity =
@playtime_window.opacity =
@steps_window.opacity =
@gold_window.opacity =
@status_window.opacity = 128
# Execute transition
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# Dispose of windows
@command_window.dispose
@playtime_window.dispose
@steps_window.dispose
@gold_window.dispose
@status_window.dispose
back.bitmap.dispose unless back.bitmap.disposed?
back.dispose unless back.disposed?
end
end
Now the picture is in the back and we can somewhat see it. Cool huh. Don't forget though you will need to do this Scene_Save, Status, Items, Skills etc. The SDK and VX picked up this mess with inheritance but that's another discussion.
Alright second part adding in options into Scene_Menu. This is quite obvious to edit if you've looked. There's a bunch of strings declared at the top of 'Scene_Menu.main'. So let's continue to edit our 'Scene_Menu.main' override, ok? You said you wanted to add an 'Extras' right? I'm going to just add it just before the 'End Game' just to limit the number of edits we have to do elsewhere. Plus we won't break the 'Save' button code or anything but 'End Game' temporarily.
Sweet, so Extra's are in there right? Well when you run the game. 'Extras' will have the behavior 'End Game' had and 'End Game' will do nothing. Oh noes! In the script editor go back to the default 'Scene_Menu' script and copy the update method. Just the update method. We are going to override this guy just like we did to main.
Code:
#--------------------------------------------------------------------------
# * Frame Update (when command window is active)
#--------------------------------------------------------------------------
def update_command
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to map screen
$scene = Scene_Map.new
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# If command other than save or end game, and party members = 0
if $game_party.actors.size == 0 and @command_window.index < 4
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Branch by command window cursor position
case @command_window.index
when 0 # item
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to item screen
$scene = Scene_Item.new
when 1 # skill
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 4 # save
# If saving is forbidden
if $game_system.save_disabled
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to save screen
$scene = Scene_Save.new
when 5 # end game
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to end game screen
$scene = Scene_End.new
end
return
end
end
Inside update is a case statement that checks for which option we are on in the command window when we hit the C button. We need to add an additional case because we added an additional option right? This case that we are adding now will be case 5 and the one that was case 5 will become case 6. Remember that we pushed 'End Game' down one? That's what we are correcting right now.
Code:
when 5 # extras
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to end game screen
$scene = Scene_Extras.new
All together now:
Code:
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
back = Sprite.new
back.bitmap = RPG::Cache.picture(Scene_Shared::BACKGROUND_TEX)
# Make command window
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = $data_system.words.equip
s4 = "Status"
s5 = "Save"
s6 = 'Extras'
s6 = "End Game"
@command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6, s7])
@command_window.index = @menu_index
# If number of party members is 0
if $game_party.actors.size == 0
# Disable items, skills, equipment, and status
@command_window.disable_item(0)
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
end
# If save is forbidden
if $game_system.save_disabled
# Disable save
@command_window.disable_item(4)
end
# Make play time window
@playtime_window = Window_PlayTime.new
@playtime_window.x = 0
@playtime_window.y = 224
# Make steps window
@steps_window = Window_Steps.new
@steps_window.x = 0
@steps_window.y = 320
# Make gold window
@gold_window = Window_Gold.new
@gold_window.x = 0
@gold_window.y = 416
# Make status window
@status_window = Window_MenuStatus.new
@status_window.x = 160
@status_window.y = 0
# Alter the transparency of the windows.
@command_window.opacity =
@playtime_window.opacity =
@steps_window.opacity =
@gold_window.opacity =
@status_window.opacity = 128
# Execute transition
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# Dispose of windows
@command_window.dispose
@playtime_window.dispose
@steps_window.dispose
@gold_window.dispose
@status_window.dispose
back.bitmap.dispose unless back.bitmap.disposed?
back.dispose unless back.disposed?
end
#--------------------------------------------------------------------------
# * Frame Update (when command window is active)
#--------------------------------------------------------------------------
def update_command
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to map screen
$scene = Scene_Map.new
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# If command other than save or end game, and party members = 0
if $game_party.actors.size == 0 and @command_window.index < 4
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Branch by command window cursor position
case @command_window.index
when 0 # item
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to item screen
$scene = Scene_Item.new
when 1 # skill
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 4 # save
# If saving is forbidden
if $game_system.save_disabled
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to save screen
$scene = Scene_Save.new
when 5 # extras
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to end game screen
$scene = Scene_Extras.new
when 6 # end game
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to end game screen
$scene = Scene_End.new
end
return
end
end
end
I'm not doing Scene_Extras for you but it'll follow something like the code below.
Code:
#==============================================================================
# ** Scene_Extras
#------------------------------------------------------------------------------
# This class does extra work!
#==============================================================================
class Scene_Extras
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# --Your custom code here--
# Transition run
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# --Your disposal code here--
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
$scene = Scene_Menu.new(5) if Input.trigger?(Input::B)
end
end
Almost forgot whenever you add to that Window_Command in Scene_Menu involving any choice that was pushed down. There's a butterfly effect. Meaning that there case was changed so now you need to edit the behavior of how the Scene that was affected. In this case we only pushed Scene_End down. So the fix for this would be:
Code:
#==============================================================================
# ** Scene_End
#------------------------------------------------------------------------------
# This class performs game end screen processing.
#==============================================================================
class Scene_End
#--------------------------------------------------------------------------
# * Process When Choosing [Cancel] Command
#--------------------------------------------------------------------------
def command_cancel
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to menu screen
$scene = Scene_Menu.new(6) # Its 6 now instead of 5
# Just so when we return to Scene_Menu the correct option is selected.
end
end
Don't pick on me. :down: You know that isn't all the work. There's still plenty to do. I just wanted to explain some things to help him understand the RGSS a little better. Plus this is support not academies most of these people don't come here to learn. Much to chagrin of you and me. So consider it as me giving him half a fish and a stick with a string attached to it. By the way, I want you to become a teacher! I think they still need scripting teachers. And if you become a teacher I will be your student and you can yell at me all you want. That is, if you're not... yella("yellow" for non back to future fans).