<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          手把手教你實(shí)現(xiàn)拼圖互動(dòng)小游戲(純VUE版本)

          共 1524字,需瀏覽 4分鐘

           ·

          2020-12-10 17:14

          深秋的某一天,在上班的地鐵上面刷著手機(jī),看到徐小夕的公眾號(hào)推送的一篇文章,介紹的是一個(gè)移動(dòng)端的拼圖小游戲.于是自己嘗試著識(shí)別二維碼完了下,感覺還挺有意思的.周末抽空研究了一下,看了下這個(gè)小游戲有哪些功能.問了下原作者,他用的是原生JS寫的一版.自己本身在學(xué)習(xí)使用VUE開發(fā)項(xiàng)目,于是便萌發(fā)了用VUE嘗試改版一下.正好可以學(xué)習(xí)學(xué)習(xí)一下.于是看了下游戲的大體效果,決定嘗試用VUE改寫一版玩一下,說干就干.也歡迎有興趣,有想法的小伙伴可以一起討論.

          下面列一下用到的一些知識(shí)點(diǎn):
          • 洗牌算法
          • CSS3動(dòng)畫切換(圖片切割樣式定位)
          • 用FileReader API實(shí)現(xiàn)本地預(yù)覽文件
          • 用Canvas生成海報(bào)
          • webpack打包(不同難度等級(jí)切換樣式問題)
          零零碎碎的花了2~3個(gè)周末的時(shí)間,然后部署了下頁(yè)面.雖然存在一些問題,代碼也比較粗糙.但是還是實(shí)現(xiàn)了自己想要的效果.
          大致的實(shí)現(xiàn)思路可以參考趣談前端公眾號(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)出來自己想要的效果啦.

          挑戰(zhàn)結(jié)果
          先來看看大致的實(shí)現(xiàn)功能模型:

          具體實(shí)現(xiàn):
          1.根據(jù)選擇的難度等級(jí)生成n*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;
          }

          2.數(shù)組亂序(重新排列)
          ????upsetArr(arr)?{
          ??????return?arr.sort(function()?{
          ????????return?Math.random()?>?0.5???-1?:?1;
          ??????});
          ????}
          3.點(diǎn)擊高亮并且切換對(duì)應(yīng)的位置(當(dāng)前點(diǎn)擊的和你要交換的)
          ???//?點(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");
          ???????
          ????????}
          ??????}
          ????}
          4.點(diǎn)擊交換圖片的位置
          ????//?置換數(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]];
          ????},
          5.檢驗(yàn)是否成功方法:
          ????//對(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');
          }
          打包樣式問題
          后來重新?lián)Q了一種思路,直接寫了一個(gè)方法,本地存儲(chǔ)選中的等級(jí),用來設(shè)置選中不同難度等級(jí)的樣式文件.然后動(dòng)態(tài)的插入到head標(biāo)簽中.
          ????//?引入設(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)友一起分享推薦哈~

          瀏覽 114
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  美日韩毛片 | 日韩人妻一区二区三区蜜桃视频 | 婷婷精品国产亚洲AV老牛 | 国模精品| 夜夜操夜夜撸 |