Uncaught TypeError: Cannot set property 'drawSquare' of undefined(Пишу змейку на js помогите пожалуйста)

201
29 января 2018, 07:23

Помогите с ошибкой Uncaught TypeError: Cannot set property 'drawSquare' of undefined...

const random = (max) => (Math.random() * (max + 1)) | 0; 
 
 
let c = document.getElementById('c'); 
let ctx = c.getContext('2d'); 
let width = c.width; 
let height = c.height; 
let blockSize = 10; 
let widthInBlocks = width / blockSize; 
let heightInBlocks = height / blockSize; 
let score = 0; 
let drawBorder = () => { 
  ctx.fillStyle = 'Gray'; 
  ctx.fillRect(0, 0, width, bBorderlockSize); 
  ctx.fillRect(0, height - blockSize, width, blockSize); 
  ctx.fillRect(width - blockSize, 0, blockSize, height); 
}; 
let drawScore = () => { 
  ctx.font = '20px Courier'; 
  ctx.fillStyle = 'Black'; 
  ctx.textAlign = 'left'; 
  ctx.textBaseline = 'top'; 
  ctx.fillText('Счет: ' + score, blockSize, blockSize); 
}; 
let gameOver = () => { 
  clearInterval(intervalId); 
  ctx.font = '60px Courier'; 
  ctx.fillStyle = 'Black'; 
  ctx.textAlign = 'center'; 
  ctx.textBaseline = 'middle'; 
  ctx.fillText('Конец игры: ', width / 2, height / 2); 
}; 
let circle = (x, y, radius, fillCircle) => { 
  ctx.beginPath(); 
  ctx.arc(x, y, radius, 0, Math.PI * 2, false); 
  if (fillCircle) { 
    ctx.fill(); 
  } else { 
    ctx.stroke(); 
  } 
}; 
let Block = (col, row) => { 
  this.col = col; 
  this.row = row; 
}; 
Block.prototype.drawSquare = (color) => { 
  let x = this.col * blockSize; 
  let y = this.row * blockSize; 
  ctx.fillStyle = color; 
  ctx.fillRect(x, y, blockSize, blockSize); 
}; 
Block.prototype.drawCircle = (color) => { 
  let centerX = this.col * blockSize + blockSize / 2; 
  let centerY = this.row * blockSIze + blockSize / 2; 
  ctx.fillStyle = color; 
  circle(centerX, centerY, blockSize / 2, true); 
}; 
Block.prototype.equal = (otherBlock) => { 
  return this.col === otherBlock.col && this.row === otherBlock.row; 
}; 
let Snake = () => { 
  this.segments = [ 
    new Block(7, 5), 
    new Block(6, 5), 
    new Block(5, 5) 
  ]; 
  this.direction = 'right'; 
  this.nextDirection = 'right'; 
}; 
Snake.prototype.draw = () => { 
  for (let i = 0; i < this.segments; i++) { 
    this.segments[i].drawSquare('Blue'); 
  } 
}; 
Snake.prototype.move = () => { 
  let head = this.segments[0]; 
  let newHead; 
  this.direction = this.nextDirection; 
  switch (this.direction) { 
    case 'right': 
      newHead = new Block(head.col + 1, head.row); 
      break; 
    case 'down': 
      newHead = new Block(head.col, head.row + 1); 
      break; 
    case 'left': 
      newHead = new Block(head.col - 1, head.row); 
      break; 
    case 'up': 
      newHead = new Block(head.col, head.row - 1); 
      break; 
  }; 
  if (this.checkCollision(newHead)) { 
    gameOver(); 
    return; 
  } 
  this.segments.unshift(newHead); 
  if (newHead.equal(apple.position)) { 
    score++; 
    apple.move(); 
  } else { 
    this.segments.pop() 
  } 
}; 
 
Snake.prototype.checkCollision = (head) => { 
  let leftCollusion = (head.col === 0); 
  let topCollusion = (head.row === 0); 
  let rightCollusion = (head.col === widthInBlocks - 1); 
  let bottomCollusion = (head.col === heightInBlocks - 1); 
  let wallCollusion = leftCollusion || topCollusion || rightCollusion || bottomCollusion; 
  let selfCollusion = false; 
  for (let i = 0; i < this.segments.length; i++) { 
    if (head.equal(this.segments[i])) { 
      selfCollusion = true; 
    } 
  } 
  return wallCollusion || selfCollusion; 
}; 
 
Snake.prototype.setDirection = (newDirection) => { 
 
  if (this.direction === 'up' && newDirection === 'down') { 
    return; 
  } else if (this.direction === 'right' && newDirection === 'left') { 
    return; 
  } else if (this.direction === 'down' && newDirection === 'up') { 
    return; 
  } else if (this.direction === 'left' && newDirection === 'right') { 
    return; 
  } 
  this.nextDirection = newDirection; 
}; 
let Apple = () => { 
  this.position = new Block(10, 10); 
}; 
Apple.prototype.draw = () => { 
  this.position.drawCircle('LimeGreen'); 
}; 
Apple.prototype.move = () => { 
  let randomCol = Math.floor(random(widthInBlocks)) + 1; 
  let randomRow = Math.floor(random(heightInBlocks)) + 1; 
  this.position = new Block(randomCol, randomRow); 
}; 
let snake = new Snake; 
let apple = new Apple; 
 
let intervalId = setInterval(() => { 
  ctx.clearRect(0, 0, width, height); 
  drawScore(); 
  snake.move(); 
  snake.draw(); 
  apple.draw(); 
  drawBorder(); 
}, 100); 
let directions = { 
  37: 'left', 
  38: 'up', 
  39: 'right', 
  40: 'down' 
}; 
document.getElementsByTagName('body').keydown((event) => { 
  let newDirection = directions[event.keyCode]; 
  if (newDirection !== undefined) { 
    snake.setDirection(newDirection); 
  } 
});
#canvas { 
  width: 400px; 
  height: 400px; 
}
<canvas id="c"></canvas>

Answer 1

Проблема в чрезмерном увлечении стрелочными функциями.

Стрелочная функция не может быть использована в качестве конструктора.

Как следствие, у нее нет специального свойства prototype, которое присутствует у обычных функций. Именно поэтому и получается указанная ошибка.

Для исправления достаточно вместо стрелочных функций использовать обычные.

Либо перейти на использование классов, с использованием ключевого слова class

READ ALSO
Как сделать поиск mysql?

Как сделать поиск mysql?

У меня есть столбец 'region' В нем записаны: Москва, Санкт-Петербург, Омск, Сочи, Пермь

280
php mysql перенос time() в timestamp

php mysql перенос time() в timestamp

здравствуйте, в бд использовал до этого момента time() для установления значения времени (к примеру дата добавление новости), возможно ли теперь...

236
Checkbox и sql?

Checkbox и sql?

Здравствуйте, не могу понять, при выставлении галочки, запись в бд не идетВот кусочек кода, если нужен полный, скину

204
получение данных по tcp PHP_BINARY_READ

получение данных по tcp PHP_BINARY_READ

Есть тестовый tcp-сервер

238