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.

Displaying Hp and Sp...

Simple Request. I want to know how to edit the Ruby Script so that the Health Points (Hp), Special Points (Sp), And Experience Points (Exp) apear on the upper left corner of the screen. So that bars indicating how much is left of the Hp, Sp, and Exp are shown. Would it be possibe to also display the amount of gold?

I'd also appreciate is if someone could come up with a script similar to what I need but with icons indicating which bar is which. (E.g: Heart icon before health points bar (hp), Crystal icon before the special points bar (Sp), and maybe a book icon before the Experience points bar (Exp), and a gold coin before the amount of gold (non bar of course, just a number.)

I hope I explained myself in a way that someone got the idea. Thanks in advance :).
 

khmp

Sponsor

This is really more a request isn't it? But I like learning and I've never done bars before so I'll work on it if someone else isn't already. Do you just want the party leader's stats to appear in the upper left? You need to provide those icon images you want though :D

Alright here's what I did. I stole a piece of code from Near Fantastica's ABS about drawing gradient bars. Also I didn't know the names of the icons you want to use so do a search for the constant, "ICON_NAMES". Replace the strings with the .png extension on them with the name of the icons you want.
Code:
#==============================================================================
# ** Window_Base
#------------------------------------------------------------------------------
#  This class is for all in-game windows.
#==============================================================================

class Window_Base < Window
  #--------------------------------------------------------------------------
  # Credit for the methods below go to:
   #-------------------------------------------------------------------------
    # ** Action Battle System
    #------------------------------------------------------------------------
    #  By: Near Fantastica  
    #------------------------------------------------------------------------

  #--------------------------------------------------------------------------
  # * Draws Actors Hp meter
  #--------------------------------------------------------------------------
  def draw_actor_hp_bar(actor, x, y, width = 100, height = 10, bar_color = Color.new(255, 0, 0, 255))
    self.contents.fill_rect(x, y, width, height, Color.new(255, 255, 255, 100)) 
    w = width * actor.hp / actor.maxhp
    for i in 0..height
      r = bar_color.red   * (height -i)/height  + 0   * i/height 
      g = bar_color.green * (height -i)/height  + 0 * i/height 
      b = bar_color.blue  * (height -i)/height  + 0 * i/height 
      a = bar_color.alpha * (height -i)/height  + 255 * i/height 
      self.contents.fill_rect(x, y+i, w , 1, Color.new(r, g, b, a)) 
    end
  end
  #--------------------------------------------------------------------------
  # * Draws Actors Sp meter
  #--------------------------------------------------------------------------
  def draw_actor_sp_bar(actor, x, y, width = 100, height = 10, bar_color = Color.new(0, 0, 255, 255))
    self.contents.fill_rect(x, y, width, height, Color.new(255, 255, 255, 100)) 
    w = width * actor.sp / actor.maxsp
    for i in 0..height
      r = bar_color.red   * (height -i)/height  + 0   * i/height 
      g = bar_color.green * (height -i)/height  + 0 * i/height 
      b = bar_color.blue  * (height -i)/height  + 0 * i/height 
      a = bar_color.alpha * (height -i)/height  + 255 * i/height 
      self.contents.fill_rect(x, y+i, w , 1, Color.new(r, g, b, a)) 
    end
  end
  #--------------------------------------------------------------------------
  # * Draws Actors Exp meter
  #--------------------------------------------------------------------------
  def draw_actor_exp_bar(actor, x, y, width = 100, height = 10, bar_color = Color.new(255, 255, 0, 255))
    self.contents.fill_rect(x, y, width, height, Color.new(255, 255, 255, 100)) 
    if actor.level == 99
      w = 0
    else
      w = width * actor.exp / actor.next_exp_s.to_f
    end
    for i in 0..height
      r = bar_color.red   * (height -i)/height  + 0   * i/height 
      g = bar_color.green * (height -i)/height  + 0 * i/height 
      b = bar_color.blue  * (height -i)/height  + 0 * i/height 
      a = bar_color.alpha * (height -i)/height  + 255 * i/height 
      self.contents.fill_rect(x, y+i, w , 1, Color.new(r, g, b, a)) 
    end
  end
end

#==============================================================================
# ** Window_WabbitHUD
#------------------------------------------------------------------------------
#  This class shows the Hud window for pink wabbit.
#==============================================================================
class Window_PinkWabbitHUD < Window_Base
  # Constant used to store the name of the icons to be used in the window.
  ICON_NAMES = {
    'hp' => 'heart.png',
    'sp' => 'crystal.png',
    'ep' => 'book.png',
    'gp' => 'coin.png'
  }
  #--------------------------------------------------------------------------
  # * Initializes the object.
  #--------------------------------------------------------------------------
  def initialize
    super(0,0,160,150)
    self.contents = Bitmap.new(width - 32, height - 32)
    #self.opacity = 0
    refresh
  end
  #--------------------------------------------------------------------------
  # * Redraws the data items in the window.
  #--------------------------------------------------------------------------
  def refresh
    # Clear out the contents of the window.
    self.contents.clear
    
    # Some variables we'll need.
    x, y, actor = 0, 0, $game_party.actors[0]
    
    # Draw the Hitpoints of the Party Leader.
    bitmap = RPG::Cache.icon(ICON_NAMES['hp'])
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24))
    draw_actor_hp_bar(actor, x + 26, y + 9)
    
    # Draw the Skill Points of the Party Leader.
    y += 32
    bitmap = RPG::Cache.icon(ICON_NAMES['sp'])
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24))
    draw_actor_sp_bar(actor, x + 26, y + 9)
    
    # Draw the Experience of the Party Leader.
    y += 32
    bitmap = RPG::Cache.icon(ICON_NAMES['ep'])
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24))
    draw_actor_exp_bar(actor, x + 26, y + 9)
    
    # Draw the Gold
    y += 32
    bitmap = RPG::Cache.icon(ICON_NAMES['gp'])
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24))
    self.contents.font.color = Color.new(150,150,0,255)
    self.contents.draw_text(x + 26, y - 5, 100, 32, $game_party.gold.to_s, 2)
  end
  #--------------------------------------------------------------------------
  # * Checks to see if the window needs to be refreshed. 
  #--------------------------------------------------------------------------
  def update
    if Graphics.frame_count / Graphics.frame_rate != @total_sec
      refresh
    end
  end
end

#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
#  This class performs map screen processing.
#==============================================================================
class Scene_Map
  alias_method :old_main, :main
  alias_method :old_update, :update
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------
  def main
    @hud = Window_WabbitHUD.new
    old_main
    @hud.dispose
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    @hud.update
    old_update
  end
end
 
Let me offer some advice khmp:

1) Give your alias names a more dynamic name. Put yourname_scriptname_methodname. It lowers the likely hood of someone else giving it the same alias name.

2) You might want to make some instance variables in your window, then compare them. Something like
Code:
def refresh
  actor = $game_party.actors[0]
  return if @actor == actor || @actor_hp == actor.hp || @actor_sp == actor.sp || @actor_exp == actor.exp
  @actor, @actor_hp, @actor_sp, @actor_exp = actor, actor.hp, actor.sp, actor.exp
  # rest of your refresh code
end

With this, it doesn't refresh unless the actor changes or the hp, sp or exp changes.


You could further this by dividing it into sub-sections.
Code:
def refresh
  clear_color = Color.new(0, 0, 0, 0)
  if actor != @actor
    @actor = actor
    rect = Rect.new(0, 0, w, h)
    self.contents.fill_rect(rect, clear_color)
    # put your draw actor picture here
  end
  if @actor_hp != actor.hp
    @actor_hp = actor.hp
    # clear rect here
    # hp stuff here
  end
  # sp
  # exp
end

The difference here is, don't call self.contents.clear, instead, just create a Rect object (you need to define the x, y locations and width and height of it, and clear just that area. Then draw over it.

It's a way to reduce lag further, which I suggest if you are drawing enhanced gradient bars or something.
 

khmp

Sponsor

Advice is perfectly fine and very much appreciated. It's always a learning experience with you around.

1.) The dynamic script naming thing I should start to do that, mostly habit that I don't. If multiple alias_methods share the same name occur does it have a problem. Does the latest one take precedence like a method redefinition? Example:
Code:
class Thing
  alias_method :old_initialize, :initialize
  def initialize
    p 1
  end
end

class Thing
  alias_method :old_initialize, :initialize
  def initialize
    p 2
  end
end
Maybe I should just test that :D

2.) I try to avoid branch conditions C++ habit. Blame my C teacher is you must :D However the way it gets broken done into separate sections is way more efficient than the way I went about it.

3.) Lastly I didn't think about clearing only the rectangle portions of where drawing was occurring instead of clearing the whole of the contents. But from now on I will try to make use of it much like your beloved Hashes. :) Thanks SephirothSpawn for all the help mate. Just need a way to steal that knowledge base you call a brain and I'll be set.
 
1) It just creates a stack error. Think of it like this:

Code:
class Something
  def blah
    p 1
  end
end

# You add this:

class Something
  alias blah2 blah
  def blah
    p 2
    blah2
  end
end

# That gives you this:

class Something
  def blah
    p 2
    blah2
  end
  def blah2
    p 1
  end
end

So if you go an alias again, blah2 already exist, so an error occurs.

2) Hehe. That's understandable.

3) I didn't think of it until months after scripting, so I can't blame you there. Hehe.


Happy to share my brain with ya. ;)
 

khmp

Sponsor

Ok, taking SephirothSpawn's advice into practice here is the new code. Funny how Pink Wabbit probably won't come back, but I'm still glad I wrote the code :)

Code:
#==============================================================================
# ** Window_Base
#------------------------------------------------------------------------------
#  This class is for all in-game windows.
#==============================================================================

class Window_Base < Window
  #--------------------------------------------------------------------------
  # Credit for the methods below go to:
   #-------------------------------------------------------------------------
    # ** Action Battle System
    #------------------------------------------------------------------------
    #  By: Near Fantastica  
    #------------------------------------------------------------------------

  #--------------------------------------------------------------------------
  # * Draws Actors Hp meter
  #--------------------------------------------------------------------------
  def draw_actor_hp_bar(actor, x, y, width = 100, height = 10, 
    bar_color = Color.new(255, 0, 0, 255))
    self.contents.fill_rect(x, y, width, height, Color.new(255, 255, 255, 100)) 
    w = width * actor.hp / actor.maxhp
    for i in 0..height
      r = bar_color.red   * (height -i)/height  + 0   * i/height 
      g = bar_color.green * (height -i)/height  + 0 * i/height 
      b = bar_color.blue  * (height -i)/height  + 0 * i/height 
      a = bar_color.alpha * (height -i)/height  + 255 * i/height 
      self.contents.fill_rect(x, y+i, w , 1, Color.new(r, g, b, a)) 
    end
  end
  #--------------------------------------------------------------------------
  # * Draws Actors Sp meter
  #--------------------------------------------------------------------------
  def draw_actor_sp_bar(actor, x, y, width = 100, height = 10, 
    bar_color = Color.new(0, 0, 255, 255))
    self.contents.fill_rect(x, y, width, height, Color.new(255, 255, 255, 100)) 
    w = width * actor.sp / actor.maxsp
    for i in 0..height
      r = bar_color.red   * (height -i)/height  + 0   * i/height 
      g = bar_color.green * (height -i)/height  + 0 * i/height 
      b = bar_color.blue  * (height -i)/height  + 0 * i/height 
      a = bar_color.alpha * (height -i)/height  + 255 * i/height 
      self.contents.fill_rect(x, y+i, w , 1, Color.new(r, g, b, a)) 
    end
  end
  #--------------------------------------------------------------------------
  # * Draws Actors Exp meter
  #--------------------------------------------------------------------------
  def draw_actor_exp_bar(actor, x, y, width = 100, height = 10, 
    bar_color = Color.new(255, 255, 0, 255))
    self.contents.fill_rect(x, y, width, height, Color.new(255, 255, 255, 100)) 
    if actor.level == 99
      w = 0
    else
      w = width * actor.exp / actor.next_exp_s.to_f
    end
    for i in 0..height
      r = bar_color.red   * (height -i)/height  + 0   * i/height 
      g = bar_color.green * (height -i)/height  + 0 * i/height 
      b = bar_color.blue  * (height -i)/height  + 0 * i/height 
      a = bar_color.alpha * (height -i)/height  + 255 * i/height 
      self.contents.fill_rect(x, y+i, w , 1, Color.new(r, g, b, a)) 
    end
  end
end

#==============================================================================
# ** Window_WabbitHUD
#------------------------------------------------------------------------------
#  This class shows the Hud window for pink wabbit.
#==============================================================================

class Window_PinkWabbitHUD < Window_Base
  # Constant used to store the name of the icons to be used in the window.
  ICON_NAMES = {
    'hp' => 'heart.png',
    'sp' => 'crystal.png',
    'ep' => 'book.png',
    'gp' => 'coin.png'
  }
  #--------------------------------------------------------------------------
  # * Initializes the object.
  #--------------------------------------------------------------------------
  def initialize
    super(0,0,160,150)
    
    self.contents = Bitmap.new(width - 32, height - 32)
    self.opacity = 100
    
    # Draw the icons only once they won't change.
    bitmap = RPG::Cache.icon(ICON_NAMES['hp'])
    self.contents.blt(x, 0, bitmap, Rect.new(0, 0, 24, 24))
    bitmap = RPG::Cache.icon(ICON_NAMES['sp'])
    self.contents.blt(x, 32, bitmap, Rect.new(0, 0, 24, 24))
    bitmap = RPG::Cache.icon(ICON_NAMES['ep'])
    self.contents.blt(x, 64, bitmap, Rect.new(0, 0, 24, 24))
    bitmap = RPG::Cache.icon(ICON_NAMES['gp'])
    self.contents.blt(x, 96, bitmap, Rect.new(0, 0, 24, 24))
    
    # Intialize some public instance variables.
    @actor, @gold = $game_party.actors[0], $game_party.gold
    @actor_hp, @actor_sp, @actor_exp = -1, -1, -1
    
    # Call refresh to draw the more dynamic items.
    refresh
  end
  #--------------------------------------------------------------------------
  # * Redraws the data items in the window.
  #--------------------------------------------------------------------------
  def refresh
    clear_color = Color.new(0, 0, 0, 0)
    
    x, y = 0, 0
    
    # Draw the Hitpoints of the Party Leader.
    if @actor_hp != @actor.hp
      # Save the new value
      @actor_hp = @actor.hp
      # Create a rectangle to clear the portion we will draw to.
      rect = Rect.new(x + 26, y + 9, 100, 10)
      self.contents.fill_rect(rect, clear_color)
      # Draw the health bar.
      draw_actor_hp_bar(@actor, x + 26, y + 9)
    end
    
    y += 32
    
    # Draw the Skill Points of the Party Leader.
    if @actor_sp != @actor.sp
      # Save the new value
      @actor_sp = @actor.sp
      # Create a rectangle to clear the portion we will draw to.
      rect = Rect.new(x + 26, y + 9, 100, 10)
      self.contents.fill_rect(rect, clear_color)
      # Draw the health bar.
      draw_actor_sp_bar(@actor, x + 26, y + 9)
    end
    
    y += 32
    
    # Draw the Experience of the Party Leader.
    if @actor_exp != @actor.exp
      # Save the new value
      @actor_exp = @actor.exp
      # Create a rectangle to clear the portion we will draw to.
      rect = Rect.new(x + 26, y + 9, 100, 10)
      self.contents.fill_rect(rect, clear_color)
      # Draw the health bar.
      draw_actor_exp_bar(@actor, x + 26, y + 9)
    end

    y += 32
    
    # Draw the Gold
    if @gold != $game_party.gold
      # Save the new value
      @gold = $game_party.gold
      # Create a rectangle to clear the portion we will draw to.
      rect = Rect.new(x + 26, y, 100, 32)
      self.contents.fill_rect(rect, clear_color)
      # Set the drawing text color to gold.
      self.contents.font.color = Color.new(150,150,0,255)
      self.contents.draw_text(x + 26, y - 5, 100, 32, @gold.to_s, 2)
    end
  end
  #--------------------------------------------------------------------------
  # * Checks to see if the window needs to be refreshed. 
  #--------------------------------------------------------------------------
  def update
    if Graphics.frame_count / Graphics.frame_rate != @total_sec
      refresh
    end
  end
end

#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
#  This class performs map screen processing.
#==============================================================================
class Scene_Map
  alias_method :khmp_pinkwabbithud_main, :main
  alias_method :khmp_pinkwabbithud_update, :update
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------
  def main
    @hud = Window_PinkWabbitHUD.new
    khmp_pinkwabbithud_main
    @hud.dispose
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    @hud.update
    khmp_pinkwabbithud_update
  end
end

However if my above thought is wrong; Hope you enjoy it Pink Wabbit! :thumb:
 

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