Plastic Gem #42: Shape Name Hud Upgrades
by Anthony Rosenbaum · 08/19/2008 (6:24 am) · 8 comments
Download Code File

Shape Name Hud
Difficulty: Easy
In this article we are going to improve the GuiShapeNameHud so that it shows the players health along with their name. This code is actually pretty straight forward it is taken from GuiCrossHairHud and has been placed in the GuiShapeNameHud. As an addition we have exposed additional colors so that as the player's health depletes you will be able to see it as a color change on the bar. Most of the code is the same but because TGE and TGEA use different utilities for drawing on the screen we will repeat the final instructions for the rendering section.
TGE - dgl methods
TGEA - GFX methods
TGE
1) Add these properties to the GuiShapeNameHud class definition
We will also add a new method for rendering the name and damage
2) Also in GuiShapeNameHud class definition add to the protected section:
On to initializing the new properties
3) Within the constructor GuiShapeNameHud::GuiShapeNameHud() add:
Now to expose the properties to the editor ( are you learning how Torque works yet?)
4) At the bottom of GuiShapeNameHud::initPersistFields() add
Now we are going to remove the old way of rendering the name for our new way of rendering the name and damage bar.
5) In GuiShapeNameHud::onRender() replace drawName() with this code
Now add our custom rending method
6) At the bottom of the file add this function
For TGEA simple rewrite the function to use the GFX interface
6) At the bottom of the file add this function
There you have it, not only it is a nice improvement this article give you something to compare against incase you are porting some custom GUIs from TGE to TGEA.
The Next Gem
We will look at fixing the Camera Object orbit position feature.

Shape Name Hud
Difficulty: Easy
In this article we are going to improve the GuiShapeNameHud so that it shows the players health along with their name. This code is actually pretty straight forward it is taken from GuiCrossHairHud and has been placed in the GuiShapeNameHud. As an addition we have exposed additional colors so that as the player's health depletes you will be able to see it as a color change on the bar. Most of the code is the same but because TGE and TGEA use different utilities for drawing on the screen we will repeat the final instructions for the rendering section.
TGE - dgl methods
TGEA - GFX methods
TGE
1) Add these properties to the GuiShapeNameHud class definition
// > pg health enhancement ColorF mDamageFillColor; ColorF mGreenColor; ColorF mLowHealthColor; ColorF mDamageFrameColor; Point2I mDamageRectSize; Point2I mDamageOffset; F32 mUnhealthyPercent; F32 mYellowPercent; F32 mMinAlpha; // < pg health enhancement
We will also add a new method for rendering the name and damage
2) Also in GuiShapeNameHud class definition add to the protected section:
// > pg health enhancement
void drawNameAndDamage( Point2I offset, const char *buf, F32 damage, F32 opacity);
// < pg health enhancementOn to initializing the new properties
3) Within the constructor GuiShapeNameHud::GuiShapeNameHud() add:
// > pg health enhancement mDamageFillColor.set( 0, 1, 0, 1 ); mLowHealthColor.set( 1, 0, 0, 1 ); mDamageFrameColor.set( 1, 0.6, 0, 1 ); mDamageRectSize.set(50, 4); mDamageOffset.set(0,32); mUnhealthyPercent = 0.3; mMinAlpha = 0.2; mYellowPercent = 0.6; mGreenColor.set(0, 1, 0, 1); // < pg health enhancement
Now to expose the properties to the editor ( are you learning how Torque works yet?)
4) At the bottom of GuiShapeNameHud::initPersistFields() add
// > pg health enhancement
addGroup("Damage");
addField( "damageFillColor", TypeColorF, Offset( mDamageFillColor, GuiShapeNameHud ) );
addField( "damageFrameColor", TypeColorF, Offset( mDamageFrameColor, GuiShapeNameHud ) );
addField( "damageRect", TypePoint2I, Offset( mDamageRectSize, GuiShapeNameHud ) );
addField( "damageOffset", TypePoint2I, Offset( mDamageOffset, GuiShapeNameHud ) );
addField( "lowHealthColor", TypeColorF, Offset( mLowHealthColor, GuiShapeNameHud ) );
addField( "unhealthyPercent",TypeF32, Offset (mUnhealthyPercent, GuiShapeNameHud));
addField( "minAlpha", TypeF32, Offset( mMinAlpha, GuiShapeNameHud ) );
addField( "yellowPercent", TypeF32, Offset( mYellowPercent, GuiShapeNameHud ) );
addField( "greenColor", TypeColorF, Offset( mGreenColor, GuiShapeNameHud ) );
endGroup("Damage");
// < pg health enhancementNow we are going to remove the old way of rendering the name for our new way of rendering the name and damage bar.
5) In GuiShapeNameHud::onRender() replace drawName() with this code
// > pg pg health enhancement if(opacity < mMinAlpha) opacity = mMinAlpha; // Render the shape's name and damage drawNameAndDamage(Point2I((S32)projPnt.x, (S32)projPnt.y), shape->getShapeName(), shape->getDamageValue(), opacity); //< pg pg health enhancement
Now add our custom rending method
6) At the bottom of the file add this function
// > pg health enhancement
//----------------------------------------------------------------------------
/// Render object names.
///
/// Helper function for GuiShapeNameHud::onRender
///
/// @param offset Screen coordinates to render name label. (Text is centered
/// horizontally about this location, with bottom of text at
/// specified y position.)
/// @param name String name to display.
/// @param damage Damage to display
/// @param opacity Opacity of name (a fraction).
void GuiShapeNameHud::drawNameAndDamage(Point2I offset, const char *name, F32 damage, F32 opacity)
{
mDamageFillColor.alpha = mDamageFrameColor.alpha = opacity;
// Damage should be 0->1 (0 being no damage,or healthy), but
// we'll just make sure here as we flip it.
damage = mClampF(1 - damage, 0, 1);
ColorF outColor = mGreenColor;
//full is green
//turn to red if below 50
if(damage <= mYellowPercent)
outColor = mDamageFillColor;
if(damage <= mUnhealthyPercent)
outColor = mLowHealthColor;
// text info
//StringBuffer sb;
//sb.append(name);
//S32 width = mProfile->mFont->getStrNWidth(sb.getPtr(),sb.length());
S32 width = mProfile->mFont->getStrWidth(name);
S32 height = mProfile->mFont->getHeight();
// setup bar for rect...
RectI rect(offset, mDamageRectSize);
rect.point.y -= height;
rect.point.x -= mDamageRectSize.x / 2;
rect.point += mDamageOffset;
// setup bar for name...
RectI nameRect(offset, Point2I(width,height));
nameRect.point.y -= height;
// for now center on bar as width = fuckyup
//nameRect.point.x -= width / 2;
nameRect.point.x -= mDamageRectSize.x / 2;
// draw name..
mTextColor.alpha = opacity;
dglSetBitmapModulation(mTextColor);
dglDrawText(mProfile->mFont, nameRect.point, name);
dglClearBitmapModulation();
// (to help debug strWidth() stuff we can draw border around name too...
//dglDrawRect(nameRect, mDamageFrameColor);
// draw bar...
// Draw the border
//draw filled to get perspective
dglDrawRectFill(rect, mDamageFrameColor);
// Draw the damage % fill
rect.point += Point2I(1, 1);
rect.extent -= Point2I(1, 1);
rect.extent.x = (S32)(rect.extent.x * damage);
if (rect.extent.x == 1)
rect.extent.x = 2;
if (rect.extent.x > 0)
dglDrawRectFill(rect, outColor);
}
// < pg health enhancementFor TGEA simple rewrite the function to use the GFX interface
6) At the bottom of the file add this function
// > pg health enhancement
//----------------------------------------------------------------------------
/// Render object names.
///
/// Helper function for GuiShapeNameHud::onRender
///
/// @param offset Screen coordinates to render name label. (Text is centered
/// horizontally about this location, with bottom of text at
/// specified y position.)
/// @param name String name to display.
/// @param damage Damage to display
/// @param opacity Opacity of name (a fraction).
void GuiShapeNameHud::drawNameAndDamage(Point2I offset, const char *name, F32 damage, F32 opacity)
{
mDamageFillColor.alpha = mDamageFrameColor.alpha = opacity;
// Damage should be 0->1 (0 being no damage,or healthy), but
// we'll just make sure here as we flip it.
damage = mClampF(1 - damage, 0, 1);
ColorF outColor = mGreenColor;
//turn to red if below 50
//full is green
//turn to red if below 50
if(damage <= mYellowPercent)
outColor = mDamageFillColor;
if(damage <= mUnhealthyPercent)
outColor = mLowHealthColor;
// text info
//StringBuffer sb;
//sb.append(name);
//S32 width = mProfile->mFont->getStrNWidth(sb.getPtr(),sb.length());
S32 width = mProfile->mFont->getStrWidth(name);
S32 height = mProfile->mFont->getHeight();
// setup bar for rect...
RectI rect(offset, mDamageRectSize);
rect.point.y -= height;
rect.point.x -= mDamageRectSize.x / 2;
rect.point += mDamageOffset;
// setup bar for name...
RectI nameRect(offset, Point2I(width,height));
nameRect.point.y -= height;
// for now center on bar as width = fuckyup
//nameRect.point.x -= width / 2;
nameRect.point.x -= mDamageRectSize.x / 2;
// draw name..
mTextColor.alpha = opacity;
GFX->getDrawUtil()->drawRect(rect, mDamageFrameColor);
// Draw the damage % fill
rect.point += Point2I(1, 1);
rect.extent -= Point2I(1, 1);
rect.extent.x = (S32)(rect.extent.x * damage);
if (rect.extent.x == 1)
rect.extent.x = 2;
if (rect.extent.x > 0)
GFX->getDrawUtil()->drawRectFill(rect, outColor);
}
// < pg health enhancementThere you have it, not only it is a nice improvement this article give you something to compare against incase you are porting some custom GUIs from TGE to TGEA.
The Next Gem
We will look at fixing the Camera Object orbit position feature.
About the author
#2
08/22/2008 (8:01 pm)
Most useful.Thx.
#3
the code guiShapeNameHud.cc commented on line 188 that:
// and we want to ignore anything it's mounted on when we run the LOS.
does it mean that it will still show up the name when i mount some static object onto the shape base player? But it doesn't work in that way, the text disappear after mounting.
Do you have any suggestions about how to fix it?
Thanks so much.
09/09/2008 (5:40 am)
Hi, i have a question related to nameHud.the code guiShapeNameHud.cc commented on line 188 that:
// and we want to ignore anything it's mounted on when we run the LOS.
does it mean that it will still show up the name when i mount some static object onto the shape base player? But it doesn't work in that way, the text disappear after mounting.
Do you have any suggestions about how to fix it?
Thanks so much.
#4
01/07/2009 (7:47 am)
Nancy - sorry for late reply. Did you get past this issue yet? I guess if you mount something to the shapebase player you need to ensure that mounted thing ALSO does not block LOS. Perhaps you need to disable collision on that mounted shape for this test?
#5
03/09/2009 (5:13 am)
Does this work in TGEA 1.8.1?
#7
03/01/2012 (2:05 pm)
Thanks! This drops right into T3D v1.2, with no changes required! just used the above TGE code, plus the TGEA render code.
#8
03/17/2012 (6:35 pm)
The link to the download code is broken, does anyone happen to still have the dl available? 
Sailendu Behera