我的编程空间,编程开发者的网络收藏夹
学习永远不晚

基于vite2+vue3制作个招财猫游戏

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

基于vite2+vue3制作个招财猫游戏

介绍

端午将至,大家都开始吃粽子了么,你是喜欢吃北方的甜的红枣粽?还是南方的大肉粽呢?

本期我们将使用vite2与vue3开发出一个招财猫小游戏,通过考验眼力和预判能力,在图案不停滚动的同时选出可以转出不同的素材最终得到粽子奖励,康康你能用多少次才会转出自己喜爱口味的粽子吧~

演示

预览地址:jsmask.gitee.io/dwgame_laohuji/

正文

游戏分析

在开发之前,我们要想好游戏设计和规则是如何,才能进行往下进行。通过上图的演示和规则介绍,我们大致可以了解游戏流程了。

然后,根据了解的流程,进行拆解,接下来我们主要会讲解这些问题:

  • 招财猫css3帧动画。
  • 图案条带中的素材在vite2的批量加载。
  • 老虎机图案自定义条带生成。
  • 老虎机无限滚动。
  • 让老虎机停止并且获取抽奖码。
  • 获得粽子后的纸屑飞舞效果的实现。

招财动画

下图是本期用的所有素材,招财猫招手的是由四张图拼凑而成的,用了一些在线的雪碧图生成工具。在里面我们会得到每张图对应的 background-position , 最后再用 animation 来完成这个帧动画。其中,animation-timing-function:steps(1, end) 是帧动画实现的核心,steps() 函数符号定义了一个阶梯函数,将输出值的域划分为等距阶梯。第一个值是需要传入正数,表示等距的数,而后一个表示插值的位置。

.cat {
  width: 574px;
  height: 630px;
  margin: 0px auto;
  position: relative;
  background-image: url("../assets/image/cat.png");
  background-position: -10px -10px;
  &.active {
    animation: play-game 0.64s steps(1, end) infinite;
  }
  @keyframes play-game {
    0% {
      background-position: -10px -10px;
    }
    33% {
      background-position: -604px -10px;
    }
    66% {
      background-position: -1198px -10px;
    }
    100% {
      background-position: -10px -660px;
    }
  }
}

素材加载

我们后面需要通过canvas合成条带,所以要先加载出需要转出的图案来。

按照原始的方案来,我们要手写好多图片资源文件的引入,所以十分麻烦。

import item0 from "../assets/image/item_0.png"
import item1 from "../assets/image/item_1.png"
import item2 from "../assets/image/item_2.png"
// ...more
import item9 from "../assets/image/item_9.png"

但是,Vite 中提供了 import.meta.glob 的语法糖来解决这种批量导入的问题,一次性加载出这些图片文件来。

const imgs = import.meta.globEager("../assets/image/item_*.png");

let num = Object.keys(imgs).length;
let items = Object.values(imgs).map((mod) => {
  let img = new Image();
  img.onload = () => --num <= 0 && initGame();
  img.class="lazy" data-src = mod.default;
  return img;
});

当然我们这里用 import.meta.globEager 来可以同步加载这些资源。

条带生成

所谓的条带,就是老虎机中滚动的背景图,不停改变 backgroundPositionY 来实现滚动效果,是老虎机的核心,所使用到的条带自然就是重中之重,但在我们平时开发条带一般都是设计给的图片,但经常替换图片后又要重新问他们要新图甚是麻烦。所以,这里我想用 canvas 把刚才的那十张图案拼接起来,形成条带供我们使用。上一步,我们已经把资源加载完成了,接下来,可以需要写一个 createBackgroundImage 函数。

function createBackgroundImage({items = [], w = 45, h = 60, size = 40,test=false}) {
  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext("2d");
  canvas.width = ctx.width = w;
  canvas.height = ctx.height = h * items.length;
  let BackgroundImage = [...items];
  BackgroundImage.forEach((img, i) => {
    ctx.save();
    ctx.drawImage(img, (w - size) / 2, (h - size) / 2 + h * i, size, size);
    if(test){
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.font = "bold 36px Baloo Bhaijaan";
      ctx.fillText(i, w / 2, h * i + h / 2 + 5, w);
    }
    ctx.restore();
  });
  return convertCanvasToImage(canvas);
}

function convertCanvasToImage(canvas) {
  var image = new Image();
  image.class="lazy" data-src = canvas.toDataURL("image/png");
  return image;
}

export default createBackgroundImage;

这里我们不光可以传入资源数组,而且可以传入块的宽和高,还有图案的大小,为了方便测试后面验证开奖码的正确性,加入 test 字段,如果开启,则会绘制上对应的数字编号。

无限滚动

当我们点击开始游戏按钮后,刚才生成出的条带就会不停的改变 backgroundPositionY ,那有什么好办法可以轻松控制这件事呢?

这里我推荐使用anime.js ,它一个功能强大且轻量级的 JavaScript 动画库。

# NPM
npm i animejs -S
# YARN
yarn add animejs
# PNPM
pnpm i animejs -S
<ul class="content">
    <li
        ref="block"
        v-for="(item, index) in 3"
        :key="index"
        :style="{ backgroundImage: `url(${backgroundImage.class="lazy" data-src})` }"
        >
        <button :disabled="stops[index]" @click="handleStop(index)">
            Stop
        </button>
    </li>
</ul>
import anime from "animejs";
function play() {
  if (isActive.value) return false;
  isActive.value = true;
  count.value += 1;
  block.value.forEach((el, index) => {
    setTimeout(() => {
      stops.value[index] = false;
      let y = parseInt(el.style.backgroundPositionY || "0", 10);
      animes.value[index] = anime({
        targets: el,
        backgroundPositionY: [h / 2, h * items.length + h / 2],
        loop: true, // 循环播放
        direction: "normal", // 方向
        easing: "linear", // 时间曲线
        duration: 1200, // 播放时间
        autoplay: true, // 是否立即播放
      });
    }, index * 240);
  });
}

play 方法时,我们获取当绑定好条带的元素块,通过 animejsbackgroundPositionY 属性设置一个数组,这个数组第0位代表起始状态,第1位代表要到达的状态。然后把 loop 属性设置 true 。那么一个简单的条带无限滚动就完成了。

中奖判定

function handleStop(index) {
  stops.value[index] = true;
  let el = block.value[index];
  let y = parseInt(el.style.backgroundPositionY || "0", 10);
  animes.value[index].remove(el);
  let n = Math.round((y - h / 2) / h);
  el.style.backgroundPositionY = n * h + h / 2 + "px";
  giftCode.value[index] = (10 - n) % 10;
  if (stops.value.find((item) => !item) === undefined) {
    getResult();
  }
}

当我们每按停一个时,我们会迅速移除对应元素 animejs 动画,计算并赋值给最数值最接近的坐标点。然后获取到其对应的数字编号存起来形成抽奖码数组,当三个全部停止时,会调用 getResult 方法来根据刚才得到的抽奖码来开奖。

const giftData = [
    {
        name: "红枣粽",
        score: 100,
        show: true,
        type:1,
        value: ["012", "025", "126", "256"],
    },
    // ...
]
function getResult() {
  let str = giftCode.value.sort().join("");
  let _obj = giftData.find((item) => item.value.includes(str));
  if (!_obj) return (isActive.value = false);
  if (_obj.show) {
    giftObj.value = _obj;
    ruleShow.value = false;
    giftShow.value = true;
  } else {
    confetti();
    hideGift();
  }
}

这里,我们把得到的抽奖码进行从小往大排列生成字符串,然后在 giftData 数组中找寻配合的组合,达成后进行不同的奖励画面。

纸屑飞舞

这里我使用了 canvas-confetti,它是专门来制作纸屑飞散的动画库。其原理是在页面创建了canvas (也可以指定容器), 然后在里面绘制了几种形状可供选择,通过数学计算,模拟了很多物理运动来完成纸屑动画多彩的效果。

# NPM
npm i canvas-confetti -S
# YARN
yarn add canvas-confetti
# PNPM
pnpm i canvas-confetti -S
import confetti from "canvas-confetti";
function handleSucces() {
  let endTime = Date.now() + 3 * 1000;
  const colors = ["#bb0000", "#ffffff"];
  (function frame() {
    confetti({
      particleCount: 2,
      angle: 45,
      spread: 155,
      origin: { x: 0 },
      colors: colors,
    });
    confetti({
      particleCount: 2,
      angle: 135,
      spread: 60,
      origin: { x: 1 },
      colors: colors,
    });
    if (Date.now() < endTime) {
      requestAnimationFrame(frame);
    }
  })();
}

结语

现在已经把大家开发这类项目可能遭遇的问题或者方案大致给大家讲述完了。不知道,给你带来的帮助是多是少,也不知道大家点击了多少次才得到喜欢吃的粽子了,但不管是什么,开心快乐就好,最后祝大家端午安康,财运,福运多多,幸福满满。

到此这篇关于基于vite2+vue3制作个招财猫游戏的文章就介绍到这了,更多相关vite2 vue3招财猫游戏内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

基于vite2+vue3制作个招财猫游戏

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

基于JavaSwing制作一个Pong小游戏

《Pong》是美国雅达利公司(ATARI)开发的视频游戏,该作模拟了两个打乒乓球的人,就是在两条线中间有一个点在动,操纵器就是一个摇杆上有一个按钮的那种。本文就来用JavaSwing制作一个Pong小游戏吧
2023-01-05

如何基于Vue制作一个猜拳小游戏

Vue.js作为目前最热门最具前景的前端框架之一,其提供了一种帮助我们快速构建并开发前端项目的新的思维模式,下面这篇文章主要给大家介绍了关于如何基于Vue制作一个猜拳小游戏的相关资料,需要的朋友可以参考下
2023-01-05

基于C#制作一个飞机大战小游戏的全过程

飞机大战小游戏详细大家都不陌生,下面这篇文章主要给大家介绍了关于基于C#制作一个飞机大战小游戏的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2023-02-16

编程热搜

目录