今日份分享:飞机小游戏
使用 Vue3 + Vite + Canvas + Worker 实现简单版的 “雷霆战机”
先看看效果
在敲代码时遇到一些问题:
-
在vue3+vite的项目中直接用 const worker = new Worker(‘./worker.js’);的写法会报错,也不用去配置什么,vite已经给我们配置好了
正确用法:
@/workers/worker.js
addEventListener('message', e=>{ const { data} = e; console.log(data); setTimeout(()=>{ return postMessage('线程完成') }) }) export default { }
在 .vue文件里使用
import Worker from "@/workers/worker.js?worker"; let worker = new Worker(); worker.postMessage({ msg: 'start'}); worker.onmessage = (e)=>{ console.log(e, 'onmessage--------'); }
-
在切换浏览器窗口后,setInterval 定时器会发生异常
解决方案:
A.使用window.onblur和window.onfocus来解决
代码如下:
window.addEventListener('blur', ()=>{ ... }) window.addEventListener('focus', ()=>{ ... })
B.使用浏览器页面可见性 API visibilitychange事件解决 (推荐)
当浏览器最小化窗口或切换到另一个选项卡时就会触发visibilitychange事件,我们可以在事件中用Document.hidden或者Document.visibilityState判断当前窗口的状态,来决定除定时器后者重新开始定时器
代码如下
document.addEventListener('visibilitychange', () => { if (document.hidden === true) { ... } else { ... } })
代码:
bullet.js
// 子弹
function Bullet({
canvas, image, width=20, height= 20 }) {
canvas.style.cssText = `
background-color: none;
`
this.ctx = canvas.getContext('2d');
// 子弹的大小
this.width = width;
this.height = height;
// 画布的大小
this.CanvasWidth = canvas.width;
this.CanvasHeight = canvas.height;
// 子弹运行速度
this.speed = 5;
this.move = 0;
// 是否存在
this.show = true;
this.image = image;
// 子弹坐标
this.x = 0;
this.y = 0;
this.stop = false;
// 坐标记录 用于暂停游戏
this.points = null;
}
Bullet.prototype = {
draw(startPoint) {
this.points = startPoint;
if(this.stop){
return
}
let {
ctx, width, height, image } = this;
// 清除子弹上一个位置
ctx.clearRect(
startPoint.x - this.width/2,
startPoint.y - this.height/2 - this.move,
width,
height
);
if(!this.show){
return
}
if (startPoint.y - 16 - this.move > -this.height) {
this.move += this.speed;
this.x = startPoint.x - this.width/2;
this.y = startPoint.y - this.height/2 - this.move;
} else {
this.show = false;
return
}
ctx.drawImage(image, this.x, this.y, width, height);
requestAnimationFrame(() => {
setTimeout(()=>{
this.isHit();
this.draw(startPoint);
},10)
})
},
isHit(