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.

Trouble with window.dispose

I've made a custom window to show the party's exp and other stats. Everything works fine, but for some reason the window stays on screen even after the battle scene ends (but only sometimes). I have used the .dispose method, and from what I can tell, my custom window is initialized and terminated identically to the other windows in the RMXP scripts. Is there some trick that I should know about? Why would the .dispose method fail to erase the window from the screen only sometimes? Any help would be greatly appreciated. Thanks.

note: I have tried setting the opacity of the window and its contents to 0 before calling the dispose method, and I have tried calling the update method (super class window_base), but nothing seems to work, it's like the computer ignores what I tell it to do with the window after a certain point.
 
Yeah, probably should have done that in the first place. Here's the part of scene battle that involves the windows I'm referring to. @end_window, and @end_exp_window are the two windows that are staying on screen.

[rgss] 
  #--------------------------------------------------------------------------
  # * Start After Battle Phase
  #--------------------------------------------------------------------------
  def start_phase5
    # Shift to phase 5
    @phase = 5
    # Play battle end ME
    $game_system.me_play($game_system.battle_end_me) unless $game_system.no_victory_music == true
    # Return to BGM before battle started
    $game_system.bgm_play($game_temp.map_bgm) unless $game_system.no_change_bgm == true
    # Initialize EXP, amount of gold, and treasure
    @exp = 0
    @gold_found = 0
    treasures = []
    @exp_count_down = false
    # Loop
    for enemy in $game_troop.enemies
      # If enemy is not hidden
      unless enemy.hidden
        # Add EXP and amount of gold obtained
        @exp += enemy.exp
        @gold_found += enemy.gold
        # Determine if treasure appears
        if rand(100) < enemy.treasure_prob
          if enemy.item_id > 0
            treasures.push($data_items[enemy.item_id])
          end
          if enemy.weapon_id > 0
            treasures.push($data_weapons[enemy.weapon_id])
          end
          if enemy.armor_id > 0
            treasures.push($data_armors[enemy.armor_id])
          end
        end
      end
    end
    # Treasure is limited to a maximum of 6 items
    treasures = treasures[0..5]
    # Obtaining EXP
    for i in 0...$game_party.actors.size
      actor = $game_party.actors
      #if actor.cant_get_exp? == false
        #last_level = actor.level
        #actor.exp += exp
        #if actor.level > last_level
        #  @status_window.level_up(i)
        #end
      #end
      if !$game_party.actors.dead?
        $game_party.actors.add_sp(@exp)
      end
      # My leveling system will consist of absorbing attribute stones
        #@stat_increases = actor.add_sp()
        @end_window = End_Battle_Stats.new(@gold_found)
        @end_exp_window = XP_Window.new(@exp)
      #  if i == 0
      #    @stat_picture0 = Show_Stat_Boost.new(@stat_increases, i)
      #  elsif i == 1
      #    @stat_picture1 = Show_Stat_Boost.new(@stat_increases, i)
      #  elsif i == 2
      #    @stat_picture2 = Show_Stat_Boost.new(@stat_increases, i)
      #  elsif i == 3
      #    @stat_picture3 = Show_Stat_Boost.new(@stat_increases, i)
      #  end
    end
    # Obtaining gold
    $game_party.gain_gold(@gold_found)
    # Obtaining treasure
    for item in treasures
      case item
      when RPG::Item
        $game_party.gain_item(item.id, 1)
      when RPG::Weapon
        $game_party.gain_weapon(item.id, 1)
      when RPG::Armor
        $game_party.gain_armor(item.id, 1)
      end
    end
    # Make battle result window
    @result_window = Window_BattleResult.new(@exp, @gold_found, treasures)
    # Set wait count
    @phase5_wait_count = 100
  end
  #--------------------------------------------------------------------------
  # * Frame Update (after battle phase)
  #--------------------------------------------------------------------------
  def update_phase5
    #If wait count is larger than 0
    #if @phase5_wait_count > 0
    #  # Decrease wait count
    #  @phase5_wait_count -= 1
    #  # If wait count reaches 0
    #  if @phase5_wait_count == 0
    #    # Show result window
    #    @result_window.visible = true
    #    # Clear main phase flag
    #    $game_temp.battle_main_phase = false
    #    # Refresh status window
    #    @status_window.refresh
    #  end
    #  return
    #end
   
    #This is now the phase where your EXP is given to your party
    if @exp_count_down
      if @exp > 0
        Audio.se_play("Audio/SE/001-System01", 80, 150)
        for i in 0...$game_party.actors.size
          if !$game_party.actors.dead?
            stat_increase = $game_party.actors.add_sp(1)
            for n in 0...stat_increase.size
              if stat_increase != nil
                @end_window.stat_increase(stat_increase, i)
              end
            end
          end
        end
        @exp -= 1
      end
      #@end_window.dispose
      #@end_window = End_Battle_Stats(@exp)
    end
    @end_window.refresh
    @end_exp_window.refresh(@exp)
    # If C button was pressed
    if Input.trigger?(Input::C)
      if @exp_count_down != true
        @exp_count_down = true
      elsif @exp_count_down == true and @exp > 0
        Audio.se_play("Audio/SE/001-System01", 80, 150)
        for i in 0...$game_party.actors.size
          if !$game_party.actors.dead?
            stat_increase = $game_party.actors.add_sp(@exp)
            for n in 0...stat_increase.size
              if stat_increase != nil
                @end_window.stat_increase(stat_increase, i)
              end
            end
          end
        end
        @exp = 0
      else
        # Battle ends
        @end_window.dispose
        @end_exp_window.dispose
        battle_end(0)
      end
    end
  end
end
 
[/rgss]

Then here is the End_Battle_Stats class

[rgss] 
class End_Battle_Stats < Window_Base
  attr_accessor :main_counter
  def initialize(gold)
    super(0, 0, 150*$game_party.actors.size + 32, 250)
    self.contents = Bitmap.new(self.width - 32, self.height - 32)
    self.contents.font = Font.new("Franklin Gothic Medium", 20)
    self.x = (640 - self.width)/2
    self.y = ((359 - self.height)/2) + 32
    @gold = gold
    @viewport = Viewport.new(0, 0, 640, 480)
    @viewport.z = 10000
    @stat_grid = Array.new(4)
    @stat_counters = Array.new(4)
    @main_counter = 20
    for i in 0...@stat_grid.size
      @stat_grid = Array.new(4)
      @stat_counters = Array.new(4)
      for n in 0...@stat_grid.size
        @stat_grid[n] = Sprite.new(@viewport)
        @stat_grid[n].bitmap = RPG::Cache.picture("Stat increase")
        @stat_grid[n].visible = false
      end
    end
  end
 
  def refresh
    self.contents.clear
    self.update
    for i in 0...$game_party.actors.size
      x = 4 + i*150
      y = 0
      draw_actor_name($game_party.actors, x, y)
      draw_actor_exp_battle($game_party.actors, x, y+16)
      # Set up weapon and armor progress bars
      draw_special_item_name($game_party.actors, 0, $data_weapons[$game_party.actors.weapon_id], x, y+57)
      draw_special_item_name($game_party.actors, 1, $data_armors[$game_party.actors.armor3_id], x, y+57+32)
      draw_special_item_name($game_party.actors, 2, $data_armors[$game_party.actors.stone1_id], x, y+57+32*2)
      draw_special_item_name($game_party.actors, 3, $data_armors[$game_party.actors.stone2_id], x, y+57+32*3)
    end
    # update stat increase graphic if it exists
    for i in 0...@stat_grid.size
      for n in 0...@stat_grid.size
        if @stat_grid[n].visible == true
          fraction = @stat_counters[n].to_f/5.0
          @stat_grid[n].opacity = (fraction*255.0).round
          if @stat_counters[n] == 0
            @stat_grid[n].visible = false
          else
            @stat_counters[n] -= 1
          end
        end
      end
    end
    if @main_counter >= 0
      fraction = 1.0-(@main_counter.to_f/20.0)
      self.opacity = (fraction*255).round
      self.contents_opacity = (fraction*255).round
      self.back_opacity = (fraction*255).round
      @main_counter -= 1
    end
  end
 
  def stat_increase(equip_type, id)
    for i in 0...equip_type.size
      if equip_type == true
        n = $game_party.actors[id].get_stat(i)
        #@stat_grid[id].src_rect.set(n*32, 0, 100, 100)
        #@stat_grid[id].x = self.x + id*150
        @stat_grid[id].x = 0
        @stat_grid[id].y = 0
        @stat_counters[id] = 5
      end
    end
  end
end
 
[/rgss]

And the XP_Window class:

[rgss] 
class XP_Window < Window_Base
  attr_accessor :main_counter
  def initialize(exp)
    super(0, 0, 150*$game_party.actors.size + 32, 64)
    self.x = (640 - self.width)/2
    self.y = ((359 - 250)/2) + 32 - 64
    self.contents = Bitmap.new(self.width - 32, self.height - 32)
    self.contents.font = Font.new("Franklin Gothic Medium", 20)
    @main_counter = 20
    #@exp_digits = [nil, nil, nil, nil]
    #@exp_sprites = Array.new(4)
    #for i in 0...4
    #  @exp_sprites = Sprite.new
    #  @exp_sprites.z = 10000
    #  @exp_sprites.visible = false
    #  @exp_sprites.bitmap = RPG::Cache.picture("number-sprite sheet")
    #end
    #isolate_digits(exp)
  end
 
  def isolate_digits(exp)
    @exp_digits = [nil, nil, nil, nil]
    #thousands
    if exp/1000 != 0
      @exp_digits[0] = exp/1000
    end
    #hundreds
    if exp/100 != 0
      exp = exp%1000
      @exp_digits[1] = exp/100
    end
    #tens
    if exp/10 != 0
      exp = exp%100
      @exp_digits[2] = exp/10
    end
    #ones
    exp = exp%10
    @exp_digits[3] = exp
    @exp_digits.compact!
  end
 
  def refresh(exp)
    #isolate_digits(exp)
    #for i in 0...@exp_digits.size
    #  @exp_sprites.x = self.x + 20 + (10*i)
    #  @exp_sprites.y = self.y + 25
    #  @exp_sprites.src_rect.set(@exp_digits*10, 0, 10, 13)
    #  @exp_sprites.visible = true
    #end
    self.contents.clear
    self.update
    self.contents.draw_text(0, 0, 80, 32, "Exp")
    self.contents.draw_text(120, 0, 100, 32, exp.to_s)
    if @main_counter >= 0
      fraction = 1.0-(@main_counter.to_f/20.0)
      self.opacity = (fraction*255).round
      self.contents_opacity = (fraction*255).round
      self.back_opacity = (fraction*255).round
      @main_counter -= 1
    end
  end
end
 
[/rgss]

and I'll go ahead and include the main method of scene battle since that's where the dispose methods occur

[rgss] 
class Scene_Battle
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------
  def main
    # Initialize each kind of temporary battle data
    $game_temp.in_battle = true
    $game_temp.battle_turn = 0
    $game_temp.battle_event_flags.clear
    $game_temp.battle_abort = false
    $game_temp.battle_main_phase = false
    $game_temp.battleback_name = $game_map.battleback_name
    $game_temp.forcing_battler = nil
    # Initialize battle event interpreter
    $game_system.battle_interpreter.setup(nil, 0)
    # Prepare troop
    @troop_id = $game_temp.battle_troop_id
    $game_troop.setup(@troop_id)
    # Make actor command window
    s1 = $data_system.words.attack
    s2 = $data_system.words.skill
    s3 = $data_system.words.guard
    s4 = $data_system.words.item
    #@actor_command_window = Window_Command.new(160, [s1, s2, s3, s4])
    @actor_command_window = Window_BattleCommand.new
    @actor_command_window.y = 160
    #@actor_command_window.back_opacity = 160
    @actor_command_window.active = false
    @actor_command_window.visible = true
    @actor_index = nil
    # Make other windows
    @party_command_window = Window_PartyCommand.new
    @help_window = Window_Help.new
    @help_window.back_opacity = 160
    @help_window.visible = false
    @status_window = Window_BattleStatus.new
    @message_window = Window_Message.new
    # Make sprite set
    @spriteset = Spriteset_Battle.new
    # Initialize this silly variable
    @command_window_already_open = false
    # Initialize wait count
    @wait_count = 0
    # Check for various accessory effects
    for i in 0...$game_party.actors.size
      # Pre emptive
      if $game_party.actors.accessory1_id == 4
        $game_party.actors.atb = $game_party.actors.get_delay
      elsif $game_party.actors.accessory2_id == 4
        $game_party.actors.atb = $game_party.actors.get_delay
      end
      # Inspector's Measure
      if $game_party.actors.accessory1_id == 3
        @spriteset.setup_inspector
        @inspector_visible = false
      elsif $game_party.actors.accessory2_id == 3
        @spriteset.setup_inspector
        @inspector_visible = false
      end
    end
    # Execute transition
    if $data_system.battle_transition == ""
      Graphics.transition(20)
    else
      Graphics.transition(40, "Graphics/Transitions/" +
        $data_system.battle_transition)
    end
    # Start pre-battle phase
    start_phase1
    # 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
    # Refresh map
    $game_map.refresh
    # Prepare for transition
    Graphics.freeze
    # Dispose of windows
    @actor_command_window.dispose
    @party_command_window.dispose
    @help_window.dispose
    @status_window.dispose
    @message_window.dispose
    if @skill_window != nil
      @skill_window.dispose
    end
    if @item_window != nil
      @item_window.dispose
    end
    if @result_window != nil
      @result_window.dispose
    end
    if @end_window != nil
      unless @end_window.disposed?
        @end_window.visible = false
        @end_window.dispose
      end
    end
    if @end_exp_window != nil
      unless @end_exp_window.disposed?
        @end_exp_window.visible = false
        @end_exp_window.dispose
      end
    end
    # Dispose of sprite set
    @spriteset.dispose
    # If switching to title screen
    if $scene.is_a?(Scene_Title)
      # Fade out screen
      Graphics.transition
      Graphics.freeze
    end
    # If switching from battle test to any screen other than game over screen
    if $BTEST and not $scene.is_a?(Scene_Gameover)
      $scene = nil
    end
  end
 
[/rgss]

you can ignore the @stat_grid and @stat_boost stuff in the End_Battle_Stats class, I haven't really implemented that completely yet and I can't imagine that it has anything to do with the problem (but who knows), and thanks for the reply.
 

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