Sam Street
Sam Street

Reputation: 306

Create new instance of function while looping

I am trying to create a simple background for a game I am making and require new instances of my function each time my loop runs.

Previously I have tried calling my function as so:

Sprite();
Sprite();
Sprite();
Sprite();
Sprite();
Sprite();
Sprite();

this worked and created several instances of that function. However, when I try this in a loop it just creates 10 of the same instance rather than calling it again as a new instance.

The code I have tried is:

for(var i = 0; i <= 10; i++){
    Sprite();
    setTimeout(Sprite, 1000);
}

function Sprite(){
    // set the sprite properties
    this.r = 30 * Math.random().toFixed(2);
    this.x = Math.floor(Math.random(Math.random()) * 5000);     //Start position
    this.y = Math.floor(Math.random(Math.random()) * 5000);     //Start position
    this.dx = Math.floor(this.x + this.r);                      //Destination position
    this.dy = Math.floor(this.y + this.r);                      //Destination position
    this.s = Math.random(Math.random()).toFixed(2)* 5000;
    this.active = true;

    //create the sprite
    var div = document.createElement('div');
    div.id = 'block';
    div.className = 'block';
    document.getElementsByTagName('body')[0].appendChild(div);

    // call the animate function
    animSprite();

    // logging output
    console.log("sprite has been created: \nthis.r = " + r + "\nthis.x = " + x + "\nthis.y = " + y + "\nthis.dx = " + dx + "\nthis.dy = " + dy + "\nthis.s = " + s + "\nanimSprite() = true");
}

the above calls the following to animate the divs: //animate the sprite

function animSprite(n){ 
    //will need a switch case to determine which shape has which properties 
    switch(n){
        case 1:
            // animate the div
            $('.block').animate({
               top: this.y,
               right: this.x
            }, this.s);
        break;
        case 2:
            // animate the div
            $('.block').animate({
               top: this.y,
               bottom: this.x
            }, this.s);
        break;
        case 3:
            // animate the div
            $('.block').animate({
               bottom: this.y,
               right: this.x
            }, this.s);
        break;
        case 4:
            // animate the div
            $('.block').animate({
               left: this.y,
               bottom: this.x
            }, this.s);
        break;

    }
}

Where have I gone wrong and how can I fix it is as if a new function is called every time the loop runs? I would prefer a jQuery free solution but I am open to using it.

Upvotes: 0

Views: 113

Answers (2)

Givi
Givi

Reputation: 1734

If I understood you correctly, this is what you are trying to achieve:

Demonstration

(function () {
    "use strict";

    function Sprite() {
        var ele = null;

        this.s = Math.random().toFixed(2) * 5000;
        this.r = Math.random().toFixed(2) * 30;
        this.x = Math.floor(Math.random() * 5000);
        this.y = Math.floor(Math.random() * 5000);
        this.dx = Math.floor(this.x + this.r);
        this.dy = Math.floor(this.y + this.r);
        this.active = true;

        if (typeof Sprite._div === "undefined") {
            Sprite._i = 0;
            Sprite._div = document.createElement("div");
            Sprite._div.id = "block";
            Sprite._div.className = "block";
        }

        ele = Sprite._div.cloneNode(true);
        document.body.appendChild(ele);

        animSprite.call(this, ++Sprite._i, ele);
    }

    function animSprite(n, ele) {
        var obj = null;
        switch (n % 4) {
            case 0:
                obj = {
                    top: this.y,
                    right: this.x
                };
                break;
            case 1:
                obj = {
                    top: this.y,
                    bottom: this.x
                };
                break;
            case 2:
                obj = {
                    bottom: this.y,
                    right: this.x
                };
                break;
            case 3:
                obj = {
                    left: this.y,
                    bottom: this.x
                };
                break;
        }
        $(ele).animate(obj, this.s);
    }
    for (var i = 1; i <= 50; i++) {
        setTimeout(function () {
            new Sprite();
        }, i * 1000);
    }
}());

Upvotes: 1

Spencer Wieczorek
Spencer Wieczorek

Reputation: 21575

This is because setTimeout() does not stop the codes execution, the code keeps going and there a multiple over-written calls. I recommend doing a setInterval() after the for loop or simply print it out on the console.

For example using a property for clarity:

function Sprite(name){ this.name = name; console.log(name); }

var array = ['a','b','c','d','e','f','g','h','i','j']
for(var i = 0; i < 10; i++){
    Sprite(array[i]);
}

http://jsfiddle.net/4Y5se/

Upvotes: 0

Related Questions