关于vue3:Vue3-也能做游戏飞翔的思否猫挖坑警告

4次阅读

共计 3532 个字符,预计需要花费 9 分钟才能阅读完成。

大家晓得,作为一个开发者社区,10 月 24 日不搞点事件有点说不过去。于是思否经营同学找到我,邀请我出一篇文章,以思否猫为主题进行开发。我当即就许可了,写代码写文章嘛,小事一桩。

我不想走寻常路,看了思否猫的造型后,当即决定用 Web 技术做一个横版航行游戏。而且要用 OpenCV + 面部辨认来管制,还要用语音管制发炮。能够说,过后想的很好。然而,现实很饱满,事实很骨感,当初看着只写了一半的代码,悔不当初啊……

0. 技术预研

先说论断:

  • Web 语音辨认临时难堪大用
  • OpenCV 在现代化浏览器的性能足够

具体来说,我不太确定 Web 语音辨认(STT)的实现机制,比方:是本地集成模型,还是要发给服务器,辨认了再返回给客户端?实测的成果不太现实,响应速度太慢,兴许做个别的利用尚可,搞游戏就齐全不可行,从发声到失去后果至多须要 10s。不过兼容性还能够,Android、iOS、桌面都能用。

OpenCV 我找到了 这个我的项目,尽管没有文档,然而有 demo 页,成果不错,响应速度很快,基本上能够满足操控所需。

所以我决定:

  1. 如果工夫足够,那么我就用 Web Audio 中的音量 API 制作发炮性能。即只有声音够大就开炮,而不是最后构想的要念特定单词(我甚至 YY 念不同的单词发不同的炮)。
  2. OpenCV 肯定要用,不然不够酷。

能够说,我这会儿都还太过自信。

1. 其它技术选型

做游戏,有些同学可能会想到 Cocos、Unity 等技术,至多也要在 <canvas> 里画图。不过,对于一款简略的横版航行游戏,我感觉 DOM 就足够了。没有很简单的图层关系、没有很多元件须要做断定,固定思否猫在屏幕中线高低飞,撞到墙就失败,我甚至能够利用 InsersectionObserver 帮忙做碰撞检测。

于是我决定:

  1. 还是基于 Vue3 + Vite 来做,至多非游戏的交互局部(开始游戏、显示问题、显示处分等)就很简略
  2. 游戏内容用 DOM 来实现,根本 position: relative + absolute 就足够
  3. 碰撞检测用 IntersectionObserver 来实现

2. 创立 Vite 我的项目

谋定就能够开始动了。比拟意外的是,我厂最近忽然特地忙,加上国庆节亲戚来广州玩时攒了不少事件(“国庆后国庆后……”),所以空余工夫很少,始终拖到本周一才开始入手。

(嗯,先铺垫着,咱们来看代码。)

创立 Vite 我的项目很简略,咱们参考官网文档即可:

pnpm create vite sf-cat-flying --template vue

接着,装置我的罕用依赖,因为游戏比较简单,就不须要 vue-router 那些了:

pnpm i tailwindcss postcss autoprefixer daisyui -D

# 配置 tailwindcss
pnpx tailwindcess init -p

批改 tailwind.config.js,退出须要的配置:

module.exports = {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,vue,tsx}",
  ],
  theme: {extend: {},
  },
  plugins: [require('daisyui')],
}

批改 index.css,删掉 vue 模版里的款式,引入 tailwind:

@tailwind base;
@tailwind components;
@tailwind utilities;

好,根底脚手架就绪,接着能够开始写代码了。

3. 布局游戏舞台

间接上代码吧:

<div id="stage">
  <div class="stage-bg"></div>
  <video />
  <img class="sf-cat" src="sf-cat.png" />
</div>
// 起初指标是挪动端,所以启动时默认全宽全高
html, body, #app, #stage, .stage-bg
  height 100%

#stage
  width 100vw
  overflow: hidden

.stage-bg
  background url(bg.png) repeat-x
  background auto 100%
  width 1000vw
  position relative
  transition 30s linear

  &.play
    transform translateX(-900vw)

#sf-cat
  transition .5s ease-in-out
  position fixed
  left 50%
  top 50%
  width 4rem
  margin -2rem 0 0 -2rem

首先我安排了一个 <div id="stage"> 作为舞台,它的高宽就是咱们能看到的游戏区域。超出它的局部都要暗藏。

接下来,我拿一个 <div class="stage-bg"> 作为背景,它的宽度是 1000vw,10 倍于 stage,也就是总共能够滚动 9 屏。30s 意味着滚动 30s,linear 示意线性滚动,速度不变。

这里的 <video> 用来显示摄像头捕捉的视频流,不便用户操作思否猫,前面再细说。

思否猫就是个一般的 <img>,我应用 position: fixed 和定位属性让它固定在屏幕正中。为了实现加速度成果,我让它的动画成果是 ease-in-out,即启动和进行都有加速度。

4. 刷新柱子和碰撞检测

柱子的增加很简略,setInterval 之后插入一些节点,把柱子的背景图填入即可。难点在于碰撞检测。

传统形式咱们个别要计算两个物件之间的间隔,而后利用一些近似计算来模仿碰撞检测。然而在现代化浏览器里,咱们有 IntersectionObserver,它能够用来检测 DOM 节点的显示状态,返回的信息里甚至包含被遮挡的比例,目测非常适宜用来作碰撞检测。

这游戏里会呈现变动的状况只有两种:

  1. 被思否猫碰到
  2. 随着滚屏隐没在屏幕左侧

已知咱们会把思否猫固定在屏幕正中,所以依据以后滚屏的地位,能够很容易断定柱子是否是被撞到。于是就失去以下代码:

const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {const { target, isIntersecting, intersectionRatio} = entry;
      if (intersectionRatio < 0.9) {
        // 指标元素被遮挡超过 10% 就报告
        const event = new CustomEvent('hit', {
          bubbles: true, // 容许事件冒泡,就能够在父元素对立捕捉事件,节俭绑定的代码
          detail: {ratio: intersectionRatio,},
        });
        target.dispatchEvent(event);
      }
    });
  },
  {threshold: 0.05,}
);

function addPipe() {const pipe = document.createElement("div");
  pipe.className = ["pipe", 'pipe-' + position].join(' ');
  pipe.style.left = 150 + 30 * pipeCount + 'vw';
  stageBackground.value.appendChild(pipe);

  // 侦测显示状态
  observer.observe(pipe);
}

最初配合事件侦听器即可:

<div class="stage-bg" @hit="onHit">

5. 增加 OpenCV 管制思否猫

OpenCV 局部的代码是间接从他人的我的项目里抄来的,也就不具体解释了。简略说下流程吧:

  1. 应用 navigator.mediaDevices.getUserMedia({video: resolution, audio: false}) 申请应用用户的摄像头。用户许可之后,能够捕捉到视频流 stream
  2. 把视频流赋给 <video>,播放,让用户可能看到本人
  3. 创立一个 <canvas>,用来从 <video> 捕捉画面
  4. 将画面信息交给 opencv 进行辨认,如果找到脸孔,则传回脸孔两头的地位,作为思否猫的指标高度

具体代码能够浏览:https://github.com/meathill/s…

6. 提前总结

装不上来了,开始摆烂 😭😭。以上,就是我目前实现的局部代码。咳咳,十分羞愧,我没能把整个游戏做到能玩。

首先这个游戏的开发工作量比我设想的要大;其次我这周比设想中要忙。最初游戏并没有实现,我只是把次要门槛都迈过去了。

我把代码放在 GitHub 上,感兴趣的同学能够看看:翱翔的思否猫 GitHub 仓库,欢送大家奉献代码。我也会抽时间(下周当前吧),持续把它实现,所以一样欢送关注。

打包后的代码放在 我的服务器上,目前能够在桌面浏览器开启响应式后尝试。(你看这条件……


7.(未完待续)


本文参加了 1024 程序员节,欢送正在浏览的你也退出。

正文完
 0