1
votes

I'm making a Flash AS3 based game, and I'm building a custom font system. It works like this: a BitmapData class takes a PNG file from the library (FontSource), loops between every character in a given string and then gets its x, y, width and height inside the image from a function (getOffset), and then it uses copyPixels to draw the custom-font text.

Here's the code:

public function draw(str) {
    var png = new FontSource(480, 32);
    var offsets;
    var char;
    var rect;
    var x;
    var y;

    this.lock();
    for (var i = 0; i < str.length; i++) {
        char = str.substr(i, 1);
        offsets = getOffsets(char);

        rect = new Rectangle(offsets[0], offsets[1], offsets[2], offsets[3]);
        this.copyPixels(png, rect, new Point(x, y));
        x += offsets[2];
    }

    this.unlock();
}

Now, the question here is: I'm building a typewriter effect class based on the ENTER_FRAME event; each new frame, a new character is added to a string. So, I wanted to ask which one of these approaches would do better related in a matter of performance:

1) Call draw() to redraw the whole BitmapData each frame.

2) Making an alpha mask and expand its width each frame.

3) Making separate Objects and adding them to stage each frame.

Thank you for your time.

1
1) Updating the existing BitmapData is fine. Just don't create a new instance of the FontSource each time you do so.Organis
Thank you for your reply.Ali

1 Answers

1
votes

As an alternative, you don't need to redraw the entire string. You can just draw more characters at its end. I'd implement this as follows: You give your bitmapped textfield a string it should draw per frame, once. It clears, then at each enter frame event it just adds 1 to the length of the string drawn, and draws only one single character. Just save more data in your class for this. For example:

public class BTF extends Sprite {
    private var str:String;
    private var source:FontSource; // set once!
    private var bd:BitmapData; // the one that'll get drawn
    private var lastIndex:int;
    private var lastX:int; // coords to draw next symbol to
    // assuming Y is always 0 - adjust per font
    public function BTF(source:FontSource,width:int,height:int) {
        this.source=source;
        bd=new BitmapData(width,height,0x00808080,true); // check if I didn't mix up parameters
        addChild(new Bitmap(bd)); // make it be drawn on your BTF
    }
    ... // rest of class skipped
    public function onEnterFrame(e:Event):void { 
        if (lastIndex>=str.length) return; // drawn all text already
        var c:char=str.charAt(lastIndex++); // get next char to draw
        var r:Rectangle=source.getOffsets(c); // you need to specify source for that - it's font that gives you bounds
        bd.copyPixels(source.fontBitmapData,r,new Point(lastX,0)); // draw that char
        lastX+=r.width; // move "cursor"
    }