[英]getting a “Cannot read property 'getFoodX' of undefined” error
因此,我正在尝试编写一个基本的 Snake 游戏并得到一个未定义的错误,尽管在查看它之后我没有发现我的代码有任何问题。 删除导致 getFood 错误的 if 条件时, this.apple.getFoodX
出现相同的错误。
class Game {
constructor(canvas, extent) {
this.canvas = canvas;
this.extent = extent;
this.cellSize = canvas.width / extent;
this.context = canvas.getContext('2d');
this.initGame();
this.gameOver = false;
setInterval(x => {
this.loop()
}, 350);
}
drawLine(x1, y1, x2, y2) {
this.context.beginPath();
this.context.moveTo(x1, y1);
this.context.lineTo(x2, y2);
this.context.stroke();
}
drawGrid() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
for (let i = 1; i <= this.extent; i++) {
this.drawLine(i * this.cellSize, 0, i * this.cellSize, this.canvas.height);
this.drawLine(0, i * this.cellSize, this.canvas.width, i * this.cellSize);
}
}
newApple() {
this.apple.create(this.extent);
}
getAppleX() {
return this.apple.getFoodX();
}
getAppleY() {
return this.apple.getFoodY();
}
getExtent() {
return this.extent;
}
genFood() {
this.apple.create(extent);
}
loop() {
if(this.gameOver === false) {
this.snake.update();
}
if(this.gameOver === false) {
this.drawGrid();
this.snake.draw();
this.apple.draw();
}
}
draw() {
this.drawGrid();
this.snake.draw();
this.apple.draw();
}
initGame() {
this.snake = new Snake([{x:7,y:8},{x:8,y:8},{x:9,y:8,}],this.cellSize, this.context, this.extent, 'ArrowRight');
this.apple = new Apple(5,10,this.cellSize,this.context);
}
gameEnds() {
this.gameOver = true;
}
}
class Apple{
constructor(x,y,cellSize,context) {
this.x = x;
this.y = y;
this.cellSize = cellSize;
this.context = context;
this.newApple = {x:0,y:0};
}
draw() {
this.context.fillStyle = 'green';
this.context.fillRect(this.x * this.cellSize, this.y * this.cellSize, this.cellSize, this.cellSize);
}
create(extent) {
this.newApple = {x: Math.floor(Math.random() * extent),y: Math.floor(Math.random() * extent)};
this.x = this.newApple.x;
this.y = this.newApple.y;
for(let i = 0; i < this.snake.snakeArray.length; i++) {
if (this.newApple.x == this.snake.snakeArray[i].x && this.newApple.y == this.snake.snakeArray[i].y) {
this.newApple = {x: Math.floor(Math.random() * extent),y: Math.floor(Math.random() * extent)};
this.x = this.newApple.x;
this.y = this.newApple.y;
}
}
}
getFoodX() {
return this.x;
}
getFoodY(){
return this.y;
}
}
class Snake {
constructor(snakeArray, cellSize,context,extent,pressedKey) {
this.cellSize = cellSize;
this.context = context;
this.extent = extent;
this.pressedKey = pressedKey;
this.snakeArray = snakeArray;
//this.snakeArray.push(startingPos);
this.snakeHead = {x: this.snakeArray[this.snakeArray.length-1].x, y:this.snakeArray[this.snakeArray.length-1].y};
document.addEventListener('keyup', event => {
this.handleKeyUp(event);
});
}
handleKeyUp(event) {
if (event.code === 'ArrowUp' || event.code === 'ArrowDown' || event.code === 'ArrowLeft' || event.code === 'ArrowRight') {
this.pressedKey = event.code;
}
}
update() {
let newSnakeHead = {x:0,y:0};
if (this.pressedKey === 'ArrowUp') {
newSnakeHead = {x: this.snakeHead.x, y: this.snakeHead.y-1};
} else if (this.pressedKey === 'ArrowRight') {
newSnakeHead = {x: this.snakeHead.x+1, y: this.snakeHead.y};
} else if (this.pressedKey === 'ArrowDown') {
newSnakeHead = {x: this.snakeHead.x, y: this.snakeHead.y+1};
} else if (this.pressedKey === 'ArrowLeft') {
newSnakeHead = {x: this.snakeHead.x-1, y: this.snakeHead.y};
}
if(newSnakeHead.x === this.game.getFoodX() && newSnakeHead.y === this.game.getFoodY()) {
this.snakeArray.push(newSnakeHead);
this.game.genFood();
}
else {
this.snakeArray.shift();
if(this.outOfBounds(newSnakeHead, this.extent) === true || this.snakeHit(newSnakeHead, this.extent) === true) {
this.game.gameEnds();
}
else{
this.snakeArray.push(newSnakeHead);
}
}
}
draw() {
for(let i = 0; i< this.snakeArray.length-1; i++) {
this.drawSquare(this.snakeArray[i].x, this.snakeArray[i].y, 'red');
}
this.drawSquare(this.snakeHead.x,this.snakeHead.y,'yellow');
}
outOfBounds(newSnakeHead,extent) {
if(newSnakeHead.x > extent || newSnakeHead.x < 0 || newSnakeHead.y > extent || newSnakeHead.y < 0 ) {
this.game.gameEnds();
return true;
}
}
snakeHit(newSnakeHead) {
for(let i = 0; i< this.snakeArray.length; i++) {
if (newSnakeHead.x == this.snakeArray[i].x && newSnakeHead.y == this.snakeArray[i].y) {
this.game.gameEnds();
return true;
}
}
}
drawSquare(x,y,color) {
this.context.fillStyle = color;
this.context.fillRect(x * this.cellSize, y * this.cellSize, this.cellSize, this.cellSize);
}
}
const canvas = document.getElementById('myCanvas');
const game = new Game(canvas, '16');
任何帮助表示赞赏!
您正在尝试使用this
游戏在 Snake class 中访问game
object,但它不是 Snake class 的一部分。 所以我认为,在Snake
class 中的update()
方法中,以下语句是罪魁祸首:-
if(newSnakeHead.x === this.game.getFoodX() && newSnakeHead.y === this.game.getFoodY()) {
this.snakeArray.push(newSnakeHead);
this.game.genFood();
}
您可以在 Snake 构造函数中创建对游戏的引用,例如:-
constructor(snakeArray, cellSize,context,extent,pressedKey,game) {
this.cellSize = cellSize;
this.context = context;
this.extent = extent;
this.pressedKey = pressedKey;
this.snakeArray = snakeArray;
this.game = game;
//this.snakeArray.push(startingPos);
this.snakeHead = {x: this.snakeArray[this.snakeArray.length-1].x, y:this.snakeArray[this.snakeArray.length-1].y};
document.addEventListener('keyup', event => {
this.handleKeyUp(event);
});
}
在你的游戏 class 中:-
initGame() {
this.snake = new Snake([{x:7,y:8},{x:8,y:8},{x:9,y:8,}],this.cellSize, this.context, this.extent, 'ArrowRight',this);
this.apple = new Apple(5,10,this.cellSize,this.context);
}
传递额外的this
参数。 这将帮助您在Snake
class 中设置对game
属性的正确引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.