<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
端午將至,大家都開始吃粽子了麼,你是喜歡吃北方的甜的紅棗粽?還是南方的大肉粽呢?
本期我們將使用vite2與vue3開發出一個招財貓小遊戲,通過考驗眼力和預判能力,在圖案不停捲動的同時選出可以轉出不同的素材最終得到粽子獎勵,康康你能用多少次才會轉出自己喜愛口味的粽子吧~
預覽地址:jsmask.gitee.io/dwgame_laohuji/
在開發之前,我們要想好遊戲設計和規則是如何,才能進行往下進行。通過上圖的演示和規則介紹,我們大致可以瞭解遊戲流程了。
然後,根據瞭解的流程,進行拆解,接下來我們主要會講解這些問題:
下圖是本期用的所有素材,招財貓招手的是由四張圖拼湊而成的,用了一些線上的雪碧圖生成工具。在裡面我們會得到每張圖對應的 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.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.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.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
方法時,我們獲取當繫結好條帶的元素塊,通過 animejs
給 backgroundPositionY
屬性設定一個陣列,這個陣列第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招財貓遊戲內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45