亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

微信小程序?qū)崿F(xiàn)經(jīng)典window掃雷游戲

 更新時(shí)間:2022年09月08日 17:14:00   作者:new?object(yanyan)  
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)經(jīng)典window掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

打開手機(jī)游戲列表發(fā)現(xiàn)了一款經(jīng)典的掃雷游戲,在玩的過程中發(fā)現(xiàn)游戲邏輯應(yīng)該不難,想著是不是能自己寫寫這個(gè)游戲,后來用了1天實(shí)現(xiàn)了整體游戲開發(fā),于是有了這篇文章來總結(jié)整體的游戲開發(fā)思路。

一、掃雷游戲規(guī)則是什么?

1、游戲?yàn)樵?0*10或其它排序組合網(wǎng)格中找雷
2、網(wǎng)格中隱藏著一定數(shù)量的雷,點(diǎn)擊到雷即為輸
3、點(diǎn)擊無雷的網(wǎng)格會(huì)顯示其臨近8個(gè)方向上的總雷數(shù),若為0則臨近8個(gè)方向上的網(wǎng)格也會(huì)自動(dòng)顯示雷數(shù),以此類推,直到出現(xiàn)不為0的網(wǎng)格
4、長按網(wǎng)格可以標(biāo)記網(wǎng)格為雷
5、找出所有的雷即為勝利

二、開發(fā)前準(zhǔn)備

1.創(chuàng)建小程序項(xiàng)目

使用微信開發(fā)者工具創(chuàng)建一個(gè)小程序項(xiàng)目。推薦使用官方推薦模板(此游戲項(xiàng)目使用js來實(shí)現(xiàn))

2.開始開發(fā)

2.1.實(shí)現(xiàn)網(wǎng)格地圖

頁面初始數(shù)據(jù):

groundSize: [16, 16], // 地圖大小
minePosition: [], // 保存雷的位置
secondInterval: 0, // 時(shí)間定時(shí)器
data: {
? second: 0, // 游戲時(shí)間
? mineCount: 24, // 雷總數(shù)
? markMineCount: 0, // 已標(biāo)記雷數(shù)
? renderGridList: [], // 網(wǎng)格列表
},

此地圖為16*16的地圖,行列大小根據(jù) groundSize 來,后續(xù)可以設(shè)置不同的地圖大小。

地圖wxml代碼(具體樣式自行規(guī)劃):

<view class="play-ground">
? <view class="play-ground__row" wx:for="{{renderGridList}}" wx:for-item="row" wx:key="index">
? ? ?<view class="play-ground__col {{col.showNum && col.mineNum === 0 ? 'play-ground__col--empty' : ''}}" wx:for="{{row}}" wx:for-item="col" wx:key="index" data-value="{{col.value}}" bindlongpress="setMineTag" bindtap="clearBox">
? ? ? ?<!-- 標(biāo)記雷圖標(biāo) -->
? ? ? ?<image wx:if="{{col.mineTag}}" class="play-ground__col-boom" src="../../static/image/mine/mine.png"></image>
? ? ? ?<!-- 點(diǎn)擊到雷圖標(biāo) -->
? ? ? ?<image wx:if="{{!col.mineTag && col.isBoom && col.isMine}}" class="play-ground__col-boom" src="../../static/image/mine/boom.png"></image>
? ? ? ?<!-- 周圍雷數(shù) -->
? ? ? ?<text wx:if="{{col.showNum && col.mineNum}}" class="play-ground__col-num play-ground__col-num--{{col.mineNum}}">{{col.mineNum}}</text>
? ? ?</view>
? ?</view>
</view>

renderGridList 渲染列表結(jié)構(gòu)(二維數(shù)組):

[
? [
? ? {
? ? ? isMine: false, // 是否為雷
? ? ? mineTag: false, // 手動(dòng)添加是否是雷的標(biāo)識(shí)
? ? ? isBoom: false, // 是否點(diǎn)擊到了雷
? ? ? mineNum: 0, // 周圍雷數(shù)
? ? ? showNum: false, // 是否顯示雷數(shù)
? ? ? value: 0, // 等同于id
? ? ? position: [0, 0], // 標(biāo)志在第幾行第幾列
? ? },
? ? ...
? ],
? ...
]

初始化網(wǎng)格方法:

initGrid() {
? const gridList = [];
? ?// 當(dāng)前遍歷gridList到第幾個(gè)元素
? ?let currentNum = 0;
? ?// 當(dāng)前遍歷minePosition到第幾個(gè)元素
? ?let currentMineIndex = 0;
? ?for (let i = 0; i < this.groundSize[0]; i++) {
? ? ?const row = [];
? ? ?for (let j = 0; j < this.groundSize[1]; j++) {
? ? ? ?let isMine = false;
? ? ? ?// 判斷是否是雷
? ? ? ?if (currentNum === this.minePosition[currentMineIndex]) {
? ? ? ? ?isMine = true;
? ? ? ? ?currentMineIndex += 1;
? ? ? ?}
? ? ? ?row.push({
? ? ? ? ?isMine,
? ? ? ? ?mineTag: false, // 手動(dòng)添加是否是雷的標(biāo)識(shí)
? ? ? ? ?isBoom: false, // 是否點(diǎn)擊到了雷
? ? ? ? ?mineNum: 0, // 周圍雷數(shù)
? ? ? ? ?showNum: false, // 是否顯示雷數(shù)
? ? ? ? ?value: currentNum,
? ? ? ? ?position: [i, j],
? ? ? ?});
? ? ? ?currentNum += 1;
? ? ?}
? ? ?gridList.push(row);
? ?}
? ?this.setData({
? ? ?renderGridList: this.generateMineNum(gridList),
? ?});
?}

2.2.生成雷

generateMine() {
? ?this.minePosition = [];
? ?// 已設(shè)置的雷總數(shù)
? ?let hadSetCount = 0;
? ?// 隨機(jī)最大值根據(jù)網(wǎng)格大小來
? ?const groundCount = this.groundSize[0] * this.groundSize[1];
? ?if (this.data.mineCount >= groundCount) {
? ? ? return;
? ? }
? ? while (hadSetCount < this.data.mineCount) {
? ? ? // 生成隨機(jī)數(shù)
? ? ? const randomNum = ~~(Math.random() * groundCount);
? ? ? // 判斷隨機(jī)數(shù)是否存在
? ? ? if (!this.minePosition.includes(randomNum)) {
? ? ? ? this.minePosition.push(randomNum);
? ? ? ? hadSetCount += 1;
? ? ? }
? ? }
? ? // 從小到大排序
? ? this.minePosition.sort((a, b) => (a > b ? 1 : -1));
? }

根據(jù)頁面初始數(shù)據(jù)中的 mineCount 來指定生成的雷數(shù),通過隨機(jī)值函數(shù)來生產(chǎn)隨機(jī)的雷的 value 值,每生成一個(gè)先判斷值是否在 minePosition 數(shù)組存在,不存在就push到 minePosition 數(shù)組中去。最終結(jié)果如下:在 initGrid 方法中會(huì)根據(jù) minePosition 對應(yīng)的值和網(wǎng)格的value值作比較,相等即為雷。

minePosition (24) [10, 17, 25, 28, 34, 35, 48, 73, 106, 132, 152, 187, 196, 197, 199, 203, 210, 217, 220, 226, 234, 238, 240, 245]

2.3.生成雷數(shù)

generateMineNum(gridList) {
?gridList.forEach(row => {
? ? row.forEach(col => {
? ? ? // 是雷則跳過
? ? ? if (col.isMine) {
? ? ? ? return;
? ? ? }
? ? ? col.mineNum = this.checkMine(gridList, col.position);
? ? });
? });
? return gridList;
},
checkMine(gridList, position) {
? const [i, j] = position;
? let mineNum = 0;
? // 判斷8個(gè)方位是否有雷
? // 上 [i - 1][j]
? if (gridList[i - 1] && gridList[i - 1][j].isMine) {
? ? mineNum += 1;
? }
? // 右上 [i - 1][j + 1]
? if (gridList[i - 1] && gridList[i - 1][j + 1] && gridList[i - 1][j + 1].isMine) {
? ? mineNum += 1;
? }
? // 右 [i][j + 1]
? if (gridList[i][j + 1] && gridList[i][j + 1].isMine) {
? ? mineNum += 1;
? }
? // 右下 [i + 1][j + 1]
? if (gridList[i + 1] && gridList[i + 1][j + 1] && gridList[i + 1][j + 1].isMine) {
? ? mineNum += 1;
? }
? // 下 [i + 1][j]
? if (gridList[i + 1] && gridList[i + 1][j].isMine) {
? ? mineNum += 1;
? }
? // 左下 [i + 1][j - 1]
? if (gridList[i + 1] && gridList[i + 1][j - 1] && gridList[i + 1][j - 1].isMine) {
? ? mineNum += 1;
? }
? // 左 [i][j - 1]
? if (gridList[i][j - 1] && gridList[i][j - 1].isMine) {
? ? mineNum += 1;
? }
? // 左上 [i - 1][j - 1]
? if (gridList[i - 1] && gridList[i - 1][j - 1] && gridList[i - 1][j - 1].isMine) {
? ? mineNum += 1;
? }
? return mineNum;
}

判斷8個(gè)方向上是否有雷時(shí)我們需要注意那些在邊角的網(wǎng)格,這些網(wǎng)格方向少于8個(gè),所以我們在做判斷是需先判斷其方向上是否有網(wǎng)格才行。

2.4.長按添加雷的標(biāo)識(shí)

setMineTag(e) {
? const {
? ? currentTarget: {
? ? ? dataset: { value },
? ? },
? } = e;
? const renderGridList = this.data.renderGridList;
? let markMineCount = 0;
? for (const row of renderGridList) {
? ? for (const col of row) {
? ? ? if (col.value === value) {
? ? ? ? col.mineTag = !col.mineTag;
? ? ? }
? ? ? if (col.mineTag) {
? ? ? ? markMineCount += 1;
? ? ? }
? ? }
? }
? this.setData({
? ? renderGridList,
? ? markMineCount,
? });
},

我們在網(wǎng)格上設(shè)置 data-value ,這樣長按事件就能獲取對應(yīng)的 value 值,通過遍歷比較找到對應(yīng)的網(wǎng)格并對網(wǎng)格的 mineTag 屬性取反來達(dá)到長按標(biāo)記或取消的功能,同時(shí) mineTag 為真時(shí)需記錄下標(biāo)記數(shù)量。

2.5.點(diǎn)擊網(wǎng)格事件

clearBox(e) {
? const {
? ? currentTarget: {
? ? ? dataset: { value },
? ? },
? } = e;
? let renderGridList = this.data.renderGridList;
? out: for (const row of renderGridList) {
? ? for (const col of row) {
? ? ? if (col.value === value) {
? ? ? ? // 判斷是否是雷,為雷則輸
? ? ? ? col.isBoom = col.isMine;
? ? ? ? if (col.isBoom) {
? ? ? ? ? wx.showToast({
? ? ? ? ? ? icon: 'error',
? ? ? ? ? ? title: '踩到雷了',
? ? ? ? ? });
? ? ? ? ? break out;
? ? ? ? }
? ? ? ? renderGridList = this.loopClearBox(renderGridList, col);
? ? ? ? break out;
? ? ? }
? ? }
? }
? this.setData({
? ? renderGridList,
? });
},
loopClearBox(gridList, col) {
? if (col.isMine || col.showNum) {
? ? return gridList;
? }
? col.showNum = true;
? if (col.mineNum) {
? ? return gridList;
? }
? // 判斷相鄰的4個(gè)方位是否為空并遞歸遍歷
? const [i, j] = col.position;
? if (gridList[i - 1]) {
? ?? ?// 上
? ? col = gridList[i - 1][j];
? ? if (col) {
? ? ? if (!col.mineNum) {
? ? ? ? gridList = this.loopClearBox(gridList, col);
? ? ? } else {
? ? ? ? col.showNum = !col.isMine;
? ? ? }
? ? }
? }
? if (gridList[i + 1]) {
? ?? ?// 下
? ? col = gridList[i + 1][j];
? ? if (col) {
? ? ? if (!col.mineNum) {
? ? ? ? gridList = this.loopClearBox(gridList, col);
? ? ? } else {
? ? ? ? col.showNum = !col.isMine;
? ? ? }
? ? }
? }
? // 左
? col = gridList[i][j - 1];
? if (col) {
? ? if (!col.mineNum) {
? ? ? gridList = this.loopClearBox(gridList, col);
? ? } else {
? ? ? col.showNum = !col.isMine;
? ? }
? }
? // 右
? col = gridList[i][j + 1];
? if (col) {
? ? if (!col.mineNum) {
? ? ? gridList = this.loopClearBox(gridList, col);
? ? } else {
? ? ? col.showNum = !col.isMine;
? ? }
? }
? return gridList;
}

loopClearBox 是遞歸遍歷方法,當(dāng)點(diǎn)擊的網(wǎng)格的周圍雷數(shù)為空時(shí)我們需要遞歸其上下左右方向的網(wǎng)格。效果如圖所示:

遞歸只有遇到有雷數(shù)的網(wǎng)格才會(huì)停下。

2.6.輸贏判斷

checkWin() {
? // 當(dāng)標(biāo)記數(shù)小于總雷數(shù)時(shí)才判斷輸贏
? if (this.data.mineCount >= this.data.markMineCount) {
? ? // 遍歷網(wǎng)格判斷標(biāo)記的雷是否正確
? ? for (let row in this.data.renderGridList) {
? ? ? for (let col of row) {
? ? ? ? if (col.isMine !== col.mineTag) {
? ? ? ? ? return false;
? ? ? ? }
? ? ? }
? ? }
? ? return true;
? }
? return false;
}

輸贏判斷是在點(diǎn)擊網(wǎng)格事件中執(zhí)行的,當(dāng)返回值為true時(shí)即為通關(guān)。

總結(jié)

以上就是整個(gè)游戲開發(fā)的整體思路講解,代碼量不多,總體js代碼只有2百多行,設(shè)計(jì)思路也比較簡單。對于在開發(fā)中的收獲,或許就是當(dāng)你玩著自己開發(fā)的游戲時(shí),作為程序員的快樂。

希望這篇文章對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:

相關(guān)文章

最新評論