2015-09-19 2 views
0

Я делаю змейку через javascript, и у меня есть 2 проблемы.Не работает условие для убийства змеи плюс неработающее свойство объекта

Первая проблема: я установил условие для «убийства» змеи, когда его X и Y попадают в рамку холста, и я не могу понять, почему он не работает.

Вторая проблема: мой метод «рисовать» из «змеи» отлично работает, как он написан, но если я вместо «var i = snake.dlzka» «var i = snake.snake_body.length», он набирает error: Невозможно прочитать свойство «x» неопределенного.

var canvas = document.getElementById("canvas"); 
 
canvas.width = 800; 
 
canvas.height = 650; 
 
var ctx = canvas.getContext("2d"); 
 

 
var dotW = 10; 
 
var dotH = 10; 
 
var direction = "right"; //smer pohybu hadika 
 

 
var snake = { 
 
    dlzka: 5, 
 
    snake_body: [], 
 
    
 
    arraySpawn: function(){ 
 
     for(var i = snake.dlzka; i >= 0; i--){ 
 
      this.snake_body.push({ 
 
       x: i*dotW, 
 
       y: 0 
 
      }); 
 
     } 
 
    }, 
 
    
 
    
 
    draw: function(){ 
 
     ctx.clearRect(0,0, canvas.width, canvas.height); 
 
     for(var i = snake.dlzka; i>0; i--){ 
 
      //alert(snake.snake_body.length); 
 
      ctx.fillStyle = "blue"; 
 
      ctx.fillRect(snake.snake_body[i].x, snake.snake_body[i].y, dotW, dotH); 
 
     } 
 
     snake.move(); 
 
    }, 
 
    
 
    
 
    move: function(){ 
 
     var first = snake.snake_body[0]; 
 
     var first_x = first.x; 
 
     var first_y = first.y; 
 
     
 
     
 
     
 
     switch(direction){ 
 
      case "right": 
 
       first_x += 10; 
 
       break; 
 
       
 
      case "left": 
 
       first_x -= 10; 
 
       break; 
 
       
 
      case "up": 
 
       first_y -= 10; 
 
       break; 
 
       
 
      case "down": 
 
       first_y += 10; 
 
       break; 
 
     } 
 
     
 
     this.snake_body.pop(); 
 
     this.snake_body.unshift({ 
 
      x: first_x, 
 
      y: first_y 
 
     }); 
 
     
 
     if((first_x == canvas.width || 0) || (first_y == canvas.height || 0)){ 
 
      var restart = confirm("Do you want to play again?"); 
 
      if(restart){ 
 
       clearInterval(intervalID); 
 
       snake.snake_body = []; 
 
       snake.arraySpawn(); 
 
       intervalID = setInterval(function(){snake.draw()}, 33); 
 
      } 
 
     } 
 
    }, 
 
    
 
    
 
    update_direction: function(e){ 
 
     var key = e.keyCode; 
 
     
 
     if(key == 37 && direction !== "right"){ 
 
      direction = "left"; 
 
     }else if(key == 38 && direction !== "down"){ 
 
      direction = "up"; 
 
     }else if(key == 39 && direction !== "left"){ 
 
      direction = "right"; 
 
     }else if(key == 40 && direction !== "up"){ 
 
      direction = "down"; 
 
     } 
 
    } 
 
}; 
 

 

 
snake.arraySpawn(); 
 
var intervalID = setInterval(function(){snake.draw()}, 33); 
 
window.onkeydown = snake.update_direction;
canvas{ 
 
    border: 1px solid black; 
 
}
<canvas id="canvas"></canvas>

скрипку: http://jsfiddle.net/scarface/pdz4k8dj/20/

ответ

1

Первая проблема возникает из фрагмента кода (first_x == canvas.width || 0) На основе operator precedence правил и слева направо оценки, это имеет значение

((first_x == canvas.width) || 0) 

который это не то, что вы хотели. Попробуйте

(first_x == canvas.width || first_x == 0) 

вместо этого ознакомьтесь с правилами, чтобы убедиться, что вы понимаете, почему. Обратите внимание на тест требует холста, чтобы быть точным кратным х (или у) размер змея перемещается, и это, возможно, было бы лучше записать как

(first_x >= canvas.width || first_x <= 0) 

Не забудьте изменить тест у значения потому что он имеет точно такую ​​же проблему.

Вторая проблема связана не с учетом того, что индексы массива основаны на нуле. Таким образом,

for(var i = snake.snake_body.length; i>0; i--) 

Итерации из конца конца массива (генерирования ошибки) возвращаются ко второму элементу. Изменение этого параметра на

for(var i = snake.snake_body.length - 1; i >= 0; i--) 

работал в скрипке.

Смежные вопросы