1

I'm trying to create an array of objects for a simple canvas-based Space Invaders game. I have created a space invader object, and an array of space invaders. I want to slightly change the horizontal position and other properties of each invader before it is added to the array. This is how I'm trying to do it:

// Invaders
invaders = new Array();
invader = {
    x: 0,
    y: 0,
    size: 25,
    xspeed: 0.25,
    yspeed: 0.1,
    alive: 1,
    letter: ""
};

invadersMovingLeft = true;
kills = 0;

word = "interesting";
numberOfInvaders = word.length;
letters = word.split('');
letterNumber = 0;
xpos = 0;
invaderSpacing = 50;
exploding = false;
shuffledLetters = shuffle(letters);
hitLetters = "";

for (i = 0; i < numberOfInvaders; i++) {
    invader['letter'] = shuffledLetters[letterNumber];
    invader['x'] = xpos;
    xpos = xpos + invaderSpacing;
    letterNumber = letterNumber + 1;
    invaders[i] = invader;
    console.log(invaders);
}

The console log shows that each invader has the exact same properties. Any idea what's going wrong here? I'm new at working with objects, and am probably making a beginner's mistake.

2 Answers 2

1

The problem is you are trying to use invader as a base object, which makes all of the invaders refer to the same object.

Instead of that, have an invader which acts like a class, that you can instantiate to make a new invader. Each invader is then a new independent instance, which you can push to the array.

function invader(){
    this.x = 0;
    this.y = 0;
    this.size = 25;
    this.xspeed = 0.25;
    this.yspeed = 0.1;
    this.alive = 1;
    this.letter = "";
}

var invaders=new Array();
var inv;

for(i=0;i<numberOfInvaders;i++){
    inv = new invader();
    inv.letter = shuffledLetters[letterNumber];
    inv.x = xpos;
    xpos = xpos+invaderSpacing;
    letterNumber = letterNumber+1;
    invaders.push(inv);
}

console.log(invaders);
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, this helps a lot. So, it is the case that properties in objects can't be changed the way I was trying to do it? Once they're set, they're permanent?
Object properties can be changed. For example: var obj = {a:'hi'}; obj.a // => 'hi'; obj.a = 'bye'; obj.a; // => 'bye' but if you say obj2 = obj, have now made a new reference to the same object. Any changes you make to obj2 will affect obj. And any changes you make to obj will affect obj2. So that is why you need to use the new keyword when instantiating your individual invaders. The syntax you are using for the invader() constructor allows you to use 'new' to instantiate individual instances.
@user3737956 no they're not permanent, you can freely change the properties any time, as long as you have a reference to the object. In your code you were working with the invader then appending it to the array, so you were adding the same reference to the same object to the array every time. My code creates an invader class, and creates multiple instances of it, which are all independent from each other.
Thank you to both Mr. Code and LexJacobs - I think I understand now. All the elements in the array were referring to the same object, (the most recently modified one) and that's why all the objects in the array had the same properties - they were the same object.
0

Try adding

var newInvader = new invader(); 

to your loop. (first line)

Then change the properties of newInvader to what you want, then add newInvader to the array instead of invader.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.