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.

[Resolved] Constantly Refreshing Parts Without FPS Loss

Hi!

So lately I've been trying to make some very informative interfaces that will update very frequently, but I'm running into the natural performance issue of redrawing all the time. I've tried a lot of methods to make this work, but all my attempts result in a FPS loss of about 20-30 depending on the requirements in redrawing.

Basically I have this block inside my update method to make sure it only refreshes when necessary:
Code:
# If bar values have changed: clear and refresh

if @hp != @actor.hp || @sp != @actor.sp || @energy != $game.system.energy

  self.contents.clear

  draw_energy_bar(8, 104)

end
I've attached the 'draw_energy_bar' method below. Any input on this would be greatly appreciated!
Code:
  #----------------------------------------------------------------------------

  # * Draw Energy Bar

  #----------------------------------------------------------------------------

  def draw_energy_bar(x, y)

    # Define bitmaps

    container = System::BITMAPS['container']

    barmap    = System::BITMAPS['crisisbar']

    # Draw container

    self.contents.blt(x, y, container, Rect.new(0,0,container.width,container.height))

    # Obtain percentage values

    percentage = $game.system.energy.to_f / 100

    if percentage <= 0

      width = 0

    else

      width = barmap.width * percentage

    end

    # Draw healthbar

    unless width <= 0

      self.contents.blt(x, y, barmap, Rect.new(0,0,width,barmap.height))

    end

    # Get values

    current = "#{$game.system.energy}"

    nxt     = "100"

    self.contents.font.color = Color.new(255,255,255)

    self.contents.font.outline = true

    self.contents.draw_text(x, y-6, 96, 24, "Energy")

    self.contents.draw_text(x + 4, y-6, 90, 24, "#{current}%",2)

    self.contents.font.color = normal_color

    self.contents.font.outline = false

  end

As a note: it works exactly as I intend it to, except the FPS loss is so great it makes it unplayable. So I'd just like to understand how to do more CPU-friendly coding that prevents this for my own experience.

Thanks in advance!
 
Not sure why you're checking HP & SP?? You're not using them in the draw method. If you're adding draw_hp_bar & draw_sp_bar, try doing them separately..

another thought would be to check every (5, 10) frames instead of every frame...

if Graphics.frame_count % 10 == 0

Is energy really changing that quickly/often?

What if.... you made a call to the 'refresh' method from the method that changes energy? then it only refreshes when it changes, and you don't have to compare values every frame?
 
Thank you for the reply!

I tried using the new condition to only check every 10th frame, and it resulted in perhaps a loss of 1-2 FPS at most. But as my bar is right now, I want the player to gain 4 energy every 2 frames or so (but being unable to gain more than 100), which means that if any energy is used, the bar should most optimally refresh at every second frame, but that causes a massive FPS loss. But I'm supposing that there's no other way than to redraw the bar every 2 frames in that case? If that's so, I'll stick to the every 10th frame process.
 
Yeh, I think no matter what, it's going to be a compromise. Interpreted scripts, when complex, are inherently 'laggy'.

I wonder if having the gradient bar in a separate sprite that only refreshes when necessary would make a difference???

It might be worth the effort to analyze the rest of the scene to optimize all other 'refresh' calls as well...
i.e. make sure refreshes are only getting called when something changes.
 

Ares

Member

I also needed to get rid of heavy FPS consumption (~20 frames) for my health hud.
These are two things I tried to keep in mind while trying to cut down performance loss.

First, as Brew said, you need to make sure the refresh is only called if something changes.

Second, you need to make sure that ONLY that what needs to be refreshed gets refreshed. So if you have a 100x100 sprite and the only part that gets refreshed is 10*100, you may want to split them up into several sprites. This way, refreshing takes up a minimum amount of time.
(example: You also redraw the container every time you refresh the bar. I think the container is static, right?
Maybe you could make another sprite for the container and the "Energy" text?)

For my hud, I ended up doing what Brew said:
Brewmeister":3mrsatf9 said:
What if.... you made a call to the 'refresh' method from the method that changes energy? then it only refreshes when it changes, and you don't have to compare values every frame?
edit: Now instead of using 20 frames it uses 1 :tongue:
 
Yeah, I did as you said, and the fact that the container doesn't need to redraw every change is a good point.
I'll keep this stuff in mind, although as the scripts are now, I can refresh it every 5 frames and it stays at 38-40 FPS all the time, so it seems to have been working with your inputs.

Thanks for the help!
 

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