Game Development Community

Position question

by Kevin James · in Torque Game Builder · 03/17/2007 (10:39 am) · 9 replies

$BulletLabel is a TextObject
$box is a StaticSprite

Why is the X position of the BulletLabel fixed no matter the length of the text, but the X position of the Box changes depending on its width?

Thanks

function PositionBoxAndText(%Length,%X,%Y)
{

  $BulletLabel.position = %X SPC %Y;
  $Box.size = %Length + 10 SPC $BulletLabel.LineHeight+2;
  $Box.Position = %X SPC %Y-4;

}


function CreateLabel()
{
    new t2dImageMapDatablock(TextBox)
    {
       imageMode = "full";
       imageName = "~/data/images/TextBox";
    };

    $Box = new t2dStaticSprite() {
            scenegraph       = SceneWindow2D.getSceneGraph();
            ImageMap         = TextBox;
            //Align            = "Left"; 
        };

    $BulletLabel = new t2dTextObject() {
            scenegraph       = SceneWindow2D.getSceneGraph();
            size             = "48.025 11.000";
            font             = "Arial Black";
            wordWrap         = "0";
            hideOverflow     = "1";
            textAlign        = "Left";
            lineHeight       = "3";
            aspectRatio      = "1";
            lineSpacing      = "0";
            characterSpacing = "0";
            autoSize         = "1";
            fontSizes        = "80";
            textColor        = "1 1 1 1";
            hideOverlap      = "0";
            
            delay            =80;
        };

}

function DisplayLabel(%ShowText,%X,%Y)
{
  if (!IsObject($BulletLabel)) CreateLabel();

  PositionBoxAndText(strlen(%ShowText),%X,%Y);

  $BulletLabel.txtPos=1;
  BulletLetter(%ShowText);
}

function BulletLetter(%ThisText)
{
  $BulletLabel.text=getSubStr(%ThisText,0,$BulletLabel.txtPos)@"|" ;
  $BulletLabel.txtPos++;
  
  alxPlay(LetterClick);

  if ($BulletLabel.txtPos<strlen(%ThisText)+1) 
    Schedule($BulletLabel.delay,0,"BulletLetter",%ThisText);
}

About the author

Computer security, digital forensics, and platform jumper enthusiast. shells.myw3b.net/~syreal/


#1
03/17/2007 (12:30 pm)
@Kevin, not really sure thats 100% accurate, but if it is, then it would be because the t2dTextObject is left-aligned possibly ...

I tossed a t2dTextObject into a scene in Level Builder, wrote some text, set the X to 0 and it was centered ... changed the text to something else, and it was still centered ...

Also, you probably do not want to re-create your ImageMapDatablock over and over every time you call CreateLabel ... either toss an 'isObject' check around it, or place it outside of the function so it's only created once, when the game starts ... otherwise, you'll be wasting resources and possibly memory ...
#2
03/17/2007 (1:26 pm)
Hi David,

TextObject.TextAlign = "Left"

Keeps the left side at its original position no matter how many characters are added during runtime.
However, I don't know how to make a StaticSprite behave the same way.

StaticSprite.Align = "left"
Has no affect.
#3
03/17/2007 (1:46 pm)
Now that I think about it, how is it that all of these people are able to make health bars that grow horizontally in one direction? Are those not staticsprites with the width getting incremented? That's basically all I want to do. I can't seem to find any examples of that.
#4
03/17/2007 (1:55 pm)
Sprites do not have that ability -- how about using TextAlign = "center" so that the X position is always centered on the t2dTextObject, then do the math from there to get the text and box to align properly ...

looks like you've got a generic system in place for telling you how wide to make the box ... now, just center align the text and tweak the math a bit ...
#5
03/17/2007 (1:57 pm)
@Kevin: there are a whole bunch of threads about that somewhere, but all you need to do is either make the bar image twice the size needed and then expand the whole thing - or just expand an image's width and then move it to the right by half that amount.
#6
03/17/2007 (2:03 pm)
@Kevin, heh ... sorry, I'd of had a better response had I known you were trying to do something like a health bar ... I got the impression you were trying to do something like a Popup Message Box for some reason ...

Tom's response is dead accurate ...

If you create the box initially with a width of 2 ... super 'thin', then change it to 3 ... just adjust the X by 0.5 and it'll appear to be 'left aligned' still ...

If you add 10 to the width, add 5 to the position X ... etc, etc ...

function updateBar(%bar, %width)
{
  %bar.setWidth(%width);
  %pos = %bar.getPosition();
  %posx = getWord(%pos, 0);
  %posy = getWord(%pos, 1);
  %posx += %width/2;
  %bar.setPosition(%posx, %posy);
}

Something like that ... you can clean it up to make it look 'smaller', I expanded everything out to show in more detail what it's doing ...
#7
03/17/2007 (3:24 pm)
Yes, that helps a lot! What is the relationship of character size to pixels?
#8
03/18/2007 (8:20 pm)
Here is the working code. This is a component that displays text in a typewriter mode. I'll post it here in case someone else might find it useful:

new t2dImageMapDatablock(TextBox)
    {
       imageMode = "full";
       imageName = "~/data/images/TextBox";
    };

    new AudioProfile( LetterClick )
    {
        filename    = "~/data/audio/click.wav";
        description = "AudioNonLooping";
        preload     = true;
    };

datablock t2dSceneObjectDatablock(BulletLabelDatablock)
{
   class     = "BulletLabel"; // associate this datablock with the namespace
   txtPos    = 1;
   delay     = 80;
   MaxLength = 35;
};

function BulletLabel::CreateLabel(%this)
{

    %Box = new t2dStaticSprite() {
            scenegraph       = SceneWindow2D.getSceneGraph();
            ImageMap         = TextBox;
        };
    %this.Box=%box;

    %BulletText = new t2dTextObject() {
            scenegraph       = SceneWindow2D.getSceneGraph();
            size             = "48.025 11.000";
            font             = "Arial Black";
            textAlign        = "Left";
            wordWrap         = "0";
            hideOverflow     = "1";
            lineHeight       = "3";
            aspectRatio      = "1";
            lineSpacing      = "0";
            characterSpacing = "0";
            autoSize         = "1";
            fontSizes        = "80";
            textColor        = "1 1 1 1";
    //        textColor = "0 0.0313726 1 1";
            hideOverlap      = "0";
            
         };
    %this.BulletText=%BulletText;

}

function BulletLabel::DisplayLabel(%this,%ShowText,%X,%Y)
{
  %this.StartAfterPause(0,%ShowText,%X,%Y);//0 is false
}

function BulletLabel::StartAfterPause(%this,%pause,%ShowText,%X,%Y)
{
  if (!IsObject(%this.BulletText)) %this.CreateLabel();

  %this.text=%ShowText;//store for use in ArrowGroup::PlayInOrder

  %ShowText=%ShowText @ %this.CopyString("*",%this.MaxLength-strLen(%ShowText));

  %this.PositionBoxAndText(strlen(%ShowText),%X,%Y);

  if (!%pause) %this.BulletLetter(%ShowText);
}

function BulletLabel::CopyString(%this,%xStr,%xCnt)
{
    for(%X=0;%X<%xCnt;%X++)
      %MakeStr=%MakeStr @ %xStr;

    return %MakeStr;
  
}

function BulletLabel::BulletLetter(%this,%ThisText)
{
  if (getSubStr(%ThisText,%this.txtPos-1,1)!$= "*")
  {
      %this.BulletText.text=getSubStr(%ThisText,0,%this.txtPos)@"|" ;
      if (getSubStr(%ThisText,%this.txtPos-1,1) !$= " ") alxPlay(LetterClick);
      %this.txtPos++;
      
      if (%this.txtPos<strlen(%ThisText)+1) 
        %this.LabelEvent=%this.Schedule(%this.delay,"BulletLetter",%ThisText);
      else %this.BulletText.text=getSubStr(%ThisText,0,%this.txtPos);//remove cursor line when finished
  }
}

function BulletLabel::PositionBoxAndText(%this,%Length,%X,%Y)
{
  %this.BulletText.position = %X SPC %Y;
  %width=%Length*1.4; 
  %this.Box.size = %width SPC %this.BulletText.LineHeight+2;
  %this.Box.Position = %X SPC %Y-4;
}

function BulletLabel::SafeDelete(%this)
{
    %this.BulletText.safeDelete();
    %this.Box.safeDelete();

    Cancel(%this.LabelEvent);
    Cancel(%this.PauseEvent);
    %this.Delete();
}

////////////////////////////////////LabelGroup Class: manage all BulletLabel objects/////////////////////////////////////
datablock t2dSceneObjectDatablock(LabelGroupDatablock)
{
   class      = "LabelGroup"; // associate this datablock with the namespace
   LineCnt    = 0;
   PauseLines = 0;//default is 0 false -no pausing between lines
};

function LabelGroup::NewLine(%this,%ShowText,%X,%Y)
{
  %Label = new t2dStaticSprite() 
    {scenegraph = SceneWindow2D.getSceneGraph();
     config = "BulletLabelDatablock";};

   %this.Line[%this.LineCnt]=%Label;//store each Line in an array to be used later, such as in SafeDelete()
   %this.LineCnt++;
   
   %Label.PauseTime=%Label.delay * strLen(%ShowText);

   if (!%this.PauseLines) %Label.DisplayLabel(%ShowText,%X,%Y);
   else if (%this.LineCnt < %this.PauseLines) %Label.DisplayLabel(%ShowText,%X,%Y);
   else {
        %Label.StartAfterPause(1,%ShowText,%X,%Y);//1 is true
        for(%X=0;%X<%this.LineCnt-1;%X++)
           %totpause += %this.Line[%X].PauseTime;

        %Label.PauseEvent[%this.LineCnt-1]=%this.schedule(%totPause,"PlayInOrder",%Label);
   }

}

function LabelGroup::PlayInOrder(%this,%Label)
{
  %Label.BulletLetter(%Label.text);
}

function LabelGroup::SafeDelete(%this)
{
    for(%X=0;%X<%this.LineCnt;%X++)
        if (IsObject(%this.Line[%X])) %this.Line[%X].safedelete();

   %this.Delete();
}


Usage example:
function TestLabels()
{
   $BLabel = new t2dStaticSprite() 
    {scenegraph = SceneWindow2D.getSceneGraph();
     config = "LabelGroupDatablock";};

   $Blabel.PauseLines =1;//0=false 1=true
   $BLabel.NewLine("1947: UN Headquarters, NY",-20, 10);
   $BLabel.NewLine("Second line HA HA",-20, 15);
   $BLabel.NewLine("Third line wow...",-20, 20);
}
#9
08/28/2009 (1:18 am)
Thanks for this function!!!

I will try to add a particle effect to write!!!

To give the impression that is a particle that is writing the text. Do you think that this is possible?