欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3版本網(wǎng)頁小游戲設(shè)計(jì)思路

 更新時(shí)間:2022年12月19日 09:56:46   作者:KinHKin(五年前端)  
最近火爆全網(wǎng)的羊了個(gè)羊小程序,背景是根據(jù)官方介紹,“羊了個(gè)羊”是一款闖關(guān)消除小游戲,通關(guān)率不到0.1%。主要玩法為重疊的各類方塊,需要在下方7個(gè)欄內(nèi)完成消除,其特點(diǎn)就是“極難”,也因此成為熱門挑戰(zhàn),對(duì)vue3版本網(wǎng)頁小游戲設(shè)計(jì)思路感興趣的朋友跟隨小編一起看看吧

1.前言

最近火爆全網(wǎng)的羊了個(gè)羊小程序,背景是根據(jù)官方介紹,“羊了個(gè)羊”是一款闖關(guān)消除小游戲,通關(guān)率不到0.1%。主要玩法為重疊的各類方塊,需要在下方7個(gè)欄內(nèi)完成消除(3個(gè)同類消除),其特點(diǎn)就是“極難”,也因此成為熱門挑戰(zhàn)。我也頗感興趣,去玩了2把,的確很有樂趣,整理了一下思路,決定搞個(gè)vue3版本的網(wǎng)頁版本,我看網(wǎng)上有react版本的了,vue3版本還沒有,下面分別給出設(shè)計(jì)思路,實(shí)現(xiàn)方式,和玩法

設(shè)計(jì)思路:

1,先來一張背景圖,網(wǎng)上搜一張草地圖片

2,最底部設(shè)置七個(gè)槽位,有三個(gè)連續(xù)相同的就消除,槽位滿了的話,挑戰(zhàn)失敗

3,中間的圖層區(qū)域使用重疊的方式,可能是半重疊,可能是全重疊,只有第一層可以移入槽位,全部消除時(shí),表示挑戰(zhàn)成功!后續(xù)挑戰(zhàn)是變化關(guān)卡的布局方式(多種排列方式)

4,點(diǎn)擊事件的思路(內(nèi)層不能點(diǎn)擊,前置點(diǎn)擊如果槽位滿了還沒有消除完,關(guān)卡的消除,消除動(dòng)作 和 添加爆炸效果,進(jìn)入下一關(guān),挑戰(zhàn)失?。?/p>

5,輔助類函數(shù):判斷是否過關(guān),消除函數(shù),實(shí)現(xiàn)爆炸??效果,控制關(guān)卡

實(shí)現(xiàn)方式:

vue3配合pinia實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)頁面

玩法:

使用關(guān)卡模式,從第1關(guān)簡(jiǎn)單到2困難,3關(guān)復(fù)雜,這里的關(guān)卡只是數(shù)據(jù)的多少變化而已,可以設(shè)計(jì)出無數(shù)關(guān)卡,這里前端模擬json數(shù)據(jù),使用對(duì)象json

效果演示:

在線體驗(yàn) :

KinHKin https://rondsjinhuajin.github.io/DemoVue/#/

源碼地址:

github歡迎follow和star,感謝可愛的各位看官大佬~??

2.實(shí)現(xiàn)過程

2.1目錄

2.2文件介紹

 入口文件index.vue,設(shè)計(jì)背景色

<script setup lang='ts'>
import Header from "./components/Header.vue";
import Main from "./components/Main.vue";
</script>
 
<template>
  <div class="sheep-wrap">
    <div class="sheep">
 
      <div class="sheep-wrap">
        <div class="sheep">
          <Header />
          <Main />
        </div>
      </div>
    </div>
  </div>
 
</template>
<style scoped lang='less'>
.sheep-wrap {
  .sheep {
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 100%;
    padding-bottom: 20px;
  }
  
  width: 100%;
  height: calc(100vh - 60px);
  background: url("../../assets/images/sheep.png") center no-repeat;
  background-size: cover;
}
</style>

Header.vue文件,文字動(dòng)效,配合pinia顯示第幾關(guān)

<script lang='ts' setup>
import { useSheepStore } from "@/stores/sheep";
const store = useSheepStore();
</script>
 
<template>
  <div class="sheep-header">
    <div>第{{ store.step + 1 }}關(guān)</div>
    <div>
      <span class="l">羊了個(gè)羊??vue3版本</span
      ><span
        style="font-size: 14px;font-family: 'Times New Roman', Times, serif';"
        >(KinHKin)</span
      >
    </div>
  </div>
</template>
<style scoped lang="less">
.flex-center {
  display: flex;
  align-items: center;
}
.sheep-header {
  padding-top: 2rem;
  text-align: center;
  letter-spacing: 0.2rem;
  font-size: 1.5rem;
  color: #fff;
  border-bottom: 1px solid #1d9614;
  padding-bottom: 1rem;
  margin-bottom: 2rem;
  div .l {
    background-image: -webkit-linear-gradient(
      left,
      #1d9614,
      #fff 25%,
      #666 50%,
      #e6d205 75%,
      #fff
    );
    -webkit-text-fill-color: transparent;
    -webkit-background-clip: text;
    -webkit-background-size: 200% 100%;
    -webkit-animation: maskedAnimation 4s infinite linear;
    padding-right: 8px;
  }
}
@keyframes maskedAnimation {
  0% {
    background-position: 0 0;
  }
 
  100% {
    background-position: -100% 0;
  }
}
</style>

Main.vue文件是核心文件,作用是引入顏色,控制關(guān)卡,設(shè)置關(guān)卡數(shù)據(jù),如何消除,增加爆炸動(dòng)效,控制交互邏輯等。

<script setup lang="ts">
import { ref, type Ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { useSheepStore } from "@/stores/sheep";
// 關(guān)卡數(shù)據(jù)
import data from "./data.json";
// 顏色
import constants from "./constants";
// pinia 控制關(guān)卡
const store = useSheepStore();
// 七個(gè)槽位
// const footerList = ref([0, 1, 2, 3, 4, 5, 6]);
const footerList: Ref<Array<any> | [any]> = ref([]);
 
const colors = ref(constants.colors);
 
// 關(guān)卡響應(yīng)式
const totalList: Ref<Array<any> | [any]> = ref([]);
totalList.value = data["list1"]; // 默認(rèn)第一關(guān)
 
// 控制動(dòng)畫效果結(jié)束才能點(diǎn)擊
const isNotClick = ref(false);
 
// 點(diǎn)擊控制事件
function handleClick(
  i: number,
  k: number,
  onei: { oneSub: string | Array<string> },
  onek: number,
  oneiSub: Array<number>,
  onekSub: number
) {
  console.log(i, k, onei, onek, oneiSub, onekSub, "測(cè)試");
  if (isNotClick.value) {
    return false;
  }
  // 內(nèi)層不能點(diǎn)擊
  if (onekSub !== onei.oneSub.length - 1) {
    return false;
  }
 
  // 前置點(diǎn)擊如果槽位滿了還沒有消除完
  fullFun()
 
  // 關(guān)卡的消除
  let tempList = fixFun(k, onekSub, onek, oneiSub)
 
  // 消除動(dòng)作 和 添加爆炸效果
  if (footerList.value.length > 2) {
    isNotClick.value = true
    const { list, flag } = eliminationFunction(footerList.value)
    footerList.value = list;
    if (flag) {
      footerList.value = addBoomFunction(footerList.value);
    }
    setTimeout(() => {
      const { list, flag } = eliminationFunction(footerList.value)
      footerList.value = list;
      isNotClick.value = false
    }, 1000);
 
    // 進(jìn)入下一關(guān)
    nextFun(tempList)
  }
  // 挑戰(zhàn)失敗
  failFun(tempList)
 
  console.log(footerList, tempList, "tempList");
}
// full
function fullFun() {
  if (footerList.value.length === 7) {
    ElMessage.closeAll();
 
    ElMessageBox.alert("挑戰(zhàn)失敗,點(diǎn)擊確定返回!", "Warning", {
      confirmButtonText: "確定",
      type: "warning",
      showClose: false,
    }).then(() => {
      location.reload();
    });
    return false;
  }
}
// fix
function fixFun(k: number, onekSub: number, onek: number, oneiSub: Array<number>) {
  const { value } = totalList;
 
  let tempList = JSON.parse(JSON.stringify(value));
 
  for (let i = 0; i < tempList.length; i++) {
    const one = tempList[k].one;
    for (let j = 0; j < one.length; j++) {
      const oneSub = one[onek];
      for (let k = 0; k < oneSub.oneSub.length; k++) {
        if (onekSub === k) {
          const footItem = oneSub.oneSub.splice(onekSub);
          break;
        }
      }
    }
  }
  footerList.value.push(oneiSub);
  totalList.value = tempList;
  return tempList
}
//fail
function failFun(tempList: any[]) {
  setTimeout(() => {
    if (footerList.value.length > 0 && !jugeList(tempList)) {
      ElMessage.closeAll();
 
      ElMessageBox.alert("挑戰(zhàn)失敗,點(diǎn)擊確定返回!", "Warning", {
        confirmButtonText: "確定",
        type: "warning",
        showClose: false,
      }).then(() => {
        location.reload();
      });
      return false;
    }
  }, 1002)
}
// next
function nextFun(tempList: any[]) {
  setTimeout(() => {
    if (!footerList.value.length && !jugeList(tempList)) {
      // debugger
      ElMessage.closeAll();
      ElMessage.success("恭喜您,挑戰(zhàn)成功!進(jìn)入下一關(guān)");
      store.step++;
      const inStep: string = "list" + (store.step + 1);
      totalList.value = JSON.parse(JSON.stringify(data))[inStep];
      footerList.value = [];
    }
  }, 1001)
}
// 判斷是否過關(guān)
function jugeList(list: any[]) {
  let temp: any = [];
  list?.forEach((oeni: { one: any }) => {
    oeni?.one?.forEach((sub: { oneSub: any }) => {
      temp = [...temp, ...sub.oneSub];
    });
  });
  return temp.length;
}
 
// 消除函數(shù)
function eliminationFunction(list: any[]) {
  let flag: boolean = false;
  for (let k = 0; k < list.length - 2; k++) {
    const temp = list;
    const arr = temp.slice(k, k + 3);
    console.log(k, arr);
    if (arr[0] === arr[1] && arr[1] === arr[2] && arr[0] === arr[2]) {
      list.splice(k + 2);
      list.splice(k + 1);
      list.splice(k, 1);
      flag = true
      break;
    }
  }
 
  return { list, flag };
}
 
// 實(shí)現(xiàn)爆炸??效果
function addBoomFunction(list: any[]) {
  const temp = JSON.parse(JSON.stringify([...list, ...['boom', 'boom', 'boom']]))
  return temp;
}
</script>
 
<template>
  <div class="sheep-main">
    <div class="sheep-main-wrap">
      <template v-for="(i, k) in totalList" :key="'i' + k">
        <el-row v-if="i.one">
          <el-col :span="8" v-for="(onei, onek) in i.one" :key="'i' + onek">
            <div class="pic-list">
              <div class="pic-list-item" v-for="(oneiSub, onekSub) in onei.oneSub"
                :style="!onei.full ? `--i:${onekSub}` : `--i:0`"
                :class="onei.full && onei.oneSub.length > 1 ? 'true' : ''" :key="'i' + onekSub"
                @click="handleClick(i, k, onei, onek, oneiSub, onekSub)">
                <el-icon class="fz" v-if="oneiSub === 0">
                  <StarFilled :color="colors[0]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 1">
                  <Aim :color="colors[1]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 2">
                  <Grid :color="colors[2]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 3">
                  <HelpFilled :color="colors[3]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 4">
                  <Star :color="colors[4]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 5">
                  <Menu :color="colors[5]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 6">
                  <Camera :color="colors[6]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 7">
                  <Bicycle :color="colors[7]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 8">
                  <IceTea :color="colors[8]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 9">
                  <ColdDrink :color="colors[9]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 10">
                  <CoffeeCup :color="colors[10]" />
                </el-icon>
              </div>
            </div>
          </el-col>
        </el-row>
      </template>
    </div>
 
    <div class="sheep-footer flex-center">
      <div v-for="(ii, k) in footerList" :key="'ii' + k" class="sheep-footer-items">
        <el-icon class="fz" v-if="ii === 0">
          <StarFilled :color="colors[0]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 1">
          <Aim :color="colors[1]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 2">
          <Grid :color="colors[2]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 3">
          <HelpFilled :color="colors[3]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 4">
          <Star :color="colors[4]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 5">
          <Menu :color="colors[5]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 6">
          <Camera :color="colors[6]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 7">
          <Bicycle :color="colors[7]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 8">
          <IceTea :color="colors[8]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 9">
          <ColdDrink :color="colors[9]" />
        </el-icon>
        <el-icon class="fz" v-if="ii === 10">
          <CoffeeCup :color="colors[10]" />
        </el-icon>
        <div class="boom-class" v-if="ii === 'boom'">??</div>
      </div>
    </div>
  </div>
</template>
<style scoped lang="less">
.flex-center {
  display: flex;
  align-items: center;
}
 
.el-row {
  // margin-top: 3rem;
  height: 28%;
}
 
.fz {
  font-size: 3rem;
  border: 1px solid #dfe5f9;
  // box-shadow: 2px 2px 10px #f3f6fe;
 
  background: #f3f6fe;
  border-radius: 5px;
}
 
.pic-list {
  position: relative;
  width: 100%;
  height: 100%;
 
  &-item {
    position: absolute;
    left: 10vw;
    cursor: pointer;
    transition: all 0.3s;
 
    &:nth-child(1n) {
      top: calc(var(--i) * 1.5rem);
    }
 
    &.true {
      box-shadow: 0 -55px 0 0 #dfe5f9 inset;
    }
 
    // &:nth-child(even) {
    //   top: 2rem;
    // }
  }
}
 
.sheep-main {
  flex: 1;
 
  &-wrap {
    height: calc(100% - 80px);
  }
}
 
.sheep-footer {
  height: 80px;
  width: 100%;
  // border: 2px solid #298df9;
  border: 2px solid #778899;
  background: #010206;
 
  .sheep-footer-items {
    height: 80px;
    width: calc(100% / 7);
    margin-left: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
 
    .boom-class {
      font-size: 3rem;
      animation: myMove 3s ease-in-out infinite;
    }
 
    @keyframes myMove {
      0% {
        opacity: 1;
      }
 
      100% {
        opacity: 0;
      }
    }
 
    // border-right: 1px solid #dfe5f9;
  }
}
</style>

3.核心邏輯分步驟詳解

import { ref, type Ref } from "vue";

import { ElMessage, ElMessageBox } from "element-plus";

import { useSheepStore } from "@/stores/sheep";

// 關(guān)卡數(shù)據(jù)

import data from "./data.json";

// 顏色

import constants from "./constants";

// pinia 控制關(guān)卡

const store = useSheepStore();

首先引入data.json數(shù)據(jù)是渲染中間的頁面內(nèi)容,即是:

中間的就叫卡片區(qū)域吧,卡片分為半個(gè)遮擋和整個(gè)遮擋,在data數(shù)據(jù)里面配置:

"full": true

 默認(rèn)是半個(gè)遮擋,配置了"full": true就表示這塊的卡片是全遮擋的效果:

:style="!onei.full ? `--i:${onekSub}` : `--i:0`"

:class="onei.full && onei.oneSub.length > 1 ? 'true' : ''" :key="'i' + onekSub"

css: 使用了var的變量形式,來控制是否需要top下移,&.true來控制是否有下一級(jí)的卡片的樣式

&:nth-child(1n) {
top: calc(var(--i) * 1.5rem);

}
&.true {
????????box-shadow: 0 -55px 0 0 #dfe5f9 inset;

}

data.json里面的數(shù)據(jù)oneSub的選值范圍是:0-10

這和dom渲染層的息息相關(guān):卡片使用的是簡(jiǎn)單的icon也可以是其他類型的元素,你覺得好看即可。

                <el-icon class="fz" v-if="oneiSub === 0">
                  <StarFilled :color="colors[0]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 1">
                  <Aim :color="colors[1]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 2">
                  <Grid :color="colors[2]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 3">
                  <HelpFilled :color="colors[3]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 4">
                  <Star :color="colors[4]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 5">
                  <Menu :color="colors[5]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 6">
                  <Camera :color="colors[6]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 7">
                  <Bicycle :color="colors[7]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 8">
                  <IceTea :color="colors[8]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 9">
                  <ColdDrink :color="colors[9]" />
                </el-icon>
                <el-icon class="fz" v-if="oneiSub === 10">
                  <CoffeeCup :color="colors[10]" />
                </el-icon>

這里只提供11中卡片的效果,可以擴(kuò)展添加,需要修改代碼。

接下來是:

// 七個(gè)槽位

// const footerList = ref([0, 1, 2, 3, 4, 5, 6]);

const footerList: Ref<Array<any> | [any]> = ref([]);
const colors = ref(constants.colors);
// 關(guān)卡響應(yīng)式

const totalList: Ref<Array<any> | [any]> = ref([]);

totalList.value = data["list1"]; // 默認(rèn)第一關(guān)
// 控制動(dòng)畫效果結(jié)束才能點(diǎn)擊

const isNotClick = ref(false);

7個(gè)槽位在底部需要變化展示,做成響應(yīng)式。totalList是動(dòng)態(tài)變化的卡片數(shù)據(jù)集。totalList.value = data["list1"] ,默認(rèn)第一關(guān)。爆炸??的電話效果有延遲,需要控制在結(jié)束之后才能進(jìn)行卡片的點(diǎn)擊。

然后就是核心的卡片點(diǎn)擊事件,需要做哪些邏輯控制呢?先看源代碼,已經(jīng)提前做了備注:

// 點(diǎn)擊控制事件
function handleClick(
  i: number,
  k: number,
  onei: { oneSub: string | Array<string> },
  onek: number,
  oneiSub: Array<number>,
  onekSub: number
) {
  console.log(i, k, onei, onek, oneiSub, onekSub, "測(cè)試");
  if (isNotClick.value) {
    return false;
  }
  // 內(nèi)層不能點(diǎn)擊
  if (onekSub !== onei.oneSub.length - 1) {
    return false;
  }
 
  // 前置點(diǎn)擊如果槽位滿了還沒有消除完
  fullFun()
 
  // 關(guān)卡的消除
  let tempList = fixFun(k, onekSub, onek, oneiSub)
 
  // 消除動(dòng)作 和 添加爆炸效果
  if (footerList.value.length > 2) {
    isNotClick.value = true
    const { list, flag } = eliminationFunction(footerList.value)
    footerList.value = list;
    if (flag) {
      footerList.value = addBoomFunction(footerList.value);
    }
    setTimeout(() => {
      const { list, flag } = eliminationFunction(footerList.value)
      footerList.value = list;
      isNotClick.value = false
    }, 1000);
 
    // 進(jìn)入下一關(guān)
    nextFun(tempList)
  }
  // 挑戰(zhàn)失敗
  failFun(tempList)
 
  console.log(footerList, tempList, "tempList");
}

首先是函數(shù)的簽名,接受最上層級(jí)的i對(duì)象,k索引,然后是中層的onei對(duì)象,onek索引,最后是父級(jí)的oneiSub對(duì)象,onekSub索引。判斷條件需要前置,判斷能否點(diǎn)擊isNotClick,內(nèi)層不能點(diǎn)擊

if (isNotClick.value) {

        return false;

}

// 前置點(diǎn)擊如果槽位滿了還沒有消除完

fullFun()函數(shù)判斷如果槽位滿了還沒有消除完,就是挑戰(zhàn)失敗

function fullFun() {
  if (footerList.value.length === 7) {
    ElMessage.closeAll();
 
    ElMessageBox.alert("挑戰(zhàn)失敗,點(diǎn)擊確定返回!", "Warning", {
      confirmButtonText: "確定",
      type: "warning",
      showClose: false,
    }).then(() => {
      location.reload();
    });
    return false;
  }
}

如何添加爆炸??效果:

思路是在三個(gè)相同消除之后添加,添加在totalList數(shù)據(jù)之中 ,效果展示完成之后立即進(jìn)行totalList數(shù)據(jù)重置操作。

 
  // 關(guān)卡的消除
  let tempList = fixFun(k, onekSub, onek, oneiSub)
 
  // 消除動(dòng)作 和 添加爆炸效果
  if (footerList.value.length > 2) {
    isNotClick.value = true
    const { list, flag } = eliminationFunction(footerList.value)
    footerList.value = list;
    if (flag) {
      footerList.value = addBoomFunction(footerList.value);
    }
    setTimeout(() => {
      const { list, flag } = eliminationFunction(footerList.value)
      footerList.value = list;
      isNotClick.value = false
    }, 1000);
 
    // 進(jìn)入下一關(guān)
    nextFun(tempList)
  }

css 添加的方法:

    .boom-class {
      font-size: 3rem;
      animation: myMove 3s ease-in-out infinite;
    }
 
    @keyframes myMove {
      0% {
        opacity: 1;
      }
 
      100% {
        opacity: 0;
      }
    }

消除函數(shù)eliminationFunction邏輯的控制,flag用來進(jìn)行是否成功消除:

 
// 消除函數(shù)
function eliminationFunction(list: any[]) {
  let flag: boolean = false;
  for (let k = 0; k < list.length - 2; k++) {
    const temp = list;
    const arr = temp.slice(k, k + 3);
    console.log(k, arr);
    if (arr[0] === arr[1] && arr[1] === arr[2] && arr[0] === arr[2]) {
      list.splice(k + 2);
      list.splice(k + 1);
      list.splice(k, 1);
      flag = true
      break;
    }
  }
 
  return { list, flag };
}

添加addBoomFunction爆炸函數(shù):

// 實(shí)現(xiàn)爆炸??效果
function addBoomFunction(list: any[]) {
  const temp = JSON.parse(JSON.stringify([...list, ...['boom', 'boom', 'boom']]))
  return temp;
}

挑戰(zhàn)失敗如何判斷呢?

//fail
function failFun(tempList: any[]) {
  setTimeout(() => {
    if (footerList.value.length > 0 && !jugeList(tempList)) {
      ElMessage.closeAll();
 
      ElMessageBox.alert("挑戰(zhàn)失敗,點(diǎn)擊確定返回!", "Warning", {
        confirmButtonText: "確定",
        type: "warning",
        showClose: false,
      }).then(() => {
        location.reload();
      });
      return false;
    }
  }, 1002)
}

jugeList函數(shù)是對(duì)目前存在的卡片集合進(jìn)行長(zhǎng)度判斷,如何卡片不存在,但是槽位的數(shù)據(jù)不為空的情況下,說明沒有消除完,就判斷要重新開始挑戰(zhàn): 

// 判斷是否過關(guān)
function jugeList(list: any[]) {
  let temp: any = [];
  list?.forEach((oeni: { one: any }) => {
    oeni?.one?.forEach((sub: { oneSub: any }) => {
      temp = [...temp, ...sub.oneSub];
    });
  });
  return temp.length;
}

最后是挑戰(zhàn)成功就可以進(jìn)行下一關(guān):

// next
function nextFun(tempList: any[]) {
  setTimeout(() => {
    if (!footerList.value.length && !jugeList(tempList)) {
      // debugger
      ElMessage.closeAll();
      ElMessage.success("恭喜您,挑戰(zhàn)成功!進(jìn)入下一關(guān)");
      store.step++;
      const inStep: string = "list" + (store.step + 1);
      totalList.value = JSON.parse(JSON.stringify(data))[inStep];
      footerList.value = [];
    }
  }, 1001)
}

如何卡片不存在,但是槽位的數(shù)據(jù)為空的情況下,說明消除完了,就可以進(jìn)入下一關(guān)進(jìn)行挑戰(zhàn),難度也將升級(jí)!

4.總結(jié)

最近是由于玩了羊了個(gè)羊的小程序,有所感悟,思考了這個(gè)游戲的整體的玩法,如何去操作,然后想到了可以實(shí)現(xiàn)一個(gè)前端網(wǎng)頁版本的羊了個(gè)羊,這里面有一些自己的設(shè)計(jì)思考是很重要的,花了一個(gè)星期左右來實(shí)現(xiàn),中間遇到了如何消除,如何控制挑戰(zhàn)失敗,成功的問題,并且一一解決了,可以想到如果前端來做這個(gè)游戲怎么在最優(yōu)的方案上,書寫可以擴(kuò)展的dom,來適配很多不同的關(guān)卡的元素或者是我們需要什么樣的數(shù)據(jù)結(jié)構(gòu),方便后續(xù)的關(guān)卡的升級(jí)。這里解決的方案是配合json,數(shù)據(jù)是數(shù)組嵌套類型,元素是需要循環(huán)來調(diào)用的,什么類型的卡片是需要提前有個(gè)范圍的,這樣是可擴(kuò)展的。最后的操作,或者撤銷,恢復(fù)等操作(這里沒有實(shí)現(xiàn))本質(zhì)上也是對(duì)于數(shù)據(jù)的操作。終而言之:數(shù)據(jù)驅(qū)動(dòng)頁面,才是我們追求的。最后,各位同學(xué)一起多思考一下背后的實(shí)現(xiàn),讓我們用技術(shù)來創(chuàng)作更多有趣的事情吧~??

到此這篇關(guān)于vue3版本網(wǎng)頁小游戲的文章就介紹到這了,更多相關(guān)vue3網(wǎng)頁小游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue 動(dòng)態(tài)組件用法示例小結(jié)

    vue 動(dòng)態(tài)組件用法示例小結(jié)

    這篇文章主要介紹了vue 動(dòng)態(tài)組件用法,結(jié)合實(shí)例形式總結(jié)分析了vue 動(dòng)態(tài)組件基本功能、原理、使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • VUE學(xué)習(xí)寶典之vue-dialog使用方法

    VUE學(xué)習(xí)寶典之vue-dialog使用方法

    在Vue中dialog對(duì)話框是一種常見的組件,用于在用戶與應(yīng)用程序進(jìn)行交互時(shí)顯示信息或收集輸入,這篇文章主要給大家介紹了關(guān)于VUE學(xué)習(xí)寶典之vue-dialog使用方法的相關(guān)資料,需要的朋友可以參考下
    2024-05-05
  • vue實(shí)現(xiàn)圖片滑動(dòng)驗(yàn)證

    vue實(shí)現(xiàn)圖片滑動(dòng)驗(yàn)證

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)圖片滑動(dòng)驗(yàn)證,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • ElementUI表單驗(yàn)證validate和validateField的使用及區(qū)別

    ElementUI表單驗(yàn)證validate和validateField的使用及區(qū)別

    Element-UI作為前端框架,最常使用到的就是表單驗(yàn)證,下面這篇文章主要給大家介紹了關(guān)于ElementUI表單驗(yàn)證validate和validateField的使用及區(qū)別,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • vue3+echarts實(shí)現(xiàn)漸變色環(huán)形圖過程

    vue3+echarts實(shí)現(xiàn)漸變色環(huán)形圖過程

    這篇文章主要介紹了vue3+echarts實(shí)現(xiàn)漸變色環(huán)形圖過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 如何在Vue和Spring?boot之間實(shí)現(xiàn)前后端連接

    如何在Vue和Spring?boot之間實(shí)現(xiàn)前后端連接

    最近搭建一個(gè)Springboot+vue前后端分離項(xiàng)目,真的很簡(jiǎn)單,下面這篇文章主要給大家介紹了關(guān)于如何在Vue和Spring?boot之間實(shí)現(xiàn)前后端連接的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Vue聲明式導(dǎo)航與編程式導(dǎo)航示例分析講解

    Vue聲明式導(dǎo)航與編程式導(dǎo)航示例分析講解

    這篇文章主要介紹了Vue中聲明式導(dǎo)航與編程式導(dǎo)航,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-11-11
  • vue中setup語法糖寫法實(shí)例

    vue中setup語法糖寫法實(shí)例

    如果你在 vue3 開發(fā)中使用了語法的話,對(duì)于組件的name屬性,需要做一番額外的處理,下面這篇文章主要給大家介紹了關(guān)于Vue3 setup語法糖的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • 使用@tap.stop阻止事件繼續(xù)傳播

    使用@tap.stop阻止事件繼續(xù)傳播

    這篇文章主要介紹了使用@tap.stop阻止事件繼續(xù)傳播,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • electron-vue+electron-updater實(shí)現(xiàn)自動(dòng)更新(步驟源碼)

    electron-vue+electron-updater實(shí)現(xiàn)自動(dòng)更新(步驟源碼)

    這篇文章主要介紹了electron-vue+electron-updater實(shí)現(xiàn)自動(dòng)更新,步驟源碼包括autoUpdater.js操控更新js文件,main.js也就是package.json內(nèi)的main指向的js文件,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10

最新評(píng)論