手把手教你實(shí)現(xiàn)拼圖互動(dòng)小游戲(純VUE版本)
深秋的某一天,在上班的地鐵上面刷著手機(jī),看到徐小夕的公眾號(hào)推送的一篇文章,介紹的是一個(gè)移動(dòng)端的拼圖小游戲.于是自己嘗試著識(shí)別二維碼完了下,感覺還挺有意思的.周末抽空研究了一下,看了下這個(gè)小游戲有哪些功能.問了下原作者,他用的是原生JS寫的一版.自己本身在學(xué)習(xí)使用VUE開發(fā)項(xiàng)目,于是便萌發(fā)了用VUE嘗試改版一下.正好可以學(xué)習(xí)學(xué)習(xí)一下.于是看了下游戲的大體效果,決定嘗試用VUE改寫一版玩一下,說干就干.也歡迎有興趣,有想法的小伙伴可以一起討論.
洗牌算法 CSS3動(dòng)畫切換(圖片切割樣式定位) 用FileReader API實(shí)現(xiàn)本地預(yù)覽文件 用Canvas生成海報(bào) webpack打包(不同難度等級(jí)切換樣式問題)
趣談前端公眾號(hào)里面的文章,教你用200行代碼寫一個(gè)愛豆拼拼樂H5小游戲(附源碼).這里我對(duì)這個(gè)游戲VUE實(shí)現(xiàn)了相關(guān)的功能.而且還增加了一些自己的想法.相鄰元素才可以挪動(dòng)和難度等級(jí)選擇,發(fā)版的是兩個(gè)不同的版本.當(dāng)然在實(shí)現(xiàn)的過程中也遇到了一些問題.不過經(jīng)過自己的折騰還是基本實(shí)現(xiàn)出來自己想要的效果啦.


//?生成n維矩陣
generateMatrix(n,?dx,?dy)?{
??var?arr?=?[],
????index?=?0;
??for?(var?i?=?0;?i?????for?(var?j?=?0;?j???????arr.push({?x:?j?*?dx,?y:?i?*?dy,?index:?index?});
??????index++;
????}
??}
??return?arr;
}
????upsetArr(arr)?{
??????return?arr.sort(function()?{
????????return?Math.random()?>?0.5???-1?:?1;
??????});
????}
???//?點(diǎn)擊高亮并且切換對(duì)應(yīng)位置?(想辦法交換對(duì)應(yīng)索引位置的x,y值即可)
????changePositon(e,?item)?{
??????//點(diǎn)擊小圖片切換位置方法
??????let?reg?=?/active/g;
??????this.boxArractivelass?=?item;
??????let?pieces?=?document.querySelectorAll(".piece");
??????if?(!this.wall)?{
????????this.wall?=?1;
????????this.prevEl?=?e.target;
????????for?(var?i?=?0,?len?=?pieces.length;?i???????????//?使用replace為了避免元素后期加入其他類名
??????????pieces[i].className?=?pieces[i].className.replace("?active",?"");
????????}
????????!reg.test(this.className)?&&?(this.className?+=?"?active");
??????}?else?{
????????this.wall?=?0;
????????var?prevIndex?=?+this.prevEl.getAttribute("index"),
??????????curIndex?=?+e.target.getAttribute("index");
????????//?置換數(shù)組
????????this.swap(this.pool,?prevIndex,?curIndex);
????????this.prevEl.style.transform?=
??????????"translate("?+
??????????this.pool[prevIndex].x?+
??????????"vw,"?+
??????????this.pool[prevIndex].y?+
??????????"vh"?+
??????????")";
????????e.target.style.transform?=
??????????"translate("?+
??????????this.pool[curIndex].x?+
??????????"vw,"?+
??????????this.pool[curIndex].y?+
??????????"vh"?+
??????????")";
????????//?清除樣式
????????this.boxArractivelass?=?-1;
????????//?校驗(yàn)是否成功
????????if?(this.isTestSuccess(this.pool))?{
????
??????????clearInterval(this.timer);
??????????this.startDx?-=?100;
??????????this.issuccess?=?true;
??????????this.transformX(this.$refs.wrap,?this.startDx?+?"vw");
???????
????????}
??????}
????}
????//?置換數(shù)組(對(duì)應(yīng)索引的x,y值進(jìn)行交換)
????swap(arr,?indexA,?indexB)?{
??????// ES6的解耦交換方式:?[arr[index], arr[n]]?=?[arr[n], arr[index]];
??????[arr[indexA],?arr[indexB]]?=?[arr[indexB],?arr[indexA]];
????},
????//對(duì)比數(shù)組中的每一個(gè)值是否與之前的值相等
????isTestSuccess(arr)?{
??????return?arr.every(function(item,?i)?{
????????return?item.index?===?i;
??????});
????}
在實(shí)現(xiàn)的過程中,遇到一個(gè)印象比較深的問題就是,當(dāng)在第一個(gè)頁(yè)面選擇簡(jiǎn)單等級(jí),然后點(diǎn)擊開始游戲,然后返回重新選擇中級(jí)等級(jí),由于樣式加載順序,導(dǎo)致頁(yè)面展示的還是之前簡(jiǎn)單等級(jí)的頁(yè)面樣式.
之前出現(xiàn)這種問題的原因是由于,我這邊是通過判斷選擇等級(jí),然后import引入不同的樣式文件導(dǎo)致的.
例如:實(shí)現(xiàn)的思路判斷:
if(this.gradeSelected==3)?{
????import('../assets/style/default.css');
}?else?if(this.gradeSelected===4){
????import('../assets/style/middle.css');
}?else?if(this.gradeSelected===5)?{
????import('../assets/style/senior.css');
}

????//?引入設(shè)置和獲取本地存儲(chǔ)的挑戰(zhàn)等級(jí)標(biāo)識(shí)
????import?localStorage?from?"./storage";?
????const?skin?=?{};
????let?getSkinStyle?=?(skin)?=>?{
????if?(!skin)?{
????????return?"";
????}
????if?(skin?===?'three')?{
????????return?`簡(jiǎn)單等級(jí)的樣式文件`
????}?else?if(skin==='four')?{
????????return?`中等等級(jí)的樣式文件`
????}?else?if(skin==='five')?{
????????return?`高級(jí)等級(jí)的樣式文件`
????}
????
????let?setSkinStyle?=?(skin)?=>?{
????let?styleText?=?getSkinStyle(skin);
????let?oldStyle?=?document.getElementById("skin");
????const?style?=?document.createElement("style");
????style.id?=?"skin";
????style.type?=?"text/css";
????style.innerHTML?=?styleText;
????oldStyle???document.head.replaceChild(style,?oldStyle)?:?document.head.appendChild(style);
};
//?設(shè)置不同等級(jí)圖片切割樣式
skin[localStorage.getSkin()]?&&?setSkinStyle(skin[localStorage.getSkin()]);
export?{?skin,?setSkinStyle?}
至此,現(xiàn)在不同等級(jí)的選擇切換,再也不會(huì)造成選擇等級(jí)與圖片分割界面樣式不符啦.也可以愉快的玩耍啦.
當(dāng)然代碼還是比較粗糙,也存在一些問題的.還有就是不同版本的手機(jī)也沒有經(jīng)過兼容性測(cè)試,代碼都在一個(gè)頁(yè)面,也沒有進(jìn)行合理的組件拆分等等.
以上游戲純屬娛樂,有興趣的小伙伴也歡迎交流,有什么問題也可以一起探討,源碼地址也放到了我的Github上面,歡迎大家一起交流探討,共同進(jìn)步.
Github項(xiàng)目地址:https://github.com/pybyongbo/vue-pinpngle
感興趣的可以點(diǎn)擊左下角原文鏈接體驗(yàn)試玩, 如果你想實(shí)現(xiàn)react版本的拼圖小游戲, 也可以和萬千網(wǎng)友一起分享推薦哈~
