我在阅读画布上的鼠标位置时遇到了麻烦。代码正常工作(半),因为它在IE中单击画布时读取位置,但只在一帧上,在chrome中,它只是将值显示为0。
以下是完整代码:
<script>
var blip = new Audio("blip.mp3");
blip.load();
var levelUp = new Audio("levelUp.mp3");
levelUp.load();
var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
context.font = '18pt Calibri';
context.fillStyle = 'white';
//load and draw background image
var bgReady = false;
var background = new Image();
background.src = 'images/background.jpg';
background.onload = function(){
bgReady = true;
}
var startMessage = 'Click the canvas to start';
//load plane image
var planeReady = false;
var planeImage = new Image();
planeImage.src = 'images/plane.png';
planeImage.onload = function() {
planeReady = true;
}
//load missile image
var missileReady = false;
var missileImage = new Image();
missileImage.src = 'images/missile-flipped.gif';
missileImage.onload = function() {
missileReady = true;
}
//initialise lives and score
var score = 0;
var lives = 3;
var missilesLaunched = 0;
var missileSpeed = 5;
var level = 1;
var missileX = 960;
var missileY = Math.random() * 500;
if (missileY > 480) {
missileY = 480;
}
function getMousePos(canvas, event) {
return {
x: input.x - rect.left,
y: input.y - rect.top
};
}
function update_images(event) {
var pos = getMousePos(canvas.getBoundingClientRect(), mouseInput);
planeImage.y = pos.y;
missileX = missileX - missileSpeed;
if (missileX < - 70) {
missilesLaunched++;
missileX = 960;
missileY = Math.random() * 500;
if (missileY > 480) {
missileY = 480;
}
blip.play();
score = missilesLaunched;
if (score % 5 == 0) {
missileSpeed = missileSpeed + 2;
level++;
levelUp.play();
}
}
}
function reload_images() {
if (bgReady = true) {
context.drawImage(background, 0, 0);
}
if (planeReady = true) {
context.drawImage(planeImage, 10, planeImage.y);
}
if (missileReady = true) {
context.drawImage(missileImage, missileX, missileY);
}
context.fillText('Lives: ' + lives, 200, 30);
context.fillText('Score: ' + score, 650, 30);
context.fillText('Level: ' + missileSpeed, 420, 30);
context.fillText('Position: ' + missileImage.y, 420, 70);
}
function main(event) {
var mouseInput = { x: 0, y: 0 };
document.addEventListener("mousemove", function (event) {
mouseInput.x = event.clientX;
mouseInput.y = event.clientY;
});
update_images(event);
reload_images();
if (lives > 0) {
window.requestAnimationFrame(main);
}
else {
}
}
function start() {
context.drawImage(background, 0, 0);
context.fillText('Click the canvas to start', 350, 250);
function startMain(event) {
game.removeEventListener("click", startMain);
main(event);
}
canvas.addEventListener("mousedown", startMain);
}
start();
</script>
答案 0 :(得分:2)
乔,你每次点击时都应该抓住鼠标位置......
...但是,每次点击时,你实际上也开始了新游戏(不停止旧游戏)。
第一个问题:多次启动游戏引擎以在同一个画布上绘制
解决方案:
在start
功能中,您需要在触发后删除mousedown
事件监听器。
function start () {
// ... other setup
function startMain (event) {
canvas.removeEventListener("click", startMain);
main(event);
}
canvas.addEventListener("click", startMain);
}
现在它只会在开始之前听取第一次点击,并且只会开始一次。
第二个问题:鼠标没有按预期更新
解决方案:这里有两个问题......
...首先,您在第一次通话时将event
传递给main
...
......之后,您将main
传递给requestAnimationFrame
。
requestAnimationFrame
不会使用某个事件调用它,它会在页面加载后以微秒数(或ms或其他单位为ms的小数精度)调用它。
所以你第一次得到main({ type: "mousedown", ... });
下次您获得main(4378.002358007);
因此,让我们重构上面的startMain
,以便main
永远不会收集一个事件。
function startMain ( ) {
canvas.removeEventListener("click", startMain);
requestAnimationFrame(main);
}
接下来的问题是,即使你只获得了一些事件,你也只能捕获一个点击事件(正如我们之前提到的那样,它会触发一个新的游戏逻辑副本)。
您的解决方案是将捕获鼠标事件的代码与读取鼠标位置的代码分开。
var mouseInput = { x: 0, y: 0 };
document.addEventListener("mousemove", function (event) {
mouseInput.x = event.clientX;
mouseInput.y = event.clientY;
});
function getMousePos (rect, input) {
return {
x : input.x - rect.left,
y : input.y - rect.top
};
}
// currently in updateImages (should not be there, but... a different story)
var pos = getMousePos(canvas.getBoundingClientRect(), mouseInput);
你也遇到了其他问题......
您现在正在呼叫getMousePos
并传入game
。我不知道你的JS中定义了game
的位置,所以你要么在其他地方{乞讨错误} {strong> 或者它&#39}。 ; s game
,您的应用就会在那里爆炸 。
你应该在你的控制台/开发工具打开时,以实际的方式构建它,并在每个部分清除错误。