HTML5画布 - 键盘按键不响应
问题描述:
我试图在乒乓球游戏中实现按键输入。重点是上下方向键不起作用。我的浏览器控制台不显示任何错误消息。HTML5画布 - 键盘按键不响应
Here is my code, this is WIP some Objects are not implemented yet
var playerBat = {
x: null,
y: null,
width: 20,
height: 80,
UP_DOWN: false,
DOWN_DOWN: false,
update: function() {
// Keyboard inputs
window.addEventListener('keydown', onKeyDown, false);
window.addEventListener('keyup', onKeyUp, false);
var key = {
UP: 38,
DOWN: 40
};
function onKeyDown(e) {
if (e.keyCode == 38)
this.UP_DOWN = true;
else if (e.keyCode == 40)
this.DOWN_DOWN = true;
}
function onKeyUp(e) {
if (e.keyCode == 38)
this.UP_DOWN = false;
else if (e.keyCode == 40)
this.DOWN_DOWN = false;
}
this.y = Math.max(Math.min(this.y, Canvas_H - this.height), 0); // Collide world bounds
},
render: function() {
ctx.fillStyle = '#000';
ctx.fillRect(this.x, this.y, this.width, this.height);
if (this.UP_DOWN)
this.playerBat.y -= 5;
else if (this.DOWN_DOWN)
this.playerBat.y += 5;
}
};
答
事件被解雇,问题是,你将他们在每次更新。你想要做的是在addEvents之类的方法外部使用回调函数和addEventListener,这些方法在初始化时应该被称为ONCE。目前,大量的事件处理程序被触发杀死了页面。
function addEvents() {
window.addEventListener('keydown', onKeyDown, false);
window.addEventListener('keyup', onKeyUp, false);
var key = {
UP: 38,
DOWN: 40
};
function onKeyDown(e) {
if (e.keyCode == key.UP) {
playerPaddle.UP_DOWN = true;
}
if (e.keyCode == key.DOWN) {
playerPaddle.DOWN_DOWN = true;
}
}
function onKeyUp(e) {
if (e.keyCode == key.UP) {
playerPaddle.UP_DOWN = false;
}
if (e.keyCode == 40) {
playerPaddle.DOWN_DOWN = key.DOWN;
}
}
}
进一步审查后,还有一些其他问题。首先,实际更改桨的X和Y的逻辑应该在更新方法中(因为这通常用于更改对象属性),而渲染方法应该只使用对象的更新属性绘制形状和图像。
其次,您正尝试在render方法中访问this.playerBat.y,但是'this'实际上就是playerBat。因此,为了正确定位'y'属性,您需要编写this.y。
我还注意到你已经有了一个关键的地图,定义了UP和DOWN键码,但实际上并没有使用它,而是使用了数字。也许你打算做什么?
答
我重新实现您所提供的代码,并添加了init
功能playerBat
,重视对和keyup
事件的事件侦听器。我只是保留了相关的位和实现的对象作为函数,但这个概念仍然适用。
送入addEventListener
需要结合this
回调函数,否则回调(this.UP_DOWN
和this.DOWN_DOWN
)内的this
值将不相同,在封闭范围的this
值;你想要的一个价值。
<canvas id='canvas' style="background:#839496">Your browser doesn't support The HTML5 Canvas</canvas>
<script>
var canvas = document.getElementById('canvas');
canvas.width = window.innerWidth-20;
canvas.height = window.innerHeight-20;
var ctx = canvas.getContext('2d');
var Canvas_W = Math.floor(canvas.width);
var Canvas_H = Math.floor(canvas.height);
/*
* Define a Player object.
*/
function PlayerBat(){
this.x = null;
this.y = null;
this.width = 20;
this.height = Canvas_H/3;
this.UP_DOWN = false;
this.DOWN_DOWN = false;
this.init = function() {
console.log('init');
// MUST bind `this`!
window.addEventListener('keydown', function(e){
console.log('keydown');
if (e.keyCode == 38) this.UP_DOWN = true;
else if (e.keyCode == 40) this.DOWN_DOWN = true;
}.bind(this), false);
// MUST bind `this`!
window.addEventListener('keyup', function(e){
console.log('keyUp')
if (e.keyCode == 38) this.UP_DOWN = false;
else if (e.keyCode == 40) this.DOWN_DOWN = false;
}.bind(this), false);
};
this.update = function() {
var key = {UP: 38, DOWN: 40};
this.y = Math.max(Math.min(this.y, Canvas_H - this.height), 0);
};
this.render = function() {
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Redraw paddle
ctx.fillStyle = '#00F';
ctx.fillRect(this.x, this.y, this.width, this.height);
this.y = (this.UP_DOWN) ? this.y - 5 : ((this.DOWN_DOWN) ? this.y + 5 : this.y);
};
}
function GameRunner(){
// Create instance of player
var playerBat = new PlayerBat();
playerBat.init();
// Execute upon instantiation of GameRunner
(function() {
playerBat.x = playerBat.width;
playerBat.y = (Canvas_H - playerBat.height)/2;
})();
function step() {
playerBat.update();
playerBat.render();
requestAnimationFrame(step);
}
// Public method. Start animation loop
this.start = function(){
requestAnimationFrame(step);
}
}
// Create GameRunner instance
var game = new GameRunner();
// Start game
game.start();
</script>