Search code examples
javascriptgame-physics

findout when all setimeouts finish


Checkout this demo/game i am building http://awebdeveloper.github.io/runners/

I wish to know when will all the players finish running. The Game class needs to know when all the player stop and who came first.

My question is is there a way to inform back the calling class when each of the animate finish after all the settimeout

Player Class

function Players(ele, ptimeout)
{
    this.movePositions  = [0, 40, 80, 120],
    this.moveBy         = 5
    this.el = ele;
    this.i = 0;
    this.stop = 1;
    this.timeout = ptimeout;
    this.position = 0;

    this.animate = function(){
        /* Stop if stopped */
        playerPosition = this.el.getBoundingClientRect();
        if(this.stop || playerPosition.left > (racetrack.offsetWidth - 30)){
            this.el.style.backgroundPosition = '120px 0px';
            return ;
        }

        playerPosition = this.el.getBoundingClientRect();
        if(this.stop || playerPosition.left > (racetrack.offsetWidth - 30)){
            this.el.style.backgroundPosition = '120px 0px';
            return ;
        }

    /* Prepare Next Move */
        setTimeout(function(_this){ 
            if(_this.i < _this.movePositions.length ){
                _this.i ++;
            }
            else{
                _this.i = 0;
            }
            _this.move();
            _this.animate();
        },this.timeout,this);
    };

    this.play = function(){
        if(this.stop === 1){
            this.stop = 0;
            this.animate();
        }
    };

    this.move = function(to,positionIndex){
        this.position = to;
        this.el.style.backgroundPosition = '-'+this.movePositions[positionIndex]+'px 0px';
        this.el.style[getSupportedPropertyName('transform')] = 'translate('+to+'px)';
    }
}

Game Class

function Game(noOfPlayers){

    var track_tmpl      = '<div class="track"><div id="player{{ x }}" class="runner"></div></div>';
    this.noOfPlayers = noOfPlayers;

    this.players = new Array();

    for (var i = 0; i < this.noOfPlayers ; i++){
        var timeout = 120 + getRandomInt(1, (this.noOfPlayers*2));
        racetrack.appendChild(createNode(track_tmpl.replace('{{ x }}', i)));
        this.players.push(new Players(document.getElementById('player' + i), timeout));
    }



    this.play = function(){
        for (var i = 0; i < this.noOfPlayers; i++){
            this.players[i].play();
        }
    };
}

Solution

  • on Player.play pass the this argument, to call from Person a function from Game. So you will have a code like this

    this.play = function(){
        for (var i = 0; i < this.noOfPlayers; i++){
            this.players[i].play(this);
        }
    };
    

    then on Player modify the code like this

    this.play = function(game){
        if(this.stop === 1){
            this.stop = 0;
            this.animate(game);
        }
    };
    

    after on method animate call the game.playerFinished(Player)

    on Game class write a method

    var i = 0;
    this.playerFinished = function(player) {
        console.log(player.name + " finished on position " + (i++));
    }
    

    where player.name a name you give on players class