It’s been a while since my last post concering AS3. I’m currently developing the HUD/GUI for awesay and yesterday, I came in contact with the new flash text engine for the first time.
For the HUD, I created a window, where I want to display a title centered on a sprite (horizontally, as well as vertically).
So, after reading some docs about how to create a simple line of text, I finally got it on the screen. To me, the process of creating such a simple line of text, seems horrific. However, you’re able to do a lot of nice things with the FTE, and the good old TextField won’t be improved in future, but is still supported. Because we want our HUD to be multilingual, I decided using the FTE would be a good choice. OK, I went a bit off-topic, so let’s get back to it.
How do I positon a simple line of text (flash.text.engine.TextLine) centered on a sprite? The horizontal positioning is easy, because it behaves like every DisplayObject, so we do it like this:
var sptMyTitleSprite:Sprite = new Sprite; sptMyTitleSprite.graphics.beginFill(0xDEDEDE); sptMyTitleSprite.graphics.drawRect(100, 25); sptMyTitleSprite.graphics.endFill(); this.addChild(sptMyTitleSprite); var tlSimpleTextLine:TextLine = myTextBlock.createTextLine(null, 100); sptMyTitleSprite.addChild(tlSimpleTextLine); tlSimpleTextLine.x = (sptMyTitleSprite.width >> 1) - (tlSimpleTextLine.width >> 1);
What I do in the code above, is creating a Sprite and draw a rectangle (100 width, 25 height) onto that Sprite. After adding the Sprite onto my displayList, I create my textLine from a TextBlock(not defined in the code above), and finally add the textLine onto my Sprite. When this is done, the textLine’s x-position is centered with the calculation(bitShift by 1 is a simple divison by 2, where the result is an integer).
Ok, that wasn’t too hard, it’s something I do very often. Well, I thought positioning the title in the vertical center of my Sprite is even that simple – Naaah, it’s not! Did you really thought it was that simple, hrhr :D
tlSimpleTextLine.y = (sptMyTitleSprite.height >> 1) - (tlSimpleTextLine.height >> 1);
That does not work. The 0, 0 Point of a TextLine (Roman) is always on the very left of the baseline.
(I catched this image from the Adobe docs).
This behaviour causes the main part of our textLine to be in the negative y-direction(up) of it’s DisplayObject. The Adobe-People may again have smoked one pipe too much while coding this ;-) just kidding!
So when I calculate the vertical center of the Sprite (sprite.height >> 1), and I position the textLine at that position, it will nearly be centered, because it’s baseline is now at y: (sprite.height >> 1).
What we have to do, to position it at the absoule center, is subtracting the half of the textLine’s decent-value. That is everything what’s below the baseline. For example the lower parts of “j, g, y”.
The final solution will be:
tlSimpleTextLine.y = (sptMyTitleSprite.height >> 1) - (tlSimpleTextLine.descent >> 1);
I wrote this post, because I didn’t find any solution to this in the net. This will hopefully help other people.