0

So, I'm creating a game in HTML/JS (Mostly Jquery).

I got an array of objects initialized at the beginning of the game (when user press P to play).Each object is a falling object (I know it's failing with a boolean named "working"), with "move" method setting a position going from 1 to 22. Each time it move, it show the current div with a number as ID (representing the position), and hide the previous div.

The problem is that, the game work perfectly with only one instance of the Object (so only one cell in the array), but when I try to put few other object, they don't move.

Here is the object constructor :

function flyers(){
this.pos = 0;
this.working = false;
this.jump = 0;
this.interval;
this.move = function(){
        if (this.working == true){

                if (this.pos == 22)
            {
                $("#perso21").hide();
                this.pos = 0;
                this.startWork();
            }
            checkSave();
        if (this.jump == 0)
            {   if ((this.pos == 5 && playerPos != 1) || (this.pos == 13 && playerPos != 2) || (this.pos == 19 && playerPos != 3))
            {
                this.die();
            }
                if ((this.pos == 4 && playerPos == 1) || (this.pos == 12 && playerPos == 2) || (this.pos == 18 && playerPos == 3))
                    this.jump = 1;
        }
        else
        {
            if (this.pos == 5 || this.pos == 13 || this.pos == 19)
            {
            score++;
            this.jump = 0;
            }
            $(".score").html("" + score + "");
        }
            $("#perso" + (this.pos - 1) + "").hide();
            $("#perso" + this.pos + "").show(); this.pos++;
        }
        else
            clearInterval(this.interval);
    };
this.startWork = function()
{
    clearInterval(this.interval);
    this.working = true;
    this.interval = setInterval(this.move, 1000 - (score / 10 * 100));
}
this.die = function(){

    this.working = false;
    this.pos = 0;
    this.jump = 0;
    if (miss < 2)
        {
            miss++;
        }
    else
        {
            quitGame();
        }
        clearInterval(this.interval);
};
return this;}

And the array initialization :

flyerstab[0] = new flyers();
flyerstab[1] = new flyers();
flyerstab[2] = new flyers();
flyerstab[3] = new flyers();
flyerstab[0].startWork();

The spawner (only possible to have 4 objects falling at the same time)

spawn = setInterval(function()
{
    var i;

    for (var i = flyerstab.length - 1; i >= 0; i--) {
        if (flyerstab[i].working == false)
        {
            flyerstab[i].startWork();
            break;
        }
        else
            console.log(i + " is working");
    };
}, 5000 - (score / 10 * 100));

I tried to find why all the day, but I didn't manage to.. Am I constructing them bad ?

  • 2
    Uh, you don't call startWork() the other flyers in flyerstab? – pmac89 Mar 04 '15 at 21:48
  • Oh well, didn't put the spawner code... Editing it. –  Mar 04 '15 at 21:50
  • 1
    Missing some context here, but if all of your instances of flyers are hiding the same elements (e.g. #perso21, #perso+pos) then at best, they're goign to step on each other's toes right. – bvaughn Mar 04 '15 at 21:51
  • You should remove the `return this;` in the constructor. – Hacketo Mar 04 '15 at 21:51
  • @brianvaughn they can't, they spawn at different time, and fall at the same speed... –  Mar 04 '15 at 21:53
  • @Hacketo Ok, I'll make some research to understand why it's not suitable. –  Mar 04 '15 at 21:54
  • They're finding elements by ID - meaning they're going to find the same element. I don't think this is what you want. If you have 10 `flyers` running, and they're all touching the same DOM element, it is, at best, the same as having 1 `flyer` running. – bvaughn Mar 04 '15 at 22:05

1 Answers1

0

Inside of this.interval = setInterval(this.move, 1000 - (score / 10 * 100));, this.move is called with this as the global context. Instead, use

this.interval = setInterval(this.move.bind(this), 1000 - (score / 10 * 100));
Travis J
  • 81,153
  • 41
  • 202
  • 273
  • @ThomasCruveilher - You're welcome :) Callback functions inside of setInterval and setTimeout are always scoped to the window, as are functions which are used as expressions. Using bind allows you to retain the context you were looking for. Here is some more information on `this`: http://stackoverflow.com/a/28443915/1026459 . Food for thought :) – Travis J Mar 04 '15 at 22:03