user2170842
user2170842

Reputation:

Variables being changed for no reason

I am making a very simple thing where things fall from the top of the screen and (once finished) you will have to grab them. I store all objects falling (bottles) inside an array. When there is one object, it draws fine and it's Y position increases normally, yet when there are more than one they are all given exactly the same X and Y. I have no idea what is causing this.

This is the whole file:

var canvas = document.getElementById("canvas");
var canvasWidth = 600;
var canvasHeight = 500;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
var ctx = canvas.getContext("2d");

var bottle = {
    x: 0,
    y: 0,
    hasFell: false,
    height: 0,
    width: 0,
    src1: "water1.png",
    src2: "water2.png"
}

var bottles = new Array();
bottles.length = 20;
bottleImage = new Image();
bottleImage.src = bottle.src1;
fellBottleImage = new Image();
fellBottleImage.src = bottle.src2;

var makeBottle = function(){
    //If math.random above 7 add new bottle
    if(Math.random() > 0.7){
        var madeBottle = false;
        for(var i = 0; i < bottles.length; i++){
            if(bottles[i] == null){
                //It only goes in here once, after it has made one bottle it exits the loop
                madeBottle = true;
                bottles[i] = bottle;

                //These are the only things that change both the X and the Y, yet these cannot be the problem.
                bottles[i].x = Math.random() * 100;
                bottles[i].y = Math.random() * 100;


                console.log("Made bottle: " + i + " X: " + bottles[i].x + " Y: " + bottles[i].y);
                break;
            }
        }
        if(!madeBottle){
            for(var i = 0; i < bottles.length; i++){
                if(bottles[i].hasFell){
                    bottles[i] = null;
                    makeBottle();
                }
            }
        }
    }
}

var gameUpdate = function(){
    for(var i = 0; i < bottles.length; i++){
        if(bottles[i] != null){
            bottles[i].y += 1;
            if(bottles[i].y > canvasHeight) bottles[i] = null;
        }
    }
    gamePaint();
}

var gamePaint = function(){
    ctx.fillStyle = "#FFFFFF";
    ctx.fillRect(0, 0, canvasWidth, canvasHeight);

    for(var i = 0; i < bottles.length; i++){
        if(bottles[i] != null){
            ctx.drawImage(bottleImage, bottles[i].x, bottles[i].y);
        }
    }
}

var gameInterval = setInterval(gameUpdate, 10);
var bottleInterval = setInterval(makeBottle, 1000);

Upvotes: 0

Views: 68

Answers (2)

Ben McCormick
Ben McCormick

Reputation: 25728

 //These are the only things that change both the X and the Y, yet these cannot be the problem.
 bottles[i].x = Math.random() * 100;
 bottles[i].y = Math.random() * 100;

Sure they can :) you're setting every member of the array to point to the bottle object, then modifying that object. You need to create different objects for each item in the array.

You can do this with

var Bottle = function(){
    this.x = 0;
    this.y = 0;
    this.hasFell = false;
    this.height = 0;
    this.width = 0;
    this.src1 = "water1.png";
    this.src2 = "water2.png";
}

and then

bottles[i] = new Bottle();

That creates a new constructor Bottle, and then instantiates it to create a new object with the property you want for each item in the array.

Upvotes: 3

Mark Reed
Mark Reed

Reputation: 95325

            bottles[i] = bottle;

That makes bottles[i] and bottle point to the same object. At the end of your loop, you still have only a single bottle with a lot of different names.

If you want to make bottles[i] a copy of bottle, you have to do the copying yourself. Here's one way:

bottles[i] = {}
for (var key in bottle) {
    bottles[i][key] = bottle[key];
}

Alternatively, if all bottles are going to start out with the same values, you could make a Bottle constructor function:

function Bottle() {
  this.x = 0;
  this.y = 0;
  this.hasFell = false;
  this.height = 0;
  this.width = 0;
  this.src1 = "water1.png";
  this.src2 = "water2.png";
}

bottle = new Bottle();

...

bottle[i] = new Bottle();

Upvotes: 3

Related Questions