2D Tuesday: Fancy Hud
by Michael Perry · 06/26/2012 (2:42 pm) · 27 comments
2D Tuesdays: Fancy HUD

Kickoff
Greetings everyone. It's 2D Tuesday! Each week someone on the 2D team will post a blog or resource related to Torque 2D and/or iTorque 2D. The majority of the posts will come from myself, but don't be shocked if someone else takes over for me from time to time.Last week, I wrapped up the Box2D discussion. I had originally planned to write a lengthy blog about behaviors, but there was a snag. As I stated in my previous posts, I'm going to be pulling a lot of stuff from archived e-mails and internal discussions/wikis. This allows me to post without eating up significant development time. Unfortunately, the past week has been very crazy for the development team. I stand by priorities, which means this week's post is going to be very lean. Actual development on the 2D engines is what everyone wants, but I don't want to break my streak of 2D blogs.
First, here's the "let's cover our bacon section":

FULL DISLOSURE
Do not take the content from these blogs as law. I'm never going to say "this will be in x.x version" or "this is ready to be used right now". There's going to be a lot of R&D discussion. I might even post a discussion I had with Melv that ended up being scrapped. It might be useful for you to understand how we communicate internally, or amusing to see the mad scientists we really are. I will not post timelines. I will not post release dates. I will not commit the team to something we cannot deliver on.

Sprite-based HUD
The process for using a second level as your interface is really simple. I have attached three screenshots to illustrate the setup.Game Level

This was a simple game level I set up, called "level.t2d". This where I create my game objects, like a player, tiles, etc. It has a space ship that constantly flies to the right.
HUD Level

This is a completely new level I created to contain my HUD, called "hud.t2d". This contains my player health sprite, power-up sprite and a particle effect that connects the two.
Final Result

This is the game running outside of the editor. As you can see, it contains both levels. Additionally, the HUD level is on top (which is what you want for an interface)
Here are the steps to reproduce my example:
1. Create your game level (which you have already done)
2. Create your HUD level (contains your interface)
3. Open game/gui/mainScreen.gui and look for this code:
new t2dSceneWindow(sceneWindow2D)
{
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiContentProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "0 0";
Extent = "1024 768";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
hovertime = "1000";
lockMouse = "0";
useWindowMouseEvents = "1";
useObjectMouseEvents = "1";
};4. Add the following code immediately after that block:
new t2dSceneWindow(hudWindow)
{
canSaveDynamicFields = "0";
isContainer = "0";
Profile = "GuiContentProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "0 0";
Extent = "1024 768";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
hovertime = "1000";
lockMouse = "0";
useWindowMouseEvents = "1";
useObjectMouseEvents = "1";
};5. Locate your load level code.
Torque 2D: Open game/gameScripts/game.cs and look for this code:
sceneWindow2D.loadLevel(%level);
iTorque 2D: Open projectFiles/scripts/game.cs, look for the above code.
6. Change that line of code to explicitly load your game level:
sceneWindow2D.loadLevel("game/data/levels/level.t2d");7. Directly beneath that code, add the following:
hudWindow.loadLevel("game/data/levels/hud.t2d");Now for the explanation of what's going on. A t2dSceneWindow is a GUI that remains static to your game window. It also contains a camera and various other functions. A t2dSceneWindow is responsible for loading your levels. In a stock T2D project, you only get one t2dSceneWindow which loads a level at the start. That is the sceneWindow2D.loadLevel() call in startGame.
Because you want to load two separate levels and show them at the same time, you need a second t2dSceneWindow. That is where the hudWindow comes into play. You have to create a new one (which is added to mainScreen.gui), which will be responsible for loading your interface (hudWindow.loadLevel("game/data/levels/hud.t2d") ).
The reason I said you should explicitly change the sceneWindow2D.loadLevel(%level), is because that %level variable is set by the game editor to whatever level you were last working on. This can be bad, since you want to load and render two separate levels in a specific order.
That's about it. If you have any specific questions about this example, I'm more than happy to answer them.

Next Time
That's it for this week folks. Sorry I couldn't deliver on an epic discussion of behaviors, but hopefully the fact that we are working feverishly on the tech and still willing to post at least something will satisfy everyone. Behaviors next week. Oh! Also, iTorque 2D 1.5.1 Preview is going out tomorrow. It's not an Earth shattering release, but it should help a few of you wrap up your existing games and support newer iOS devices.VOTE TIME!
1. Why behaviors rock and how they are going to become more epic!
2. How we were able to remove 45 kilograms of dirt and cobwebs from the editor system!
Post a reply with your vote.
About the author
Programmer.
#22
06/28/2012 (8:54 am)
// Update health bar to display current health
%health = %this.owner.getHealth(); // note: getHealth() is a method of another behavior on the owner. Try to have only one behavior with a given name on any object or things can get weird.
// Test to see that health has changed since last update
if (%health < %this.currentHealth)
{
// Since health has changed we need to update the health bar.
// Keep the current health to see if we need to update the health bar
// on the next update.
%this.currentHealth = %health;
// Set the new size of the health bar.
%sizer = (%this.currentHealth / %this.totalHealth) * (%this.owner.getWidth() / 2);
if (%sizer < 0)
%sizer = 0;
if (isObject(%this.displayObj))
{
%this.displayObj.setWidth(%sizer);
// If we want the health bar to shrink to the left we have to calculate
// our mounting offset and update the health bar position.
if (%this.BarToLeft)
{
%mobWidth = %this.owner.getWidth() / 2;
%barWidth = %this.displayObj.getWidth();
%this.barOffsetX = (%mobWidth / 2) - (%barWidth / 2);
}
}
if (isObject(%this.frameObj))
{
%x = getWord(%this.owner.position, 0);
%y = getWord(%this.owner.position, 1) + %this.offset;
%this.frameObj.setPosition(%x, %y);
}
// This section adjusts the color of the health bar to reflect the damage
// state. These colors are GREEN, YELLOW and RED by default, but they can be
// adjusted in the editor using the appropriate fields.
// The DamageStateX variables are also set in the editor to determine when
//
if (%this.ChangeColor)
{
%damagePercent = %this.currentHealth / %this.totalHealth;
if (%damagePercent <= %this.DamageState1 && %damagePercent > %this.DamageState2)
{
%this.displayObj.BlendColor = %this.ColorHurt;
}
else if (%damagePercent <= %this.DamageState2)
{
%this.displayObj.BlendColor = %this.ColorDying;
}
}
}
#23
1 please ;)
06/29/2012 (10:14 pm)
I'd very much like to see the behavior write up as none of my code currently is using them and the tutorials out there aren't exactly what I'm looking for.1 please ;)
#24
The trick to making it work right is to use multiple scenegraphs per health bar. Then slide the health part of the bar to make it look like the energy is going up or down. I have done this myself but the code is pretty tricky and elaborate :/ I hope to eventually release some kind of add on pack and include the fancy energy bars for people to use. I know most games need them and it's not quite so easy to make with TGB as it is right now.
07/01/2012 (8:45 am)
@MrSpaceGame The trick to making it work right is to use multiple scenegraphs per health bar. Then slide the health part of the bar to make it look like the energy is going up or down. I have done this myself but the code is pretty tricky and elaborate :/ I hope to eventually release some kind of add on pack and include the fancy energy bars for people to use. I know most games need them and it's not quite so easy to make with TGB as it is right now.
#25
I did that, but it is somehow not as accurate as I want it to be.
Thanks for all the other helpful tipps :).
07/01/2012 (2:29 pm)
>> MrSpaceGame - scale your health bar and then move it to the left edge of the frame plus half its current width. I did that, but it is somehow not as accurate as I want it to be.
Thanks for all the other helpful tipps :).
#26
07/01/2012 (7:05 pm)
Yay 2D Tuesday! I'm a bit late to the party. I vote for #2.
#27
07/03/2012 (1:24 pm)
It's Tuesday of next week. Just sayin'. :P 
Conor O'Kane
cokane.com