Envision, Create, Share

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.

script error

i have this script and I can't seem to find the error. I keep getting a syntax error on the last line of it (line 107). Please not that I did not write this script. It was written as an alternate for my mp3 player by Optimistshadow.
anyways, the script is as follows.....

Code:
class MP3_Case
  attr_accessor :contents
  def initialize
    @contents = []
  end
  
  def add_item(item_id)
    @contents += item_id
    return
  end
  
  def delete_item(item_id)
    for i in 0..@contents.size - 1
      if @contents[i] == item_id
        @contents.delete_at(i)
        return
      end
    end
    return
  end
end

class Scene_MP3
  def initialize
    $spriteset = Spriteset_Map.new
    @window_mp3 = Window_Command.new(160, $mp3_case.contents)
  end
  
  def main
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
    end
    Graphics.freeze
    $spriteset.dispose
    @window_mp3.dispose
  end
  
  def update
    $spriteset.update
    @window_mp3.update
    update_action
  end
  
  def update_action
    # 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)
      $game_system.bgm_play("#{@window_mp3[@window_mp3.index]}.mp3")
      $scene = Scene_Map.new
    end
  end
end
      
class Scene_Title
  alias os_cng command_new_game
  def command_new_game
    $mp3_case = MP3_Case.new
    os_cng
  end
end

class Scene_Save
  alias os_wsd write_save_data
  def write_save_data(file)
    os_wsd
    Marshal.dump($mp3_case, file)
  end
end

class Scene_Load
  def read_save_data(file)
    # Read character data for drawing save file
    characters = Marshal.load(file)
    # Read frame count for measuring play time
    Graphics.frame_count = Marshal.load(file)
    # Read each type of game object
    $game_system        = Marshal.load(file)
    $game_switches      = Marshal.load(file)
    $game_variables     = Marshal.load(file)
    $game_self_switches = Marshal.load(file)
    $game_screen        = Marshal.load(file)
    $game_actors        = Marshal.load(file)
    $game_party         = Marshal.load(file)
    $game_troop         = Marshal.load(file)
    $game_map           = Marshal.load(file)
    $game_player        = Marshal.load(file)
    $mp3_case           = Marshal.load(file)
    # If magic number is different from when saving
    # (if editing was added with editor)
    if $game_system.magic_number != $data_system.magic_number
      # Load map
      $game_map.setup($game_map.map_id)
      $game_player.center($game_player.x, $game_player.y)
    end
    # Refresh party members
    $game_party.refresh
  end
end

Thanks for any and all help in advance.
 

khmp

Sponsor

Errors that point at the bottom of a script are errors that deal with a missing 'end' to a block of code. In this case you're missing an 'end' at the bottom of your Scene_MP3 class line 62. That should solve your problem. Also this:
Code:
class Scene_Save
  alias os_wsd write_save_data
  def write_save_data(file)
    os_wsd
    Marshal.dump($mp3_case, file)
  end
end
Should be this:
Code:
class Scene_Save
  alias os_wsd write_save_data
  def write_save_data(file)
    os_wsd(file)
    Marshal.dump($mp3_case, file)
  end
end
Don't forget to pass in the argument into the aliased write_save_data. That's all I saw at a glance.

Good luck with it xgamexfreakx! :thumb:
 
Thanks. It fixed that problem...on to the next.
Now i am getting an error when i try to add a song. The error reads:

Script 'MP3 Player' line 8: Type error occured
cannot convert fixnum into array

The script that i am using to add a song is this:
Code:
$mp3_case.add_item(034)
(034 is the item #) Once again i have been stumped by scripting. Help would be very much appreciated!

EDIT: i think I fixed the problem. i just switched the + and the = signs around an it worked! New problem though...(too many bugs! ':|)

Now when i try to run the MP3 player, I get a new error:

Script 'window_command' line 40:Typeerror occurred.
Cannot convert Fixnum into String

(This is the standard Window_Command script and this is the only custom script running)
when you run the mp3 player from the menu, it calls a common event that says:
Code:
$scene = Scene_MP3.new
so it should bring up a window with all the songs in it, (I think) If it is trying to draw a window.
Now i don't really understand this. if it wants a string, can't it just be edited into a print or a 'p' function???
I am probably way off here but who knows, i may figure it out just messing with it.
 

khmp

Sponsor

All right I'm going to give you help on this. Everything I say is for the sake of constructive criticism. First right off the bat comments. I think you omitted them because you were unsure of what the code accomplished. But their absence is a terrible thing when someone else is reading your code. Besides writing the comments not only helps you better understand the code but even if its wrong as soon as someone else reads they can help you better understand where you went wrong. Since that's out of the way lets look at the code.

First we'll go through this MP3_Case class. I'm unsure what its meant to accomplish aside from holding an array of integers/strings? Which is okay but kind of overkill in Ruby because the Array object is so flexible. Anyway let's make this a little more readable.

Code:
class MP3_Case
  attr_accessor :contents
  def initialize
    @contents = []
  end
  
  def add_item(item_id)
    @contents += item_id
    return
  end
  
  def delete_item(item_id)
    for i in 0..@contents.size - 1
      if @contents[i] == item_id
        @contents.delete_at(i)
        return
      end
    end
    return
  end
end
Code:
#==============================================================================
# ** MP3_Case
#------------------------------------------------------------------------------
#  This class will hold the possible ids of playable mp3s.
#==============================================================================

class MP3_Case
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :contents
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    # Declare an empty @contents Array.
    @contents = []
  end
  #--------------------------------------------------------------------------
  # * Add Item
  #     item_id : id of the item you wish to add
  #--------------------------------------------------------------------------  
  def add_item(item_id)
    # Append the item into @contents Array.
    @contents << item_id
  end
  #--------------------------------------------------------------------------
  # * Delete Item
  #     item_id : id of the item you wish to remove
  #--------------------------------------------------------------------------  
  def delete_item(item_id)
    # Delete all incidences of 'item_id' in @contents.
    @contents.delete(item_id)
  end
end

There is no need to place a return at the end of either add_item or delete_item. As soon as it executes all the lines of code inside the method it returns automatically, barring looping :P. I'd recommend passing strings into these methods as well and then the conversion error from fixnum integer to string won't occur. Now in the delete_item method you iterated through each element making a comparison and based on whether the item was found deleted it. You'd have to do that in probably every other language but Ruby has a built-in delete for an Array object. And that class becomes a heck of a lot shorter. Almost enough so that the code can go somewhere else and there is no need for this class. But I want you to decide that.

Onto Scene_MP3:

Code:
class Scene_MP3
  def initialize
    $spriteset = Spriteset_Map.new
    @window_mp3 = Window_Command.new(160, $mp3_case.contents)
  end
  
  def main
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
    end
    Graphics.freeze
    $spriteset.dispose
    @window_mp3.dispose
  end
  
  def update
    $spriteset.update
    @window_mp3.update
    update_action
  end
  
  def update_action
    # 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)
      $game_system.bgm_play("#{@window_mp3[@window_mp3.index]}.mp3")
      $scene = Scene_Map.new
    end
  end
Code:
#==============================================================================
# ** Scene_MP3
#------------------------------------------------------------------------------
#  This screen will show the available mp3s.
#==============================================================================

class Scene_MP3
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------  
  def initialize
    @sps_mapback = Spriteset_Map.new
    @window_mp3 = Window_Command.new(160, $mp3_case.contents)
  end
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------  
  def main
    # We transition the graphics so the last Graphics.freeze is turned off.
    Graphics.transition
    
    # Loop so we can update
    loop do
      Graphics.update
      Input.update
      update
      # We want to eventually be able to break the loop.
      break if $scene != self
    end
    
    # Freeze graphics to properly remove graphical elements.
    Graphics.freeze
    
    # Remove of disposable resources.
    @sps_mapback.dispose
    @window_mp3.dispose
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------  
  def update
    @window_mp3.update
    update_action
  end
  #--------------------------------------------------------------------------
  # * Frame Update : Input
  #--------------------------------------------------------------------------
  def update_action
    # 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)
      $game_system.bgm_play("#{$mp3_case.contents[@window_mp3.index]}.mp3")
      $scene = Scene_Map.new
    end
  end
end

This really didn't need a lot of changes. I just added a few comments to help you better understand the code. At least I hope they do. I also changed the global scope spriteset_map variable to a class scope variable. Not a big deal but it doesn't look good. One last thing. If lets say you throw 3 items into this array through a common event. Then when you save it saves the array. Now when you load that save it will load the array and when the common event that is used to add the 3 items runs it adds 3 duplicates into the array. The rest looks fine commenting aside.

Run common event:
@contents = [1,2,3]

Save the game. Exit.
@contents = nil

Load saved game
@contents = [1,2,3]

Run common event:
@contents = [1,2,3,1,2,3]

But this is only a problem if your loading the array every time you create the scene this could happen. The other big problem is, again, the fact that you were storing numbers instead of strings. Where ever you're calling $mp3_case.contents.add_item use '' around the argument. Say the mp3 was 034.mp3
you would use $mp3_case.contents.add_item('034'). Got it? :D

Good luck with it xgamexfreakx! :thumb:
 
khmp;320161 said:
All right I'm going to give you help on this. Everything I say is for the sake of constructive criticism. First right off the bat comments. I think you omitted them because you were unsure of what the code accomplished. But their absence is a terrible thing when someone else is reading your code. Besides writing the comments not only helps you better understand the code but even if its wrong as soon as someone else reads they can help you better understand where you went wrong. Since that's out of the way lets look at the code.

First, I am all for any help I can get. It can be constructive criticism like you said, or someone just ranting on how bad I am at this and telling me how to fix it. Either way helps. Second, I didn't write this. It was written by optimist shadow in an earlier request. I chose not to use this at first, but my other option isn't working so I have fallen back to this. I know almost nothing of scripting. All I know is basic variables, what they are. It is pretty sad really.
khmp;320161":2jp59ba8 said:
First we'll go through this MP3_Case class. I'm unsure what its meant to accomplish aside from holding an array of integers/strings? Which is okay but kind of overkill in Ruby because the Array object is so flexible. Anyway let's make this a little more readable.

Code:
class MP3_Case
  attr_accessor :contents
  def initialize
    @contents = []
  end
  
  def add_item(item_id)
    @contents += item_id
    return
  end
  
  def delete_item(item_id)
    for i in 0..@contents.size - 1
      if @contents[i] == item_id
        @contents.delete_at(i)
        return
      end
    end
    return
  end
end
Code:
#==============================================================================
# ** MP3_Case
#------------------------------------------------------------------------------
#  This class will hold the possible ids of playable mp3s.
#==============================================================================

class MP3_Case
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :contents
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    # Declare an empty @contents Array.
    @contents = []
  end
  #--------------------------------------------------------------------------
  # * Add Item
  #     item_id : id of the item you wish to add
  #--------------------------------------------------------------------------  
  def add_item(item_id)
    # Append the item into @contents Array.
    @contents << item_id
  end
  #--------------------------------------------------------------------------
  # * Delete Item
  #     item_id : id of the item you wish to remove
  #--------------------------------------------------------------------------  
  def delete_item(item_id)
    # Delete all incidences of 'item_id' in @contents.
    @contents.delete(item_id)
  end
end

There is no need to place a return at the end of either add_item or delete_item. As soon as it executes all the lines of code inside the method it returns automatically, barring looping :P. I'd recommend passing strings into these methods as well and then the conversion error from fixnum integer to string won't occur. Now in the delete_item method you iterated through each element making a comparison and based on whether the item was found deleted it. You'd have to do that in probably every other language but Ruby has a built-in delete for an Array object. And that class becomes a heck of a lot shorter. Almost enough so that the code can go somewhere else and there is no need for this class. But I want you to decide that.
Basically, this code (the entire thing, not just this part) is meant to hold "items". When you use the Mp3 player, it checks for those items to see which songs you have. After it runs a check, it would display the songs you have and allow you to select the one you want to listen to. (Almost like the option in the RPG Maker that lets you listen to music while you are working).
khmp;320161":2jp59ba8 said:
Onto Scene_MP3:

Code:
class Scene_MP3
  def initialize
    $spriteset = Spriteset_Map.new
    @window_mp3 = Window_Command.new(160, $mp3_case.contents)
  end
  
  def main
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
    end
    Graphics.freeze
    $spriteset.dispose
    @window_mp3.dispose
  end
  
  def update
    $spriteset.update
    @window_mp3.update
    update_action
  end
  
  def update_action
    # 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)
      $game_system.bgm_play("#{@window_mp3[@window_mp3.index]}.mp3")
      $scene = Scene_Map.new
    end
  end
Code:
#==============================================================================
# ** Scene_MP3
#------------------------------------------------------------------------------
#  This screen will show the available mp3s.
#==============================================================================

class Scene_MP3
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------  
  def initialize
    @sps_mapback = Spriteset_Map.new
    @window_mp3 = Window_Command.new(160, $mp3_case.contents)
  end
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------  
  def main
    # We transition the graphics so the last Graphics.freeze is turned off.
    Graphics.transition
    
    # Loop so we can update
    loop do
      Graphics.update
      Input.update
      update
      # We want to eventually be able to break the loop.
      break if $scene != self
    end
    
    # Freeze graphics to properly remove graphical elements.
    Graphics.freeze
    
    # Remove of disposable resources.
    @sps_mapback.dispose
    @window_mp3.dispose
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------  
  def update
    @window_mp3.update
    update_action
  end
  #--------------------------------------------------------------------------
  # * Frame Update : Input
  #--------------------------------------------------------------------------
  def update_action
    # 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)
      $game_system.bgm_play("#{$mp3_case.contents[@window_mp3.index]}.mp3")
      $scene = Scene_Map.new
    end
  end
end

This really didn't need a lot of changes. I just added a few comments to help you better understand the code. At least I hope they do. I also changed the global scope spriteset_map variable to a class scope variable. Not a big deal but it doesn't look good. One last thing. If lets say you throw 3 items into this array through a common event. Then when you save it saves the array. Now when you load that save it will load the array and when the common event that is used to add the 3 items runs it adds 3 duplicates into the array. The rest looks fine commenting aside.

Run common event:
@contents = [1,2,3]

Save the game. Exit.
@contents = nil

Load saved game
@contents = [1,2,3]

Run common event:
@contents = [1,2,3,1,2,3]

But this is only a problem if your loading the array every time you create the scene this could happen. The other big problem is, again, the fact that you were storing numbers instead of strings. Where ever you're calling $mp3_case.contents.add_item use '' around the argument. Say the mp3 was 034.mp3
you would use $mp3_case.contents.add_item('034'). Got it? :D

Good luck with it xgamexfreakx! :thumb:

If you can think of a better way to write this, (I am pretty sure you could) please do. As I said earlier, I am a total scripting noob. I'll try out the changes you said to do, when I get home from school. And if you want, I can post a demo with everything I am using to test this. Thanks!
 
I'll see what I can do. All my files are at home on my comp, so I'll try and upload them after school.

EDIT: Here is the file I have been using. Let me know if it is a broken link.

http://www.mediafire.com/?e0b4fdgh2z1

Sorry for the wait to upload. This was just a fast and easy place to host the file untill I can upload it onto my website.

EDIT: Changed the upload link to media fire
 

khmp

Sponsor

Code:
#==============================================================================
# ** MP3_Case
#------------------------------------------------------------------------------
#  This class will hold the possible ids of playable mp3s.
#==============================================================================

class MP3_Case
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :contents
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    # Declare an empty @contents Array.
    @contents = []
  end
  #--------------------------------------------------------------------------
  # * Add Item
  #     item_id : id of the item you wish to add
  #--------------------------------------------------------------------------  
  def add_item(item_id)
    # Return if the contents already has the mp3name.
    return if @contents.include?(item_id)
    # Append the item into @contents Array.
    @contents << item_id
  end
  #--------------------------------------------------------------------------
  # * Delete Item
  #     item_id : id of the item you wish to remove
  #--------------------------------------------------------------------------  
  def delete_item(item_id)
    # Delete all incidences of 'item_id' in @contents.
    @contents.delete(item_id)
  end
end

#==============================================================================
# ** Scene_MP3
#------------------------------------------------------------------------------
#  This screen will show the available mp3s.
#==============================================================================

class Scene_MP3
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------  
  def initialize
    @sps_mapback = Spriteset_Map.new
    @window_mp3 = Window_Command.new(160, $mp3_case.contents)
  end
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------  
  def main
    # We transition the graphics so the last Graphics.freeze is turned off.
    Graphics.transition
    
    # Loop so we can update
    loop do
      Graphics.update
      Input.update
      update
      # We want to eventually be able to break the loop.
      break if $scene != self
    end
    
    # Freeze graphics to properly remove graphical elements.
    Graphics.freeze
    
    # Remove of disposable resources.
    @sps_mapback.dispose
    @window_mp3.dispose
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------  
  def update
    @sps_mapback.update
    @window_mp3.update
    update_action
  end
  #--------------------------------------------------------------------------
  # * Frame Update : Input
  #--------------------------------------------------------------------------
  def update_action
    # 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)
      bgm = RPG::AudioFile.new("#{$mp3_case.contents[@window_mp3.index]}",
                                100, # Volume (Default: 100)
                                100) # Pitch  (Default: 100)
      $game_system.bgm_play(bgm)
      $scene = Scene_Map.new
    end
  end
end

#==============================================================================
# ** Scene_Title
#------------------------------------------------------------------------------
#  This class performs title screen processing.
#==============================================================================

class Scene_Title
  alias os_cng command_new_game
  def command_new_game
    $mp3_case = MP3_Case.new
    os_cng
  end
end

#==============================================================================
# ** Scene_Save
#------------------------------------------------------------------------------
#  This class performs save screen processing.
#==============================================================================

class Scene_Save
  alias os_wsd write_save_data
  def write_save_data(file)
    os_wsd(file)
    Marshal.dump($mp3_case, file)
  end
end

#==============================================================================
# ** Scene_Load
#------------------------------------------------------------------------------
#  This class performs load screen processing.
#==============================================================================

class Scene_Load
  def read_save_data(file)
    # Read character data for drawing save file
    characters = Marshal.load(file)
    # Read frame count for measuring play time
    Graphics.frame_count = Marshal.load(file)
    # Read each type of game object
    $game_system        = Marshal.load(file)
    $game_switches      = Marshal.load(file)
    $game_variables     = Marshal.load(file)
    $game_self_switches = Marshal.load(file)
    $game_screen        = Marshal.load(file)
    $game_actors        = Marshal.load(file)
    $game_party         = Marshal.load(file)
    $game_troop         = Marshal.load(file)
    $game_map           = Marshal.load(file)
    $game_player        = Marshal.load(file)
    $mp3_case           = Marshal.load(file)
    # If magic number is different from when saving
    # (if editing was added with editor)
    if $game_system.magic_number != $data_system.magic_number
      # Load map
      $game_map.setup($game_map.map_id)
      $game_player.center($game_player.x, $game_player.y)
    end
    # Refresh party members
    $game_party.refresh
  end
end

Change the way you add songs in the event to the right of the player at the start. The call script event command should be this:
Code:
$mp3_case.add_item('034')
not
Code:
$mp3_case.add_item(034)

I changed the add_item method to only add items that don't already exist in the contents. The reason it was saying conversion error fixnum to string was because $game_system.play_bgm takes a RPG::Audiofile not just a string or an integer. So I changed the update_action method in Scene_MP3 to create one for you. If you have any more problems first make sure you are adding "strings" or 'strings' and not strings into the add_item method.
Ex: [034 < Wrong], ['034' < Correct], ["034" < Correct]

Good luck with your game xgamerxfreakx! :thumb:
 
All the past problems have been fixed. Now when you select the Mp3 Player from the menu, it bring up the Menu like it should. Now the problem is that when you try to select the song, it tries to play the song called "034" Which is obviously not a song. I am guessing that somewhere in the script you would have to add a line that says that item 034 is a song battle01. or it could be something to edit in the database.
Also, If you could make all of the characters on the map disapear, it would be greatly appreciated. Thanks!
 

khmp

Sponsor

Hardcoding a script to interpret 034 as battle01 is a bad thing. If you use call script and use $mp3_case.add_item('battle01') it will play battle01 when its selected from the mp3 screen. Making the characters disappear is a simple task those. Just do a search through the script and remove the lines with @sps_mapback in it. That includes the initialization, update, and disposal. If you have any more problems don't hesitate to ask.

Good luck xgamerxfreakx! :thumb:
 
Everything is working great now! Thanks a lot! Just one final question though...Could you modify the script to allow an option to return to the default BGM?? (The one set in the Map Parameters..) If so...it would be greatly apprecated..
 

khmp

Sponsor

Yes it is possible but how do you want to accomplish it? Do you want it to be a choice given when the user enters Scene_MP3? Or do you want it to be a particular keystroke during Scene_Map that turns it off and sets it back to the default background music? Sorry for answering your question with another question? Sorry about that.
 

khmp

Sponsor

All right consider it done I think. I can't test it just yet. I'm going off the code from before. Added a boolean to Game_System to make sure I doesn't memorize the bgm every time Scene_MP3 started.

So I want you to replace Scene_MP3:
Code:
#==============================================================================
# ** Scene_MP3
#------------------------------------------------------------------------------
#  This screen will show the available mp3s.
#==============================================================================

class Scene_MP3
  SZ_DEFAULT = 'default'
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------  
  def initialize
    list = $mp3_case.contents.dup
    list << SZ_DEFAULT
    @window_mp3 = Window_Command.new(160, list)
    if $game_system.b_restore == false || $game_system.b_restore == nil
      p 'bgm saved'
      $game_system.bgm_memorize
      $game_system.b_restore = true
    end
  end
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------  
  def main
    # We transition the graphics so the last Graphics.freeze is turned off.
    Graphics.transition
    
    # Loop so we can update
    loop do
      Graphics.update
      Input.update
      update
      # We want to eventually be able to break the loop.
      break if $scene != self
    end
    
    # Freeze graphics to properly remove graphical elements.
    Graphics.freeze
    
    # Remove of disposable resources.
    @window_mp3.dispose
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------  
  def update
    @window_mp3.update
    update_action
  end
  #--------------------------------------------------------------------------
  # * Frame Update : Input
  #--------------------------------------------------------------------------
  def update_action
    # 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)
      # The user wants the default background music to play
      if @window_mp3.index == $mp3_case.contents.size
        p 'bgm restored'
        $game_system.bgm_restore
        $game_system.b_restore = false
      else
        bgm = RPG::AudioFile.new("#{$mp3_case.contents[@window_mp3.index]}",
                                  100, # Volume (Default: 100)
                                  100) # Pitch  (Default: 100)
        $game_system.bgm_play(bgm)
        $scene = Scene_Map.new 
      end
    end
  end
end

Also add in this code:
Code:
#==============================================================================
# ** Game_System
#------------------------------------------------------------------------------
#  This class handles data surrounding the system. Backround music, etc.
#  is managed here as well. Refer to "$game_system" for the instance of 
#  this class.
#==============================================================================

class Game_System
  attr_accessor :b_restore
end

If you want to alter the string it says at the bottom of the command window when you run Scene_MP3 do a search for SZ_DEFAULT and replace the string in the single quotes.

Good luck with your game xgamexfreakx! :thumb:
 
Unfortunately it doesn't work......

When you open the MP3 Player, a popup appears and says "bgm saved" or something along those lines. Then you can select your song and it closes out. Now if you want to revert back, you open up the mp3 player again. When you do this it saves the BGM again. When you click the button to restore the default music, another popup appears and it says "BGM restored". But it doesn't revert back to the original song or close out of the menu. I am guessing that this is just some minor little problem, but for all I know, it could be really big.

Another thing, say I wanted to picture in the background. I would just add in the common event, "Show Picture X" and then it would show up behind the new scene window right? And then to get rid of it I would have to add something in the script that tells the picture to go away. What would that be? If it to too long and bothersome you don't have to add it in. I was just wondering......

Thanks
 

OS

Sponsor

Oh, man. I can't believe this. I thought it worked. It was one of my less tested scripts. Well, I'm sorry for any lack of support on the script, xgamexfreakx. And khmp, I'll keep in mind what you posted before. I have improved since writing this particular script.

As for helping now, the only reason why it would do that (or at least the most obvious reason I can think of) is because the script memorizes the bgm every time it is accessed, which means the variable b_restore is turned false or nil when the script is done processing. But I can see from the script that this isn't happening, so...idk.

If ever you want another script, I'll be sure it works 100% next time.
 

khmp

Sponsor

OptimistShadow;321641 said:
As for helping now, the only reason why it would do that (or at least the most obvious reason I can think of) is because the script memorizes the bgm every time it is accessed, which means the variable b_restore is turned false or nil when the script is done processing. But I can see from the script that this isn't happening, so...idk.

The boolean is only altered if:
a. The boolean has yet to be defined, meaning first entry into the Scene initialize. Memorize the current bgm, turn the boolean true.
b. The boolean is false, meaning that default was selected the last time the Scene ran. Memorize the current BGM, turn the boolean true.
Then if the user selects default in the update_action method. It will turn the boolean off and restore the BGM. The next time Scene_MP3 runs it saves the BGM because the boolean was false. And the pattern is repeated.

Another approach to avoid the use of a boolean would be figuring out what the autoplay_bgm for the map that was just left was and just playing that when the user selects default from the 'update_action' method. But because the Scene_MP3 isn't directly accessed from Scene_Map you'd need to store the BGM somewhere in global scope. But storing a BGM instead of a boolean variable isn't memory efficient but then again its Ruby so I'm not sure about that.

Now for you gamexfreakx:

I tried this code on my pc and it behaves as it should including the memorization and restoration of the default bgm playing upon the execution of Scene_MP3. I just tested it by placing an *.mp3 in the Audio/BGM folder. Those messages were just for helping you. To remove those get rid of the p statements.

So here's what I have in the code section w/ removed 'p' lines:

Code:
#==============================================================================
# ** MP3_Case
#------------------------------------------------------------------------------
#  This class will hold the possible ids of playable mp3s.
#==============================================================================

class MP3_Case
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :contents
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    # Declare an empty @contents Array.
    @contents = []
  end
  #--------------------------------------------------------------------------
  # * Add Item
  #     item_id : id of the item you wish to add
  #--------------------------------------------------------------------------  
  def add_item(item_id)
    # Return if the contents already has the mp3name.
    return if @contents.include?(item_id)
    # Append the item into @contents Array.
    @contents << item_id
  end
  #--------------------------------------------------------------------------
  # * Delete Item
  #     item_id : id of the item you wish to remove
  #--------------------------------------------------------------------------  
  def delete_item(item_id)
    # Delete all incidences of 'item_id' in @contents.
    @contents.delete(item_id)
  end
end

#==============================================================================
# ** Game_System
#------------------------------------------------------------------------------
#  This class handles data surrounding the system. Backround music, etc.
#  is managed here as well. Refer to "$game_system" for the instance of 
#  this class.
#==============================================================================

class Game_System
  attr_accessor :b_restore
end

#==============================================================================
# ** Scene_MP3
#------------------------------------------------------------------------------
#  This screen will show the available mp3s.
#==============================================================================

class Scene_MP3
  #--------------------------------------------------------------------------
  # * Constants
  #--------------------------------------------------------------------------   
  SZ_DEFAULT = 'default' # Change this to alter what option appears last
  SZ_PICTURE = 'your_picture.bmp/png/jpg' # Change this to the picture in the back
  #^ That will crash if you don't change it.
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------  
  def initialize
    list = $mp3_case.contents.dup
    list << SZ_DEFAULT
    @sp_picture = Sprite.new
    @sp_picture.bitmap = RPG::Cache.picture(SZ_PICTURE)
    @window_mp3 = Window_Command.new(160, list)
    if $game_system.b_restore == false || $game_system.b_restore == nil
      $game_system.bgm_memorize
      $game_system.b_restore = true
    end
  end
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------  
  def main
    # We transition the graphics so the last Graphics.freeze is turned off.
    Graphics.transition
    
    # Loop so we can update
    loop do
      Graphics.update
      Input.update
      update
      # We want to eventually be able to break the loop.
      break if $scene != self
    end
    
    # Freeze graphics to properly remove graphical elements.
    Graphics.freeze
    
    # Remove of disposable resources.
    @sp_picture.bitmap.dispose
    @sp_picture.dispose
    @window_mp3.dispose
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------  
  def update
    @window_mp3.update
    update_action
  end
  #--------------------------------------------------------------------------
  # * Frame Update : Input
  #--------------------------------------------------------------------------
  def update_action
    # 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)
      # The user wants the default background music to play
      if @window_mp3.index == $mp3_case.contents.size
        $game_system.bgm_restore
        $game_system.b_restore = false
        $scene = Scene_Map.new
      else
        bgm = RPG::AudioFile.new("#{$mp3_case.contents[@window_mp3.index]}",
                                  100, # Volume (Default: 100)
                                  100) # Pitch  (Default: 100)
        $game_system.bgm_play(bgm)
        $scene = Scene_Map.new 
      end
    end
  end
end

#==============================================================================
# ** Scene_Title
#------------------------------------------------------------------------------
#  This class performs title screen processing.
#==============================================================================

class Scene_Title
  alias os_cng command_new_game
  def command_new_game
    $mp3_case = MP3_Case.new
    os_cng
  end
end

#==============================================================================
# ** Scene_Save
#------------------------------------------------------------------------------
#  This class performs save screen processing.
#==============================================================================

class Scene_Save
  alias os_wsd write_save_data
  def write_save_data(file)
    os_wsd(file)
    Marshal.dump($mp3_case, file)
  end
end

#==============================================================================
# ** Scene_Load
#------------------------------------------------------------------------------
#  This class performs load screen processing.
#==============================================================================

class Scene_Load
  def read_save_data(file)
    # Read character data for drawing save file
    characters = Marshal.load(file)
    # Read frame count for measuring play time
    Graphics.frame_count = Marshal.load(file)
    # Read each type of game object
    $game_system        = Marshal.load(file)
    $game_switches      = Marshal.load(file)
    $game_variables     = Marshal.load(file)
    $game_self_switches = Marshal.load(file)
    $game_screen        = Marshal.load(file)
    $game_actors        = Marshal.load(file)
    $game_party         = Marshal.load(file)
    $game_troop         = Marshal.load(file)
    $game_map           = Marshal.load(file)
    $game_player        = Marshal.load(file)
    $mp3_case           = Marshal.load(file)
    # If magic number is different from when saving
    # (if editing was added with editor)
    if $game_system.magic_number != $data_system.magic_number
      # Load map
      $game_map.setup($game_map.map_id)
      $game_player.center($game_player.x, $game_player.y)
    end
    # Refresh party members
    $game_party.refresh
  end
end

I added the picture thing in and it can be done all in code. Do a search for these two constants inside class Scene_MP3.

1.) SZ_DEFAULT = 'default'(replace the text inside the quotes to alter the last option that switches it back to the default BGM).

2.) SZ_PICTURE = 'your_picture.bmp/png/jpg'(replace the text inside the quotes to the filename of the picture inside the Graphics/Pictures that you want displayed as the background).

Good luck with it xgamexfreakx! :thumb:

PS: If you have any further trouble I'm going to need you to reupload the project sadly. It's the only way I think I can help you properly, sorry.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top