add 支持自定义动物图案、随机区情况
This commit is contained in:
		| @@ -8,9 +8,14 @@ | |||||||
| <script setup lang="ts"></script> | <script setup lang="ts"></script> | ||||||
| <style scoped> | <style scoped> | ||||||
| #app { | #app { | ||||||
|   padding: 16px 16px 50px; |  | ||||||
|   background: url("assets/bg.jpeg"); |   background: url("assets/bg.jpeg"); | ||||||
|  |   padding: 16px 16px 50px; | ||||||
|   min-height: 100vh; |   min-height: 100vh; | ||||||
|   background-size: 100% 100%; |   background-size: 100% 100%; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .content { | ||||||
|  |   max-width: 480px; | ||||||
|  |   margin: 0 auto; | ||||||
|  | } | ||||||
| </style> | </style> | ||||||
|   | |||||||
| @@ -28,10 +28,10 @@ const useGame = () => { | |||||||
|   const blockData: Record<number, BlockType> = {}; |   const blockData: Record<number, BlockType> = {}; | ||||||
|  |  | ||||||
|   // 总块数 |   // 总块数 | ||||||
|   let totalBlockNum = 0; |   let totalBlockNum = ref(0); | ||||||
|  |  | ||||||
|   // 已消除块数 |   // 已消除块数 | ||||||
|   let clearBlockNum = 0; |   let clearBlockNum = ref(0); | ||||||
|  |  | ||||||
|   // 总共划分 24 x 24 的格子,每个块占 3 x 3 的格子,生成的起始 x 和 y 坐标范围均为 0 ~ 21 |   // 总共划分 24 x 24 的格子,每个块占 3 x 3 的格子,生成的起始 x 和 y 坐标范围均为 0 ~ 21 | ||||||
|   const boxWidthNum = 24; |   const boxWidthNum = 24; | ||||||
| @@ -99,12 +99,12 @@ const useGame = () => { | |||||||
|  |  | ||||||
|     // 补齐到 blockNumUnit 的倍数 |     // 补齐到 blockNumUnit 的倍数 | ||||||
|     // e.g. minBlockNum = 14, blockNumUnit = 6, 补到 18 |     // e.g. minBlockNum = 14, blockNumUnit = 6, 补到 18 | ||||||
|     totalBlockNum = minBlockNum; |     totalBlockNum.value = minBlockNum; | ||||||
|     if (totalBlockNum % blockNumUnit !== 0) { |     if (totalBlockNum.value % blockNumUnit !== 0) { | ||||||
|       totalBlockNum = |       totalBlockNum.value = | ||||||
|         (Math.floor(minBlockNum / blockNumUnit) + 1) * blockNumUnit; |         (Math.floor(minBlockNum / blockNumUnit) + 1) * blockNumUnit; | ||||||
|     } |     } | ||||||
|     console.log("总块数", totalBlockNum); |     console.log("总块数", totalBlockNum.value); | ||||||
|  |  | ||||||
|     // 2. 初始化块,随机生成块的内容 |     // 2. 初始化块,随机生成块的内容 | ||||||
|     // 保存所有块的数组 |     // 保存所有块的数组 | ||||||
| @@ -112,14 +112,14 @@ const useGame = () => { | |||||||
|     // 需要用到的动物数组 |     // 需要用到的动物数组 | ||||||
|     const needAnimals = gameConfig.animals.slice(0, gameConfig.typeNum); |     const needAnimals = gameConfig.animals.slice(0, gameConfig.typeNum); | ||||||
|     // 依次把块塞到数组里 |     // 依次把块塞到数组里 | ||||||
|     for (let i = 0; i < totalBlockNum; i++) { |     for (let i = 0; i < totalBlockNum.value; i++) { | ||||||
|       animalBlocks.push(needAnimals[i % gameConfig.typeNum]); |       animalBlocks.push(needAnimals[i % gameConfig.typeNum]); | ||||||
|     } |     } | ||||||
|     // 打乱数组 |     // 打乱数组 | ||||||
|     const randomAnimalBlocks = _.shuffle(animalBlocks); |     const randomAnimalBlocks = _.shuffle(animalBlocks); | ||||||
|  |  | ||||||
|     // 初始化 |     // 初始化 | ||||||
|     for (let i = 0; i < totalBlockNum; i++) { |     for (let i = 0; i < totalBlockNum.value; i++) { | ||||||
|       const newBlock = { |       const newBlock = { | ||||||
|         id: i, |         id: i, | ||||||
|         status: 0, |         status: 0, | ||||||
| @@ -146,7 +146,7 @@ const useGame = () => { | |||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     // 剩余块数 |     // 剩余块数 | ||||||
|     let leftBlockNum = totalBlockNum - totalRandomBlockNum; |     let leftBlockNum = totalBlockNum.value - totalRandomBlockNum; | ||||||
|  |  | ||||||
|     // 4. 计算有层级关系的块 |     // 4. 计算有层级关系的块 | ||||||
|     const levelBlocks: BlockType[] = []; |     const levelBlocks: BlockType[] = []; | ||||||
| @@ -337,7 +337,7 @@ const useGame = () => { | |||||||
|         // 块状态改为已消除 |         // 块状态改为已消除 | ||||||
|         slotBlock.status = 2; |         slotBlock.status = 2; | ||||||
|         // 已消除块数 +1 |         // 已消除块数 +1 | ||||||
|         clearBlockNum++; |         clearBlockNum.value++; | ||||||
|         // 清除操作记录,防止撤回 |         // 清除操作记录,防止撤回 | ||||||
|         opHistory = []; |         opHistory = []; | ||||||
|         return; |         return; | ||||||
| @@ -353,7 +353,7 @@ const useGame = () => { | |||||||
|         alert("你输了"); |         alert("你输了"); | ||||||
|       }, 2000); |       }, 2000); | ||||||
|     } |     } | ||||||
|     if (clearBlockNum >= totalBlockNum) { |     if (clearBlockNum.value >= totalBlockNum.value) { | ||||||
|       gameStatus.value = 3; |       gameStatus.value = 3; | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| @@ -467,6 +467,8 @@ const useGame = () => { | |||||||
|     heightUnit, |     heightUnit, | ||||||
|     currSlotNum, |     currSlotNum, | ||||||
|     opHistory, |     opHistory, | ||||||
|  |     totalBlockNum, | ||||||
|  |     clearBlockNum, | ||||||
|     doClickBlock, |     doClickBlock, | ||||||
|     doStart, |     doStart, | ||||||
|     doShuffle, |     doShuffle, | ||||||
|   | |||||||
| @@ -20,6 +20,9 @@ | |||||||
|       <a-form-item label="动物数" name="typeNum"> |       <a-form-item label="动物数" name="typeNum"> | ||||||
|         <a-input-number v-model:value="config.typeNum" /> |         <a-input-number v-model:value="config.typeNum" /> | ||||||
|       </a-form-item> |       </a-form-item> | ||||||
|  |       <a-form-item label="动物图案" name="animalStr"> | ||||||
|  |         <a-input v-model:value="config.animalStr" /> | ||||||
|  |       </a-form-item> | ||||||
|       <a-form-item label="总层数" name="levelNum"> |       <a-form-item label="总层数" name="levelNum"> | ||||||
|         <a-input-number v-model:value="config.levelNum" /> |         <a-input-number v-model:value="config.levelNum" /> | ||||||
|       </a-form-item> |       </a-form-item> | ||||||
| @@ -29,6 +32,12 @@ | |||||||
|       <a-form-item label="边界收缩" name="borderStep"> |       <a-form-item label="边界收缩" name="borderStep"> | ||||||
|         <a-input-number v-model:value="config.borderStep" /> |         <a-input-number v-model:value="config.borderStep" /> | ||||||
|       </a-form-item> |       </a-form-item> | ||||||
|  |       <a-form-item label="随机区数" name="randomAreaNum"> | ||||||
|  |         <a-input-number v-model:value="config.randomAreaNum" /> | ||||||
|  |       </a-form-item> | ||||||
|  |       <a-form-item label="随机区块数" name="randomBlockNum"> | ||||||
|  |         <a-input-number v-model:value="config.randomBlockNum" /> | ||||||
|  |       </a-form-item> | ||||||
|       <a-form-item> |       <a-form-item> | ||||||
|         <a-button |         <a-button | ||||||
|           type="primary" |           type="primary" | ||||||
| @@ -53,9 +62,25 @@ import { defaultGameConfig } from "../core/gameConfig"; | |||||||
| const formRef = ref<FormInstance>(); | const formRef = ref<FormInstance>(); | ||||||
| const router = useRouter(); | const router = useRouter(); | ||||||
| const { setGameConfig, setCustomConfig } = useGlobalStore(); | const { setGameConfig, setCustomConfig } = useGlobalStore(); | ||||||
| const config = reactive<GameConfigType>({ ...defaultGameConfig }); | const initConfig = { | ||||||
|  |   ...defaultGameConfig, | ||||||
|  |   randomAreaNum: 2, | ||||||
|  |   randomBlockNum: 8, | ||||||
|  |   animalStr: defaultGameConfig.animals.join(""), | ||||||
|  | }; | ||||||
|  | const config = reactive<any>(initConfig); | ||||||
|  |  | ||||||
| const handleFinish = (values: GameConfigType) => { | /** | ||||||
|  |  * 表单提交 | ||||||
|  |  * @param values | ||||||
|  |  */ | ||||||
|  | const handleFinish = (values: any) => { | ||||||
|  |   config.randomBlocks = new Array(values.randomAreaNum).fill( | ||||||
|  |     values.randomBlockNum | ||||||
|  |   ); | ||||||
|  |   if (values.animalStr) { | ||||||
|  |     config.animals = Array.from(values.animalStr); | ||||||
|  |   } | ||||||
|   setGameConfig(config); |   setGameConfig(config); | ||||||
|   setCustomConfig(config); |   setCustomConfig(config); | ||||||
|   router.push("/game"); |   router.push("/game"); | ||||||
|   | |||||||
| @@ -1,13 +1,18 @@ | |||||||
| <template> | <template> | ||||||
|   <div id="gamePage"> |   <div id="gamePage"> | ||||||
|  |     <a-row align="space-between"> | ||||||
|       <a-button style="margin-bottom: 8px" @click="doBack"> 返回</a-button> |       <a-button style="margin-bottom: 8px" @click="doBack"> 返回</a-button> | ||||||
|     <a-row align="center"> |       <a-button>块数:{{ clearBlockNum }} / {{ totalBlockNum }}</a-button> | ||||||
|  |     </a-row> | ||||||
|     <!-- 胜利 --> |     <!-- 胜利 --> | ||||||
|  |     <a-row align="center"> | ||||||
|       <div v-if="gameStatus === 3" style="text-align: center"> |       <div v-if="gameStatus === 3" style="text-align: center"> | ||||||
|         <h2>恭喜,你赢啦!🎉</h2> |         <h2>恭喜,你赢啦!🎉</h2> | ||||||
|         <img alt="程序员鱼皮" src="../assets/kunkun.png" /> |         <img alt="程序员鱼皮" src="../assets/kunkun.png" /> | ||||||
|       </div> |       </div> | ||||||
|  |     </a-row> | ||||||
|     <!-- 分层选块 --> |     <!-- 分层选块 --> | ||||||
|  |     <a-row align="center"> | ||||||
|       <div v-show="gameStatus > 0" class="level-board"> |       <div v-show="gameStatus > 0" class="level-board"> | ||||||
|         <div v-for="(block, idx) in levelBlocksVal" :key="idx"> |         <div v-for="(block, idx) in levelBlocksVal" :key="idx"> | ||||||
|           <div |           <div | ||||||
| @@ -26,8 +31,9 @@ | |||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|  |     </a-row> | ||||||
|     <!-- 随机选块 --> |     <!-- 随机选块 --> | ||||||
|       <div class="random-board"> |     <a-row align="space-between" class="random-board"> | ||||||
|       <div |       <div | ||||||
|         v-for="(randomBlock, index) in randomBlocksVal" |         v-for="(randomBlock, index) in randomBlocksVal" | ||||||
|         :key="index" |         :key="index" | ||||||
| @@ -48,25 +54,22 @@ | |||||||
|           class="block disabled" |           class="block disabled" | ||||||
|         ></div> |         ></div> | ||||||
|       </div> |       </div> | ||||||
|       </div> |     </a-row> | ||||||
|     <!-- 槽位 --> |     <!-- 槽位 --> | ||||||
|       <div v-if="slotAreaVal.length > 0" class="slot-board"> |     <a-row v-if="slotAreaVal.length > 0" align="center" class="slot-board"> | ||||||
|         <div |       <div v-for="(slotBlock, index) in slotAreaVal" :key="index" class="block"> | ||||||
|           v-for="(slotBlock, index) in slotAreaVal" |  | ||||||
|           :key="index" |  | ||||||
|           class="block" |  | ||||||
|         > |  | ||||||
|         {{ slotBlock?.type }} |         {{ slotBlock?.type }} | ||||||
|       </div> |       </div> | ||||||
|       </div> |     </a-row> | ||||||
|     <!-- 技能 --> |     <!-- 技能 --> | ||||||
|       <a-space style="margin-top: 16px"> |     <div class="skill-board"> | ||||||
|  |       <a-space> | ||||||
|         <a-button size="small" @click="doRevert">撤回</a-button> |         <a-button size="small" @click="doRevert">撤回</a-button> | ||||||
|         <a-button size="small" @click="doRemove">移出</a-button> |         <a-button size="small" @click="doRemove">移出</a-button> | ||||||
|         <a-button size="small" @click="doShuffle">洗牌</a-button> |         <a-button size="small" @click="doShuffle">洗牌</a-button> | ||||||
|         <a-button size="small" @click="doBroke">破坏</a-button> |         <a-button size="small" @click="doBroke">破坏</a-button> | ||||||
|       </a-space> |       </a-space> | ||||||
|     </a-row> |     </div> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| @@ -84,6 +87,8 @@ const { | |||||||
|   slotAreaVal, |   slotAreaVal, | ||||||
|   widthUnit, |   widthUnit, | ||||||
|   heightUnit, |   heightUnit, | ||||||
|  |   totalBlockNum, | ||||||
|  |   clearBlockNum, | ||||||
|   doClickBlock, |   doClickBlock, | ||||||
|   doStart, |   doStart, | ||||||
|   doShuffle, |   doShuffle, | ||||||
| @@ -122,8 +127,13 @@ onMounted(() => { | |||||||
| } | } | ||||||
|  |  | ||||||
| .slot-board { | .slot-board { | ||||||
|   margin-top: 24px; |  | ||||||
|   border: 10px solid saddlebrown; |   border: 10px solid saddlebrown; | ||||||
|  |   margin: 16px auto; | ||||||
|  |   width: fit-content; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .skill-board { | ||||||
|  |   text-align: center; | ||||||
| } | } | ||||||
|  |  | ||||||
| .block { | .block { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user