2013-06-13 3 views
5

Я строю небольшую игру JavaScript, но после просмотра учебников и еще чего-то в Интернете, это просто не работает для меня. Чтобы избавить вас от некоторых неприятностей, вот те части, где, как я думаю, все могло бы пойти не так (реальная проблема объясняется чуть ниже).Простая игра Javascript: Возможная ошибка массива объектов

Он работает на очень простом цикле сейчас и у меня есть массив для хранения болтов игрока, как он стреляет в них:

var playerBolts=new Array(); //Holds all the bolt objects that the player shoots 

setInterval(function(){ 
    updateGame(); 
    drawGame(); 
},25); 

Это объект болт, который создается, когда игрок стреляет.

function bolt(facing,playerX,playerY){ //The bolt object is shot from the player's current position 
    this.facingLeft=facing; //The direction at which the bolt moves, if left, true 
    this.x=playerX; //The x position of the bolt 
    this.y=playerY; //The y position of the bolt 
    if(facingLeft==true){ 
     this.xSpeed=-3; //The horizontal speed at which the bolt is moving 
    } 
    else if (facingLeft==false){ 
     this.xSpeed=3; 
    } 
    this.ySpeed=0; //The vertical speed at which the bolt is moving 
    this.W=3; //The width of the bolt's model 
    this.H=3; //The height of the bolt's model 
    this.color="red"; //The color of the bolt's model 
    this.update=update; 
    function update(){ //Updates the bolt's properties 
     this.x=this.x+this.xSpeed; 
     this.y=this.y+this.ySpeed; 
    }  
    this.draw=draw; 
    function draw(){ //Draws the bolt's model to the canvas 
     context.fillStyle=this.color; 
     context.fillRect(this.x, this.y, this.W, this.H); 
    } 
} 

Когда всходы «игрок», метод Задвижка от объекта игрока называется:

function player(){ //The player object 
    this.facingLeft=true; //If the player's character is facing left, true 
    this.x=100; //The x position of the player 
    this.y=100; //The y position of the player 
    this.shootBolt=shootBolt; 
    function shootBolt(){ //Shoots a bolt, creating a new bolt object and adding it to the playerBolts array  
     playerBolts.push(bolt(this.facingLeft,this.x,this.y)); 
    } 
} 

Проблема заключается в том, что следующий болт становится все быстрее каждый следующий выстрел. Чем больше вы стреляете, тем быстрее они становятся. Кроме того, предполагается, что при стрельбе видны несколько болтов, но каждый раз, когда вы стреляете, предыдущий исчезает.

Теперь игра проходит через функции обновления и рисования. Я использовал для

function updateGame(){ //The main update phase 
    player1.update(); //Updates the player's properties 
    playerBolts.forEach(function(bolt){ //Updates all active bolts's properties 
     this.update(); 
    }); 
} 
function drawGame(){ //The main drawing phase 
    context.fillStyle="white"; 
    context.fillRect(0,0,canvasW,canvasH); //Clears the canvas for the next frame 
    player1.draw(); //Draws the player 
    playerBolts.forEach(function(bolt){ //Draws all bolt's model to the canvas 
     this.draw(); 
    });  
} 

Так да ... Я думаю, что это, возможно, придется делать с тем, как я добавить объекты с «толчком» к массиву, метод «Foreach» (хотя я пытался цикл for тоже). Я не знаю, что я делаю неправильно, и я искал источники, и это должно работать нет? Если информации недостаточно, я всегда мог бы опубликовать все это (всего 119 хорошо задокументированных строк).

спасибо.

+0

Спасибо за все ответы, я попробую то, что вы упомянули как можно скорее, и вернитесь к каждому! –

ответ

1

Проблема заключается в том, что function bolt(facing,playerX,playerY){ не создает новый bolt, он просто устанавливает переменные в том же месте, как и раньше:

function bolt(facing,playerX,playerY){ //The bolt object is shot from the player's current position 
    this.facingLeft=facing; //The direction at which the bolt moves, if left, true 
    ... 

-Так вы не вызываете bolt на новый объект, вызовите его из одно и то же место каждый раз, все переменные, которые вы устанавливаете под this, постоянно переусердствуют.

+0

Спасибо, это была одна из проблем :) –

4

Я подозреваю, что у вас проблемы с this. Вы строите bolt объектов по телефону:

bolt(this.facingLeft, this.x, this.y) 

Однако внутри функции bolt, вы используете this, как будто это относится к вновь созданному болтом. К сожалению, нет. Попробуйте строить болты, как это вместо:

new bolt(this.facingLeft, this.x, this.y) 

Если вы делаете это таким образом, то this внутри bolt относится к вновь созданному объекту.

Кроме того, это this также, возможно, не так:

playerBolts.forEach(function(bolt){ //Draws all bolt's model to the canvas 
    this.draw(); 
}); 

По странным причинам, this в вашей функции петли могут или не могут быть ваши болты (см https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach).Просто чтобы быть в безопасности, попробуйте вместо этого:

playerBolts.forEach(function(bolt){ //Draws all bolt's model to the canvas 
    bolt.draw(); 
}); 

К слову, new вопрос является очень распространенным явлением; Я делаю это привычкой делать мои функции конструктора, поэтому они работают либо с new, либо без них. Чтобы сделать это, вместо использования this просто введите bolt, чтобы вернуть новый объект вместо управления this. Потому что JS-х this ужасно запутанная, я считаю, это гораздо лучший подход:

function bolt(facing,playerX,playerY){ //The bolt object is shot from the player's current position 
    var theBolt = { 
     facingLeft: facing,   //The direction at which the bolt moves, if left, true, 
     x: playerX,     //The x position of the bolt 
     y: playerY,     //The y position of the bolt 
     xSpeed: facingLeft ? -3 : 3, //The horizontal speed at which the bolt is moving 
     ySpeed: 0,     //The vertical speed at which the bolt is moving 
     W: 3,       //The width of the bolt's model 
     H: 3,       //The height of the bolt's model 
     color: 'red',     //The color of the bolt's model 
     update: update, 
     draw: draw 
    }; 
    function update(){ //Updates the bolt's properties 
     theBolt.x = theBolt.x + theBolt.xSpeed; 
     theBolt.y = theBolt.y + theBolt.ySpeed; 
    }  
    function draw(){ //Draws the bolt's model to the canvas 
     context.fillStyle = theBolt.color; 
     context.fillRect(theBolt.x, theBolt.y, theBolt.W, theBolt.H); 
    } 

    return theBolt; 
} 
+0

Большое вам спасибо, это было то, что было не так (как моя петля forEach была сделана, и мой объект болта). Не могу поблагодарить вас за то, что вы так долго спасли меня. Кстати, теперь я знаю «возвращение theBolt»; важно, но почему? Я не уверен, что он делает. –

+1

Это означает, что результатом вызова 'bolt (...)' является тот объект 'theBolt', который был создан. – Jacob

+0

Человек столько, что я должен научиться ... ну, что покрывает его тогда, еще раз спасибо :) –

0

Как уже сказал, ваша проблема в том, что вы не создаете новый болт каждый раз, просто вызовите функцию затвора. Таким образом, «это» в функции ссылается на глобальный объект, поэтому у вас есть только один болт, который обновляется несколько раз.

Кроме того, следующее:

> if(facingLeft==true){ 
>  this.xSpeed=-3; //The horizontal speed at which the bolt is moving 
> } 
> else if (facingLeft==false){ 
>  this.xSpeed=3; 
> } 

можно заменить с помощью ?: conditional operator (он же тройной оператор):

this.xSpeed = facingLeft? -3 : 3; 

А где у вас есть:

> this.update=update; 
> function update(){ //Updates the bolt's properties 
>  this.x=this.x+this.xSpeed; 
>  this.y=this.y+this.ySpeed; 
> } 

Вы можете назначить функция непосредственно использует выражение функции:

// Update the bolt's properties 
this.update = function() { 
    this.x = this.x + this.xSpeed; 
    this.y = this.y + this.ySpeed; 
} 

или еще лучше, поставить функцию на прототип конструктора, так что все экземпляры наследуют ту же функцию:

bolt.prototype.update = function() { 
    ... 
} 

Same для рисовать метод. И немного больше пробелов в вашем коде сделает его более читаемым. :-)

+0

Привод вниз. Круто. Кажется, сейчас у меня около миллиона. – RobG

+0

Спасибо, я попробую использовать некоторые вещи наверняка, уже на самом деле! (Я проголосовал за вас: O) –

+0

Прохладный, проезд - это факт жизни здесь. :-) – RobG