0

i'm trying to call an objects methods at the same time with a loop. I would create a game with a group of enemies that are move at the same time.

I create an object "Warrior"

    function Warrior(x, y) {

    // Coordinates x, y 

    this.x = x;
    this.y = y;

    this.character = $('<div class="enemy"></div>');

    // Inserting the div inside #map
    this.character.appendTo('#map'); 


    // assigning x and y parameters

    this.character.css({        

        marginLeft: x + 'px',
        marginTop: y + 'px'

    });

    // walk method that move the div

    this.walk = function() {

        // Moving div 10px to the right
        this.character.css('left', "+=10");

    }

    }

    var enemies = new Array();
    enemies[0] = new Warrior(0, 0);
    enemies[1] = new Warrior(10, 20);
    enemies[2] = new Warrior(60, 80);

    for(var i=0;i<enemies.length;i++) {
        setInterval(function(){enemies[i].walk()}, 1000);
    }

I've created an array "enemies"

and I tried to call walk() methods at the same time

But nothing it happens. I would like that the divs are moving at the same time!

Thanks!

  • 1
    Have you tested `walk()` on any enemy, does it move? If it doesn't, then the problem is not in loop. – sybear May 26 '14 at 21:09

2 Answers2

0

Based on this question

You might want to pass a parameter by value to setInterval:

for(var i=0;i<enemies.length;i++) {
    setInterval(
        function(index){   //<-- accept parameter here
            enemies[index].walk();
        }, 1000, i);       //<-- pass i here
}

If you do not pass the parameter, x variable changes while loop is running, thus all the functions will be called having x = 2 (because you have 3 elements in your array)

Community
  • 1
  • 1
sybear
  • 7,837
  • 1
  • 22
  • 38
0

You have two major problems where:

  1. CSS does not allow programmatic modification in the way that javascript does. You modify values in javascript, and then set them in CSS:

    this.walk = function() {
        var current = parseInt(this.character.css('left')),
            stepped = current + 10;
        this.character.css('left', stepped);
    }
    
  2. Your loop creates a closure on var i which is only declared once, so the same value will be shared across the functions. You can either have the function take a parameter, and provide it in the setInterval call:

    • setInterval(function(index) { /* ... */}, 1000, i);

    or you can put the loop within the interval function:

    setInterval(function() {
        for (var i = 0; i < enemies.length; i++) {
             enemies[i].walk();
        }
    });
    

You might also want to reconsider whether your walk function should modify the CSS directly. You've already forgotten about your x and y coordinate attributes in this code. Perhaps you should have a walk method that modifies these coordinates, and a draw function that updates the sprites' positions based on their current coordinates.

John Spong
  • 1,361
  • 7
  • 8