2012-03-25 9 views
0

Я пытаюсь запустить следующий код, но получить ошибку в функции gameLoop, заявив: Ошибка выполнения JavaScript: Object не поддерживает свойство или метод 'update'.Объект не поддерживает метод

Я начинаю программист JavaScript. Можете ли вы определить, что не так с этим кодом?

function Core(context) { 
    this.context = context; 
    this.fps = 500; 
    this.sprite = new Sprite(); 
} 

Core.prototype.run = function() { 
    setInterval(this.gameLoop, this.fps); // <<<< PROBLEM 
} 

Core.prototype.gameLoop = function() { 
    this.update(); 
    this.draw(); 
} 

Core.prototype.update = function() { 
    this.sprite.x += 50; 
    this.sprite.y += 50; 
} 

Core.prototype.draw = function() { 
    this.context.clearRect(0, 0, 300, 300); 
    this.context.fillRect(this.sprite.x, this.sprite.y, 50, 50); 
    this.context.fillText('x: ' + this.sprite.x + ' y: ' + this.sprite.y, 10, 250); 
} 
+0

Исправлен код: http://pastebin.com/xuNTQSrP - '' this' в Core.prototype.gameLoop' не разрешило к. ожидаемый, из-за 'setInterval'. –

+0

@Milosz: Не нужно, важно только, чтобы они определялись, когда 'gameLoop' ** называется **, а не когда он определен. –

ответ

1

В JavaScript this определяется исключительно как называется функция, а не где и как это определено. Проблема в том, что setInterval не вызывает ваш код с правильным значением this. Чтобы исправить:

function Core(context) { 
    var self = this; 

    this.context = context; 
    this.fps = 500; 
    this.sprite = new Sprite(); 
    this.boundGameLoop = function() { 
     self.gameLoop(); 
    }; 
} 

Core.prototype.run = function() { 
    setInterval(this.boundGameLoop, this.fps); 
} 

На двигателях JavaScript, которые имеют функции ES5 (или если вы используете ES5 "подкладку"), вы можете изменить Core на:

function Core(context) { 
    this.context = context; 
    this.fps = 500; 
    this.sprite = new Sprite(); 
    this.boundGameLoop = this.gameLoop.bind(this); 
} 

Больше чтение:


Side Примечание: Ваш код зависит от ужаса, который Automatic Semicolon Insertion. (Все ваши функции присвоений   — Core.prototype.run = function() { ... }) нужно после запятой закрытия })

+0

Спасибо, это работает хорошо. – Aetherix

+1

И спасибо за внимание. Я действительно могу использовать их! :) – Aetherix

+0

@Aetherix: Рад, что помогло! –

0

Что вам нужно, это .bind.

setInterval(this.gameLoop.bind(this), this.fps) 
+0

Спасибо, это действительно работает. – Aetherix

+0

@Aetherix Рад помочь :) – xdazz

-1

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

Core.prototype.update = function() { 
    this.sprite.x += 50; 
    this.sprite.y += 50; 
} 

Core.prototype.gameLoop = function() { 
    this.update(); 
    this.draw(); 
} 
Смежные вопросы