Question

I'm working on a very simple (1st project) "game" with various achievements. In fact, that's pretty much all there is to the game.

Let's say we have 3 possible achievements:

  • Game started
  • You played 5 seconds
  • You played 6 seconds.

(I know, I know, I can hear you: Wow, looks like a super fun game concept ! hehe)

I'm trying to build a generic function in charge of displaying the achievement message on the screen, and remove it 2 seconds after it had been displayed. It mean multiple achievement can be displayed at the same time. But each should disapear after their own 2 seconds.

I tried to instanciate a new timer for each achievement whitout success. The problem is that each time need a name, and a callback function, and I have no way to link a timer to an achievement message since I have to use the callback function. I'm sure I'm just doing it wrong since it's my first project, so I'm asking for some help.

Here's the code I have to display an achievement:

var genericTimer:Array = new Array();
function displayAchievement(msg){
    var myTextBox:TextField = new TextField();    
    myTextBox.text = msg;
    myTextBox.x = 50;    
    myTextBox.y = 20; 
    addChild(myTextBox);

    genericTimer[] = new Timer(2000, 1);
    //Make myTextBox (of this instance only) disapear after 2 seconds
}
Was it helpful?

Solution 2

You can achieve this by the help of anonymous function. Personally I don't like them, but such approach will give you minimum of code:

function displayAchievement(msg:String):void {
    var myTextBox:TextField = new TextField();
    myTextBox.text = msg;
    myTextBox.x = 50;
    myTextBox.y = 20;
    addChild(myTextBox);

    var timer:Timer = new Timer(2000, 1);
    timer.addEventListener(TimerEvent.TIMER_COMPLETE, function (e:TimerEvent):void {
        removeChild(myTextBox);
    });
    timer.start();
}

OTHER TIPS

I would personally do it using an Event.ENTER_FRAME handler.

const TIME_TO_DISPLAY_ACHIEVEMENTS:uint = 2000; //ms
var achievements:Vector.<Object> = new Vector.<Object>();
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);

function displayAchievement(msg){
    var myTextBox:TextField = new TextField();    
    myTextBox.text = msg;
    myTextBox.x = 50;    
    myTextBox.y = 20; 
    addChild(myTextBox);

    achievements.push({tf:myTextBox, time:getTimer()});
}

function enterFrameHandler(e:Event):void {
    var i:uint, l:uint, t:uint;
    t = getTimer();
    l = achievements.length;
    for (i = l - 1; i >= 0; i--) {
        if (achievements[i].time + TIME_TO_DISPLAY_ACHIEVEMENTS <= t) {
            removeChild(achievements[i].tf);
            achievements.splice(i, 1);
        }
    }
}

That's untested and I wrote it pretty quickly, so you may need to alter it to make it compile and/or run.

Basically, you add an object with the achievement and a timestamp to a Vector or array. Then on each frame, you quickly cycle backward (to account for removing objects) through and check if any have expired. If they have, you remove them from the stage and from the vector/array.

This could definitely be optimized and you could replace ENTER_FRAME with a Timer that runs every 100ms or something to save on CPU time, but it should work

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top