Bitmap in Bitmap? - Designing HUD's

Discussion in 'Learning Ruby and RGSSx' started by Rikifive, Aug 28, 2016.

  1. Rikifive

    Rikifive Bringer of Happiness Veteran

    Messages:
    1,442
    Likes Received:
    676
    Location:
    Poland
    First Language:
    Polish
    Primarily Uses:
    Other
    Hello everybody!


    Currently I'm designing HUD, that will display characters' HP and MP on map screen and I'd like to ask a question.


    What I was about to do, is to create sprites directly in Scene_Map ~ their variables and such all in that scene.


    However, I think that's not the smartest solution, as it will get kinda messy later, right?


    For example making a sprite for each character, where each sprite will have their own values based on characters' statuses ~ and each bars will have multiple layers like base and fill~ and all of this - directly in Scene_Map.


    It itself isn't an issue, but it may bring some problems later, so I'd have to use pretty long names, to make sure, that I'll not bump into them when working on different things.


    So I was thinking, if making a class to handle that would be better.


    But now there's a question - can I make a sprite class with multiple graphics? When I'll set the bitmap to bar's base, how can I add the fill part?


    creating variable with the graphics and using contents.blt method or whatever works there?


    How should I go about this to not kill the performance?


    Another solution would be making a window class, where I could perform such an action, but I'd like to avoid using windows as they simply have totally unnecessary features, that I don't need there, so that would be just a free performance loss. And redrawing stuff is painful. I'd simply like to operate with multiple graphics, like moving&resizing 'fill' layer on the base one etc.


    EXAMPLE:


    For example if I'd be doing that in window class then:


    I'm making one window class - generally a window where I'll draw stuff.


    Now I'm making a variable for base and throwing graphics to it for example:


    base = Cache.abc("base")
    rect = Rect.new(0,0,base.width,base.height)
    contents.blt(100,100,base,rect,255)




    and doing the same with the 'fill' image~ where it's size is determined by let's say HP.


    Now I could redraw that part in the window to resize the fill when the HP will change.


    Since it's not the best solution I think ~ I'd like to use sprite class instead.


    For example create a sprite class.


    As a self.bitmap put the base.


    Then create a variable with 'fill' part and set its position and size dependable on let's say HP.


    Then simply resize the sprite/bitmap without having to redraw it like it would happen in window class.


    A quick example of what I'm trying to do:


    In scene, I'm creating a base of the bar:


    @bar = Sprite.new
    @bar.bitmap = Cache.hud("bar")
    @bar.x = 50




    now fill part on it


    @fill = Sprite.new
    @fill.bitmap = Cache.hud("fill")
    @fill.x = 52
    width = hp/mhp * 100
    @fill.src_rect.set(0, 0, width, 16)




    and then change width and update src_rect.


    It all would work, but the thing is, there's much more stuff than this and updating that in the Scene_Map update method will be pretty messy, so that's why I was thinking of moving that all to a new class and in the Scene_Map just create sprites and update them with a single line, where it all would be handled further individually by each sprite from their update method specified in class.


    I was thinking of making a class, that would handle the whole bar, then just create it multiple times in the map scene for each character.


    The solution is probably pretty obvious, but it's been awhile since I was scripting stuff, plus I haven't slept for 39 hours now (at the time it was posted), so please mind potential lack of logic in this post.


    I kinda got stuck with this. =P


    I hope I covered everything. =P


    Now excuse me, I'm going to sleep. x3


    Thank you! x3
     
    Last edited by a moderator: Aug 28, 2016
    #1
  2. Shaz

    Shaz Veteran Veteran

    Messages:
    37,326
    Likes Received:
    11,133
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    Make a new window class and create an instance of that window in Scene_Map.  Look at how Scene_Map handles multiple windows - wherever there's a reference to the other windows, you'll add some action on the new window as well.


    Your window class can have whatever you want it to have - lots of bitmaps, or a single bitmap that you blit to.  


    You could also just make a hud class and refer to that from Scene_Map, that has all the info you need to track, and handle the sprites within Spriteset_Map.
     
    #2
  3. Rikifive

    Rikifive Bringer of Happiness Veteran

    Messages:
    1,442
    Likes Received:
    676
    Location:
    Poland
    First Language:
    Polish
    Primarily Uses:
    Other
    Yep, but I don't want to use window class as redrawing contents each frame can be destructive. Not mentioning, that window class has tons of stuff, that I don't need, such as skin itself.


    Instead of that, I want to make sprites and manipulate them (move/resize) to represent HP bars etc..


    While I could easily achieve that by creating multiple sprites and working with them within the scene, it will get messy later, so I think having a class with its own update method would be better, but now the question is:


    I want to make let's say an HP Bar.


    For that, I need the base (background) and the fill (green bar, for example) - can I do that in a single sprite class, where I could store the variables related to it in them instead of the scene, where I'm creating them?


    I want to make for example


    class Sprite_Map_HUD < Sprite


    ~ where multiple bitmaps would be loaded to handle the whole bar and it would have the update method to update it ~ then I'd simply create that sprite in Scene_Map and put that single line to update it, where it would do its thing later.


    Normally I'd use self.bitmap and stuff, so that will handle the base, but how about adding a second graphic file to handle the movable green bar?


    Does that make sense? =P
     
    #3
  4. Shaz

    Shaz Veteran Veteran

    Messages:
    37,326
    Likes Received:
    11,133
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    The Window class doesn't redraw the contents each frame.  It redraws it when you tell it to.  The update method runs each frame - this is where you should determine if contents need to be redrawn.  The refresh method does the redrawing.
     
    #4
  5. Rikifive

    Rikifive Bringer of Happiness Veteran

    Messages:
    1,442
    Likes Received:
    676
    Location:
    Poland
    First Language:
    Polish
    Primarily Uses:
    Other
    I know, I know, but let's assume that I'll need to update it each frame.


    I know how to do that with the windows, but I know it is possible to do that with the sprites and now I'm looking for the best way to do that.


    Example?


    There's HP Bar.


    Character gets hit for like 20% of his max HP.


    on the bar, 20% of its length turns white and starts to slowly drain to the target amount.


    hm... Oh I can even think of an example:










    Take a look on what happens with the boss HP bar when it gets hit.


    I'm not saying that I want to fully recreate that, but here you have an example, showing, that there are times, where it needs to be updated each frame.


    Or imagine simply a situation, where the character is poisoned and constantly loses HP - redrawing window every single frame...


    Now, there are 6 characters, so there'll be 6 bars on screen ~ I'd like to have it optimized, because the Scene_Map itself is poorly optimized already and it lags when there are events on map, so a big window covering ~30% of the screen is the last thing, that should be added to the party...


    And don't get me wrong please, I'm not ranting. x3


    I was working with windows before and you need to be really cautious about them, sprites on the other hand are much more lighter as even if there are tons of them each updated every single frame - they consume less memory.


    I wish Ace would be able to handle things normally, I really do...


    So... like I can easily draw many sprites in one window class, can I do the same with sprite class or do I have to make each sprite separately?


    What will be lighter?


    One window, that is redrawn each frame


    or


    One sprite for a base that doesn't change and another one sprite for the bar, that is resized each frame using src_rect and stuff? Or even just moved to the left by 1 each frame?


    There is a difference. x3


    I hope you'll know what I mean. x3
     
    #5
  6. Shaz

    Shaz Veteran Veteran

    Messages:
    37,326
    Likes Received:
    11,133
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    That's why I also said this:

     
    #6
    Rikifive likes this.
  7. Rikifive

    Rikifive Bringer of Happiness Veteran

    Messages:
    1,442
    Likes Received:
    676
    Location:
    Poland
    First Language:
    Polish
    Primarily Uses:
    Other
    Yep, you're right and that's what I was aiming for - and I came here to get into the details with this. You kept saying about windows, so my replies also were talking about windows, even though it all was going kinda off-topic.


    Anyway, yes your last sentence in that post was accurate to my question and now when we're done with the windows, I want to get into the details. x3


    To my understanding, I could create a hud class, where I'd have multiple variables, that would serve as sprites, just like when I'd be doing that in the scene itself, right?


    But there, I'd have separate update method and instance variables, that in the scene, so that would be a good thing.


    Now in the scene, I'd just have to create a single instance variable like this?


    @status_hud = Map_Status_HUD.new #=> which would be the hud class (class Map_Status_HUD)


    and then, updating it in the scene like this


    @status_hud.update


    Is this how it works?


    Also what about disposing bitmaps? I assume I'd just have to create a dispose method in the hud class, where all the bitmaps from variables would be freed ~ and then just calling @status_hud.dispose would do the thing, yes?


    To be honest I didn't know you can do things that way ~ that's even more convenient than I thought.


    That will also allow me to easily create HP bars and stuff around enemies, that will not be messy, since it will directly refer to their instance variables. x3


    Unless I'm mistaking something...

    [​IMG]
    Okay I gave it a try and everything worked perfectly.


    Thanks for pointing the Spriteset_Map as it indeed contained all the information I needed.


    That's exactly what I was asking for ~ I mean, I was thinking of doing something like this, though I was not sure if that would work or if that would be safe (performance/memory-wise), so I've made that thread. Your last sentence in that post should be the first one. x3 


    What a shame, that I didn't know of such a handy way of putting stuff to scene. That would make stuff much neater... Time to do some cleanings then... And holy balls, it will help me do so much stuff!


    Thank you for help! (=


    Thread can be closed if desired.
     
    Last edited by a moderator: Aug 29, 2016
    #7

Share This Page