Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么会出错?未捕获类型错误:无法读取属性';功能';未定义的`_Javascript - Fatal编程技术网

Javascript 为什么会出错?未捕获类型错误:无法读取属性';功能';未定义的`

Javascript 为什么会出错?未捕获类型错误:无法读取属性';功能';未定义的`,javascript,Javascript,这是我的密码 const canvas = document.getElementById('game'); const ctx = canvas.getContext("2d"); let gridSize = 20; class Snake { constructor(imageFile, x = Math.floor(Math.random() * gridSize), y = Math.floor(Math.random() * gridSize), directi

这是我的密码


const canvas = document.getElementById('game'); 
const ctx = canvas.getContext("2d"); 



let gridSize = 20;

class Snake {
    constructor(imageFile, x = Math.floor(Math.random() * gridSize), y = Math.floor(Math.random() * gridSize), direction = ["left", "up", "right", "down"][Math.floor(Math.random() * 4)], speed = 0, snakeSize = 3) {
        this.x = x;
        this.y = y;
        this.direction = direction;
        this.speed = speed;
        this.directions = {"left": {x: -1,y: 0}, "up": {x:0, y:-1}, "right": {x: 1, y:0}, "down": {x:0, y:1}}
        this.image = this.loadImage(imageFile)

        this.body = [];

        for (let index = 0; index < snakeSize; index++) {
            this.body.push({x: this.x - index * this.directions[direction].x, y: this.y - index * this.directions[direction].y})
        }
    }

    loadImage(imageFile) {
        const image = new Image();
        image.onload = function() {}
        image.src = imageFile;

        return image;
    }

    slither() {
        this.x += this.directions[this.direction].x
        this.y += this.directions[this.direction].y
        if (this.x < 0) {
            this.x = gridSize - 1;
        }
        if (this.x > gridSize - 1) {
            this.x = 0;
        }

        if (this.y < 0) {
            this.y = gridSize - 1;
        }
        if (this.y > gridSize - 1) {
            this.y = 0;
        }
        for (let i = this.body.length - 1; i > 0; i--) {
            this.body[i].x = this.body[i-1].x
            this.body[i].y = this.body[i-1].y
        }
        this.body[0].x = this.x
        this.body[0].y = this.y
    }

    grow() {
        this.x += this.directions[this.direction].x
        this.y += this.directions[this.direction].y
        this.body.unshift({x: this.x, y: this.y})
    }
}

class Game {
    constructor(player, snake, score = 0) {
        this.player = player;
        this.snake = snake
        this.score = score
    }

    draw() {
        this.snake.slither()


        //paint background
        ctx.fillStyle = "black";
        ctx.fillRect(0, 0, canvas.width, canvas.height); 

        this.snake.draw()
    }

    start() {
        let x = 8;
        let interval = setInterval(this.draw, 1000 / x);
    }

    gameOver() {
        console.log("Game Over")
    }

}

let mySnake = new Snake("snake-graphics.png")
let myGame  = new Game("Donnovan", mySnake,)


myGame.start()


const canvas=document.getElementById('game');
const ctx=canvas.getContext(“2d”);
设gridSize=20;
蛇类{
构造函数(imageFile,x=Math.floor(Math.random()*gridSize),y=Math.floor(Math.random()*gridSize),方向=[“左”、“上”、“右”、“下”][Math.floor(Math.random()*4)],速度=0,蛇形大小=3){
这个.x=x;
这个。y=y;
这个方向=方向;
速度=速度;
this.directions={“left”:{x:-1,y:0},“up”:{x:0,y:-1},“right”:{x:1,y:0},“down”:{x:0,y:1}
this.image=this.loadImage(imageFile)
this.body=[];
for(让index=0;indexgridSize-1){
这个.x=0;
}
如果(此.y<0){
y=gridSize-1;
}
if(this.y>gridSize-1){
这个。y=0;
}
for(设i=this.body.length-1;i>0;i--){
this.body[i].x=this.body[i-1].x
this.body[i].y=this.body[i-1].y
}
this.body[0].x=此.x
this.body[0].y=this.y
}
成长{
this.x+=this.directions[this.direction].x
this.y+=this.directions[this.direction].y
this.body.unshift({x:this.x,y:this.y})
}
}
班级游戏{
构造函数(玩家、蛇、分数=0){
this.player=player;
这条蛇
这个分数=分数
}
画(){
这个。蛇。滑梯()
//绘画背景
ctx.fillStyle=“黑色”;
ctx.fillRect(0,0,canvas.width,canvas.height);
this.snake.draw()
}
开始(){
设x=8;
设间隔=设置间隔(本图为1000/x);
}
gameOver(){
控制台日志(“游戏结束”)
}
}
让mySnake=newsnake(“Snake graphics.png”)
让我的游戏=新游戏(“Donnovan”,mySnake,)
myGame.start()
我想知道为什么在运行代码
myGame.start()
之后,我会出现以下错误
uncaughttypeerror:无法读取未定义的属性'slither'

在我看来,似乎存在一个将上下文转移到游戏功能的问题。要么就是这样,要么就是我没有正确使用javascript的面向对象方法


这里有什么问题?如何解析?

您需要
绑定
构造函数中的draw函数,以便它正确访问此变量。现在,
draw
函数在setInterval中被触发,这使得它的上下文是窗口而不是类

constructor(player, snake, score = 0) {
        this.player = player;
        this.snake = snake
        this.score = score
        this.draw = this.draw.bind(this);
}
draw() {
        this.snake.slither()


        //paint background
        ctx.fillStyle = "black";
        ctx.fillRect(0, 0, canvas.width, canvas.height); 

        this.snake.draw()
    }
还请注意,您正在尝试访问draw函数中未在snake类中定义的
this.snake.draw
。请在使用前定义它

未引发错误的示例代码段:
const canvas=document.getElementById('game');
const ctx=canvas.getContext(“2d”);
设gridSize=20;
蛇类{
构造函数(imageFile,x=Math.floor(Math.random()*gridSize),y=Math.floor(Math.random()*gridSize),方向=[“左”、“上”、“右”、“下”][Math.floor(Math.random()*4)],速度=0,蛇形大小=3){
这个.x=x;
这个。y=y;
这个方向=方向;
速度=速度;
this.directions={“left”:{x:-1,y:0},“up”:{x:0,y:-1},“right”:{x:1,y:0},“down”:{x:0,y:1}
this.image=this.loadImage(imageFile)
this.body=[];
for(让index=0;indexgridSize-1){
这个.x=0;
}
如果(此.y<0){
y=gridSize-1;
}
if(this.y>gridSize-1){
这个。y=0;
}
for(设i=this.body.length-1;i>0;i--){
this.body[i].x=this.body[i-1].x
this.body[i].y=this.body[i-1].y
}
this.body[0].x=此.x
this.body[0].y=this.y
}
成长{
this.x+=this.directions[this.direction].x
this.y+=this.directions[this.direction].y
this.body.unshift({x:this.x,y:this.y})
}
}
班级游戏{
构造函数(玩家、蛇、分数=0){
this.player=player;
这条蛇=蛇;
这个分数=分数;
this.draw=this.draw.bind(this);
}
画(){
这个。蛇。滑梯()
//绘画背景
ctx.fillStyle=“黑色”;
ctx.fillRect(0,0,canvas.width,canvas.height);
}
开始(){
设x=8;
设间隔=设置间隔(本图为1000/x);
}
gameOver(){
控制台日志(“游戏结束”)
}
}
让mySnake=newsnake(“Snake graphics.png”)
让我的游戏=新游戏(“Donnovan”,mySnake,)
myGame.start()

问题在于您的
游戏.start()
方法,该方法调用
setInterval(this.draw,1000/x)
。当
setInterval
调用<
start() {
    let x = 8;
    let interval = setInterval(this.draw.bind(this), 1000 / x);
}
draw() {
    this.snake.slither()

    //paint background
    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, canvas.width, canvas.height); 
}