我正在用JavaScript编写一个简单的游戏。我使用的单个JS文件变得一团糟。所以我将它重构为几个类。但是我遇到了一些问题,一些变量变成'空'。
在重绘函数中,“this.ctx”变量为null。我不明白为什么它是null ...在launchGame方法中它正确初始化。
var Game = {
username : "",
password : "",
state : "login",
interactables : [],
interactablesOffset : 0,
c : document.getElementById('gameCanvas'),
ctx : null,
usernameInput : "", passwordInput : "", loginBtn : "", loginBtnText : "Login",
//Initialises handlers and launches the game cycle
launchGame : function () {
//Initialize
this.c.addEventListener("click", this.handleClick, false);
this.ctx = this.c.getContext('2d');
setInterval(gameInstance.redraw, 300);
},
//Redraws the game every 300 ms
redraw: function () {
this.interactablesOffset = 0;
var user = this.usernameInput != null ? this.usernameInput.value() : "";
var pw = this.passwordInput != null ? this.passwordInput.value() : "";
**this.ctx.clearRect(0, 0, 800, 800);//this.ctx is null**
switch (state) {
case "login":
displayLoginMenu(user, pw);
break;
}
},
//Displays the login menu
displayLoginMenu : function (_username, _password) {
ctx.font = "bold 14px sans-serif";
ctx.fillText("Username:", 5, 70);
usernameInput = new CanvasInput({ canvas: document.getElementById('gameCanvas'), x: 100, y: 50, value: _username });
ctx.font = "bold 14px sans-serif";
ctx.fillText("Password:", 5, 120);
passwordInput = new CanvasInput({ canvas: document.getElementById('gameCanvas'), x: 100, y: 100, value: _password });
loginBtn = Object.create(BaseButton);
loginBtn.x = 100;
loginBtn.y = 150;
loginBtn.width = 162;
loginBtn.height = 25;
this.addIteractable(obj);
this.paintInteractables();
},
//Paints the interactables to the screen
paintInteractables : function () {
for(var i = 0; i < interactables.length; i++) {
var obj = interactables[i];
if(obj !=null)
obj.paint();
}
},
//Adds an interactable component to the screen
addIteractable : function addIteractable(obj) {
interactables[interactablesOffset] = obj;
interactablesOffset++;
},
//Handles clicks on game
handleClick : function (e) {
console.log('click: ' + e.offsetX + '/' + e.offsetY);
for (var i = 0; i < interactables.length; i++) {
var element = interactables[i];
if (e.offsetX >= element.x && e.offsetX <= element.x + element.w
&& e.offsetY >= element.y && e.offsetY <= element.y + element.h) {
console.log("clickBtn");
interactables[i].pressed();
}
}
}
}
var gameInstance = Object.create(Game);
gameInstance.launchGame();
答案 0 :(得分:2)
您在此代码中丢失了上下文:
setInterval(gameInstance.redraw, 300);
所以gameInstance.redraw
将在全局对象上下文(window
)中调用。这意味着它内部的this
将指向不是游戏实例而是指向窗口对象。
要解决此问题,您可以:
launchGame : function () {
//Initialize
this.c.addEventListener("click", this.handleClick, false);
this.ctx = this.c.getContext('2d');
var self = this;
setInterval(function() {
self.redraw();
}, 300);
},
或
setInterval(this.redraw.bind(this), 300);