使用 Vue3 + Vite + Canvas + Worker 实现简单版的 “雷霆战机”

这篇博客介绍了如何使用Vue3、Vite、Canvas和Worker技术实现一个简单的“雷霆战机”飞机小游戏。在开发过程中,作者遇到在Vue3 + Vite项目中创建Worker的错误,通过正确引用和使用浏览器的visibilitychange事件解决了问题,确保了游戏在窗口焦点变化时的正常运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今日份分享:飞机小游戏

使用 Vue3 + Vite + Canvas + Worker 实现简单版的 “雷霆战机”

先看看效果

在敲代码时遇到一些问题:

  1. 在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--------');
    }
    
  2. 在切换浏览器窗口后,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(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值