HUD Groups

by Forum_account
An easy way to manage screen objects.
ID:121051
 
I'm working on another library but I'm not entirely sure what to add to it. I figure I'll post it and see what people think.

http://www.byond.com/developer/Forum_account/HUDGroups

The library is for creating and managing HUDs. I see two problems with HUDs/screen objects:

1. Screen objects are awkward to use. There are a lot of details that are hard to manage and its often hard to code things in such a way that it's organized and easy to work with.

2. HUD libraries tend to just do things for you. They're fine if that's exactly what you want to do, but generally aren't very customizable.

You might use screen objects to create a health meter but that's not something a library should do for you. There are tons of ways you might want a health meter to work. Instead of making a health meter for you, a library can provide easier ways to manage screen objects so that you can more easily create the type of health meter you need.

For example, here's a slightly simplified version of a demo from this library:

HealthMeter
parent_type = /HudGroup
icon = 'health-bar-demo.dmi'

New()
..()

// add eight objects to this group
for(var/i = 1 to 8)

// the objects are placed in a row, 16 pixels apart, starting at 0,0
var/px = i * 16 - 16
var/py = 0
add(px, py, "health")

proc
// updates the eight screen objects in the group to represent the new health value
update(value)
for(var/i = 1 to 8)

// the objects list is the list of screen objects in this group
var/HudObject/h = objects[i]

if(i <= value)
h.icon_state = "health"
else
h.icon_state = "empty"

// all you have to do to use it:
player.health_meter = new(player)
player.health_meter.update(player.health)


The library provides you with the HudGroup object which has procs for creating screen objects (the add() proc), setting the position of all objects in the group, hiding/showing the group. The add() proc returns an instance of /HudObject, which is derived from /atom/movable so it *is* the actual screen object, but it also has some procs I added. The HudObject also has a proc to set its position.

The main focus here is eliminating annoying details. You don't have to compute, parse, or set screen_loc values. You don't have to set vars like icon, icon_state, and layer - most of those vars are inherited from the HudGroup. You don't have to add or remove objects from the client.screen list.


The library comes with three demos: a health bar, an action menu, and a flyout menu. These demonstrate most of the library's capabilities.

These demos are all much more complex than I like demos to be. Unfortunately, this can't really be avoided. The HUD needs to be controlled by you. If the library had more features that would simplify the health meter code example, the library would be implementing the health meter for you. There's just that much logic that goes into making a health meter that you have to write yourself.

Things I'd Like to Add

I'll add support for more events, currently it only supports the Click() proc. I didn't add support for other events because they weren't needed for the examples.

I'd like to be able to nest HudGroup objects. Currently you can only nest HudObjects inside of a HudGroup. Being able to group groups would let you manage more complex HUDs. For example, a player's health meter and mana meter might be separate groups, but are both placed inside the same parent group so they can both be managed easile.

I'd also like to add support for drawing text on the screen. My guess is that it'll be a single proc on the HudGroup object that creates a single screen object with text attached to it. I'm not sure how this will be handled internally. I don't know what's possible or what they best way is. I could use one screen object per letter of text, or I could make each letter an overlay.


I'd appreciate it if you'd let me know what you'd like to see in the library. I designed it based on how I'd want to implement the kinds of things I do need to implement, but I'm not sure what other people would use it for. If you have ideas, suggesting additional features or demos would be very much appreciated.
You should add hud chatting :3. I've always wondered how people like Falacy did that.
On drawing text, Silk Games' HUD demonstration uses /images to draw text by attaching them to screen objects.

Really loving this library though. Something I've always wanted to see is a Diablo-style HUD system where you can have items of varying sizes and can arrange them on the grid.
LordAndrew wrote:
Really loving this library though. Something I've always wanted to see is a Diablo-style HUD system where you can have items of varying sizes and can arrange them on the grid.

THIS.

I downloaded Silk's library but hadn't looked to see how it handled text. I'll probably do it the same way, I'm sure he picked that method for a reason.

I'd like to see a Diablo-style inventory too. There are a couple of things I'd like to add to the library first that'd make it easier, but it's not that far out of the question.
LordAndrew wrote:
Really loving this library though. Something I've always wanted to see is a Diablo-style HUD system where you can have items of varying sizes and can arrange them on the grid.

Maybe I'll put that back into my HUD library when I finally release it again.
Nice work FA.
Forum_account wrote:
I downloaded Silk's library but hadn't looked to see how it handled text. I'll probably do it the same way, I'm sure he picked that method for a reason.

My experience has been that images are faster and easier to work with when it comes to rendering the text. Screen objects can take a moment to visually update but image drawing happens instantly. Granted, a lot of my methods originated many years ago when BYOND's screen object handling wasn't as refined, so the speed benefits may not be as noticeable now.

Images are easier to work with in the sense that it's really simple to attach images to a menu built using screen objects and then show/hide that menu without having to deal with a separate set of objects. The HUDs that I use are all pre-made when the world boots up and shared between players, therefore using images makes drawing and displaying text for different people much more simple.
SilkWizard wrote:
Screen objects can take a moment to visually update but image drawing happens instantly.

So true :(

The thing with images is that you must remove them from overlays before any modifications can be made, and then you re-add them to overlays. If you have any case where you modify an image before removing it from all the overlays that contain it, it'll just be stuck forever until you completely clear the overlays list (or possibly do some workaround with appearances).
An easy way to add text(With (optional?) text wrapping!). That's what I want. =)
Definitely right about image drawing happening more efficiently than screen objects. Heck, I even made a mistake in the demo included with the "SByIo Library" that caused major lag for others by keeping menu objects no longer in use to remain. Of course that will be corrected for multi-user testing for V3.

Thinking about it, some already know that I just began to utilize the screen object/image object hybrid for the "SByIo Library" to improve efficiency with onscreen input (V2 supports it, but is very inefficient for multi-user use). So, an screen object/image object hybrid would definitely work great for text handling. Much more efficient than separate character objects that's for sure.

And ah yes, who wants proper mouse_opacity support added for image objects (it can be set, but does nothing currently)? :D
http://www.byond.com/members/ BYONDHelp?command=view_tracker_issue&tracker_issue=3514
SilkWizard wrote:
Forum_account wrote:
I downloaded Silk's library but hadn't looked to see how it handled text. I'll probably do it the same way, I'm sure he picked that method for a reason.

My experience has been that images are faster and easier to work with when it comes to rendering the text. Screen objects can take a moment to visually update but image drawing happens instantly. Granted, a lot of my methods originated many years ago when BYOND's screen object handling wasn't as refined, so the speed benefits may not be as noticeable now.

Images are easier to work with in the sense that it's really simple to attach images to a menu built using screen objects and then show/hide that menu without having to deal with a separate set of objects. The HUDs that I use are all pre-made when the world boots up and shared between players, therefore using images makes drawing and displaying text for different people much more simple.

What do you do exactly? Create screen objects with no icon and attach images to them? Create image objects and add them to the overlays list of a screen object?
Forum_account wrote:
What do you do exactly? Create screen objects with no icon and attach images to them? Create image objects and add them to the overlays list of a screen object?

You can see my method demonstrated in that little Silk Games HUD Demo (it's very short, there isn't much code to wade through). The screen objects are created with their own icons and icon_states - the images are just drawn on top of them. The images aren't overlays, they're created using the image() proc with the top left screen object in the given menu set as the location. From there it's just a matter of adjusting pixel_x/pixel_y on each image to position and space the text.
SilkWizard wrote:
You can see my method demonstrated in that little Silk Games HUD Demo (it's very short, there isn't much code to wade through). The screen objects are created with their own icons and icon_states - the images are just drawn on top of them. The images aren't overlays, they're created using the image() proc with the top left screen object in the given menu set as the location. From there it's just a matter of adjusting pixel_x/pixel_y on each image to position and space the text.

Really the only issue we've had to contend with was the missing first character bug, but drawing the first character twice is a nice quick workaround.

Another thing with images is it's much easier to display them to a list of players without having to loop through them and add things to client.screen.

tenkuu wrote:
Another thing with images is it's much easier to display them to a list of players without having to loop through them and add things to client.screen.

The library manages the client's screen and image lists for you, so you'd never have to loop through anything. You just call the hide() or show() proc on the HudGroup object and all objects in the group are shown to them.

I'm working on an update that'll add text. You just call the HudGroup's add_text() proc to add a blank screen object with images attached to it. You can move the screen object to move the text or call a proc to change its text.

The update will also include a Font object which is necessary for positioning letters. The Font object has a wrap_text() proc which takes a string and width (in pixels) and adds line breaks to the string to it'll fit inside the specified width. Unfortunately, the library requires your font icon to be formatted a certain way and doesn't come with many tools to help you.

I'd like to add another demo and maybe update the existing flyout menu demo before posting the update, but it should be available sometime today.
How about a way to make a hud around the edge of the map that expands itself longer/shorter when you maximize or change the size.
Ganing wrote:
How about a way to make a hud around the edge of the map that expands itself longer/shorter when you maximize or change the size.

There is a size() proc on the HudObject that is used to change its size. I didn't use this in any demos, but it would come in handy for making things fit the screen size. I'll work on a demo that incorporates this.
Ok, I just posted an update that adds text capabilities and two demos to show how to use it. The "text-demo" example just shows the most basic way to display text on the screen. The "message-box-demo" example shows how to create an alert() kind of message box on the screen.

The library comes with a font but it shouldn't be terribly difficult to create your own. If there are any utilities or changes you'd need to make the library work more easily with an existing .dmi file you have for a font, just ask =)
I wonder if it's possible to have a HUD positioned off-screen (not actually visible, or partly visible) so that it doesn't stretch the screen.
I'm thinking like having text or a status bar rise from below the screen, only to be seen when necessary.
Kaiochao wrote:
I wonder if it's possible to have a HUD positioned off-screen (not actually visible, or partly visible) so that it doesn't stretch the screen.
I'm thinking like having text or a status bar rise from below the screen, only to be seen when necessary.

Actually, you can. However, it involves using screen location pixel offsets (for screen objects) to achieve that effect. I used that effect in "SkyDrop Delivery" when you first see the menu appear (Animation disabled for multiplayer).

If you want to have a look, go right ahead. :D (Let me know if you need the link.)
Page: 1 2