vue3开发扫雷游戏,支持调整难度,支持计时

news/2024/11/13 16:08:26/文章来源:https://www.cnblogs.com/leesen/p/18544170

闲来练习练习js,写了个扫雷游戏,直接拿去复制粘到自己本地某个html文件里就能运行,记得把vue加载地址改成线上的~~

有空了可以再加上计分板

运行起来长下面这样

 直接上代码

 

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6     <title>扫雷v1.0</title>
  7     <!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
  8     <script src="vue.global-v3.5.12.js"></script>
  9     <style>
 10         *{ margin:0; padding:0; font-size:14px; color:#333;}
 11         body{ padding: 20px; }
 12         .container{
 13             background-color: #efefef;
 14             padding: 10px;
 15             display: flex;
 16         }
 17         .warper{
 18             padding:1px;
 19             background-color: #cfcfcf;
 20         }
 21         .row{
 22             display: flex;
 23             flex-direction: row;
 24         }
 25         .cell{
 26             width: 30px;
 27             text-align: center;
 28             height: 30px;
 29             line-height: 30px;
 30             background-color: #dfdfdf;
 31             border: 2px solid #cfcfcf;
 32         }
 33         .cell:hover{
 34             border-color:rgb(250, 179, 112);
 35             background-color: rgb(231, 202, 164);
 36             cursor: pointer;
 37         }
 38         .board{
 39             width: 170px;
 40             margin-right: 20px;
 41         }
 42         .config-item{
 43             padding:10px;
 44         }
 45         .config-item .btn{
 46             margin-right: 20px;
 47         }
 48         .cell.clicked-0{ background-color: #f7f7f7; }
 49         .cell.clicked-1{ background-color: #fff0f0; }
 50         .cell.clicked-2{ background-color: #ffdbdb; }
 51         .cell.clicked-3{ background-color: #ffc3c3; }
 52         .cell.clicked-4{ background-color: #ffa3a3; }
 53         .cell.clicked-5{ background-color: #ff9898; color: white; }
 54         .cell.clicked-6{ background-color: #ff6f6f; color: white; }
 55         .cell.clicked-7{ background-color: #ff5a5a; color: white; }
 56         .cell.clicked-8{ background-color: #ff2424; color: white; }
 57         .cell.boom{ background-color: #ffffff; color: rgb(255, 0, 0); font-size:22px;}
 58         .cell.flag{ border-color: #fdafaf; }
 59     </style>
 60 </head>
 61 <body>
 62     <div class="container" id="app">
 63         <div class="board">
 64             <div class="config-item">
 65                 <h3>请点击START开始游戏</h3>
 66                 <h3>点击RESET重置游戏</h3>
 67             </div>
 68             <div class="config-item">
 69                 <form>
 70                     <label for="rowsindex">难度</label>
 71                     <select v-model="currentLevel" @change="handleLevelChange">
 72                         <option v-for="(level, index) in levels" :key="index" :value="level">{{ level.name }}</option>
 73                     </select>
 74                 </form>
 75             </div>
 76             <div class="config-item">
 77                 用时 <strong>{{ costTime }}</strong>
 78             </div>
 79             <div class="config-item">
 80                 <button class="btn" @click="resetGame">RESET</button>
 81                 <button class="btn" :disabled="gameStatus == 'start'" @click="startGame">START</button>
 82             </div>
 83         </div>
 84         <div class="warper">
 85             <div class="row" v-for="(row, indexRow) in cells" :key="indexRow">
 86                 <div 
 87                     v-for="(column, indexColumn) in cells[indexRow]" 
 88                     :key="indexColumn" 
 89                     :class="'cell '+column.style" 
 90                     @click="handleCellClick(indexRow, indexColumn)"
 91                     @click.right.prevent="handleCellFlag(indexRow, indexColumn)"
 92                 >
 93                     {{ column.text }}
 94                 </div>
 95             </div>
 96         </div>
 97     </div>
 98 
 99 <script>
100     const { createApp, ref, computed, nextTick } = Vue
101     createApp({
102         setup() {
103             const boomValue = 332962963;
104             const levels = ref([
105                 { name: '黑铁', rowsindex: 8, columnsindex: 8, boomCount: 6 },
106                 { name: '青铜', rowsindex: 10, columnsindex: 10, boomCount: 11 },
107                 { name: '白银', rowsindex: 14, columnsindex: 14, boomCount: 20 },
108                 { name: '黄金', rowsindex: 16, columnsindex: 16, boomCount: 28 },
109                 { name: '白金', rowsindex: 20, columnsindex: 20, boomCount: 44 },
110                 { name: '钻石', rowsindex: 24, columnsindex: 24, boomCount: 60 },
111                 { name: '大师', rowsindex: 30, columnsindex: 30, boomCount: 95 },
112                 { name: '王者', rowsindex: 36, columnsindex: 36, boomCount: 120 }
113             ]);
114             const currentLevel = ref(levels.value[0]);
115 
116             let rowsindex = currentLevel.value.rowsindex;
117             let columnsindex = currentLevel.value.columnsindex;
118             let boomCount = currentLevel.value.boomCount;
119 
120             const start = 0;
121             let end = computed(()=>{
122                 return rowsindex*columnsindex-1;
123             })
124             const gameStatus = ref("stop");
125             const costTime = ref("00:00:00");
126             let timer;
127             let startTime = 0;
128 
129             const cells = ref([]);
130             let randoms = [];
131             let rightsZero = [];
132 
133             const startGame = () => {
134                 gameStatus.value = "start";
135                 startTimer();
136                 initGame();
137             }
138 
139             const resetGame = () => {
140                 gameStatus.value = "stop";
141                 stopTimer();
142                 resetTimer();
143                 initGame();
144             }
145 
146             const handleLevelChange = () => {
147                 console.log(currentLevel.value)
148                 resetGame();
149             }
150 
151             const handleCellClick = (i, j) => {
152                 if(gameStatus.value!=='start'){
153                     return;
154                 }
155 
156                 if(cells.value[i][j].value != boomValue){
157                     rightsZero = [];
158                     clickRights(i, j);
159                     for(let i=0; i<rightsZero.length; i++){
160                         let [rowIndex, columnIndex] = getRowIndexColumnIndex(rightsZero[i]);
161                         cells.value[rowIndex][columnIndex] = getCellClickedInfo(rowIndex, columnIndex);
162                     }
163                     ifWin();
164                 }else{
165                     cells.value[i][j] = {style:'boom', clicked: true, text: '⭕️', value: boomValue};
166                     finishGame();
167                 }
168             }
169 
170             const handleCellFlag = (i, j) => {
171                 if(gameStatus.value!=='start'){
172                     return;
173                 }
174                 
175                 let cell = cells.value[i][j];
176                 if(cell.clicked){
177                     return;
178                 }
179                 if(cell.style === 'flag'){
180                     cells.value[i][j] = {style:'unClicked', clicked: false, text: '', value: cell.value};
181                 }else{
182                     cells.value[i][j] = {style:'flag', clicked: false, text: '🚩', value: cell.value};
183                     ifWin();
184                 }
185             }
186 
187             const ifWin = () => {
188                 let flagCount = 0;
189                 for(let i=0; i<rowsindex; i++){
190                     for(let j=0; j<columnsindex; j++){
191                         if(cells.value[i][j].style === 'flag'){
192                             flagCount++;
193                         }
194                     }
195                 }
196                 let rightCount = 0;
197                 for(let i=0; i<rowsindex; i++){
198                     for(let j=0; j<columnsindex; j++){
199                         if(cells.value[i][j].value === boomValue && cells.value[i][j].style == 'flag'){
200                             rightCount++;
201                         }
202                     }
203                 }
204                 if(flagCount === boomCount && flagCount === rightCount){
205                     winGame();
206                 }
207             }
208 
209             const clickRights = (i, j) => {
210                 let index = i*rowsindex+j;
211                 if(rightsZero.indexOf(index) !== -1){
212                     return;
213                 }
214                 rightsZero.push(index);
215                 if(cells.value[i][j].value === 0){
216                     //
217                     if(i - 1 >= 0 && cells.value[i-1][j].value === 0 && cells.value[i-1][j].clicked === false && cells.value[i-1][j].style !== 'flag'){
218                         clickRights(i-1, j);
219                     }
220                     //
221                     if(i + 1 < rowsindex && cells.value[i+1][j].value === 0 && cells.value[i+1][j].clicked === false && cells.value[i+1][j].style !== 'flag'){
222                         clickRights(i+1, j);
223                     }
224                     //
225                     if(j - 1 >= 0 && cells.value[i][j-1].value === 0 && cells.value[i][j-1].clicked === false && cells.value[i][j-1].style !== 'flag'){
226                         clickRights(i, j-1);
227                     }
228                     //
229                     if(j + 1 < columnsindex && cells.value[i][j+1].value === 0 && cells.value[i][j+1].clicked === false && cells.value[i][j+1].style !== 'flag'){
230                         clickRights(i, j+1);
231                     }
232                 }
233             }
234 
235             const getCellClickedInfo = (row, index) => {
236                 let cell = cells.value[row][index];
237                 return {style:'clicked-'+cell.value, clicked: true, text: cell.value === 0 ? '' : cell.value, value: cell.value};
238             }
239 
240             const finishGame = () => {
241                 gameStatus.value = 'stop';
242                 setTimeout(()=>{
243                     stopTimer();
244                     alert('Game Over');
245                     showAllBoom();
246                     // initGame();
247                 }, 50)
248             }
249 
250             const winGame = () => {
251                 gameStatus.value = 'stop';
252                 setTimeout(()=>{
253                     stopTimer();
254                     alert('You Win');
255                     // initGame();
256                 }, 50)
257             }
258 
259             const showAllBoom = () => {
260                 for(let i=0; i<rowsindex; i++){
261                     for(let j=0; j<columnsindex; j++){
262                         const cell = cells.value[i][j];
263                         if(cell.value === boomValue){
264                             cells.value[i][j] = {style:'boom', clicked: true, text: '⭕️', value: boomValue};
265                         }else{
266                             cells.value[i][j] = {style:'clicked-'+cell.value, clicked: true, text: cell.value === 0 ? '' : cell.value, value: cell.value};
267 
268                         }
269                     }
270                 }
271             }
272 
273             const initGame = () => {
274                 console.log('initGame')
275                 rowsindex = currentLevel.value.rowsindex;
276                 columnsindex = currentLevel.value.columnsindex;
277                 boomCount = currentLevel.value.boomCount;
278 
279                 cells.value = [];
280                 randoms = [];
281                 for(let i=0; i<rowsindex; i++){
282                     cells.value[i] = [];
283                     for(let j=0; j<columnsindex; j++){
284                         cells.value[i][j] = {style:'unClicked', clicked: false, text: '', value: 0};
285                     }
286                 }
287                 for(let i=0; i<boomCount; i++){
288                     getUniqueRandoms(randoms);
289                 }
290                 for(let i=0; i<randoms.length; i++){
291                     let [rowIndex, columnIndex] = getRowIndexColumnIndex(randoms[i]);
292                     cells.value[rowIndex][columnIndex].value = boomValue;
293                 }
294                 for(let i=0; i<rowsindex; i++){
295                     for(let j=0; j<columnsindex; j++){
296                         if(cells.value[i][j].value !== boomValue){
297                             let count = 0;
298                             for(let x=i-1; x<=i+1; x++){
299                                 for(let y=j-1; y<=j+1; y++){
300                                     if(x>=0 && x<rowsindex && y>=0 && y<columnsindex && cells.value[x][y].value === boomValue){
301                                         count++;
302                                     }
303                                 }
304                             }
305                             cells.value[i][j].value = count;
306                         }
307                     }
308                 }
309             }
310 
311             const getRandoms = () => {
312                 return parseInt(Math.random()*(start+1-end.value) + end.value);
313             }
314 
315             const getUniqueRandoms = (randoms) => {
316                 let random = getRandoms();
317                 if(randoms.indexOf(random) === -1){
318                     randoms.push(random);
319                 }else{
320                     getUniqueRandoms(randoms);
321                 }
322             }
323 
324             const getRowIndexColumnIndex = (index) => {
325                 let rowIndex = parseInt(index / columnsindex);
326                 let columnIndex = index % columnsindex;
327                 return [rowIndex, columnIndex];
328             }
329 
330             const startTimer = () => {
331                 startTime = new Date().getTime();
332                 timer = setInterval(()=>{
333                     costTime.value = getCostTime();
334                 }, 1000)
335             }
336 
337             const stopTimer = () => {
338                 clearInterval(timer);
339             }
340 
341             const resetTimer = () => {
342                 startTime = 0;
343                 costTime.value = '00:00:00';
344             }
345 
346             const getCostTime = () => {
347                 let now = new Date().getTime();
348                 let diff = parseInt((now - startTime) / 1000);
349                 let h = parseInt(diff / 3600);
350                 let hStr = h < 10? '0'+h : h;
351                 let m = parseInt((diff % 3600) / 60);
352                 let mStr = m < 10? '0'+m : m;
353                 let s = diff % 60;
354                 let sStr = s < 10? '0'+s : s;
355                 return hStr+':'+mStr+':'+sStr;
356             }
357 
358             initGame();
359             
360             return {
361                 cells,
362                 costTime,
363                 gameStatus,
364                 rowsindex,
365                 columnsindex,
366                 levels,
367                 currentLevel,
368                 handleCellClick,
369                 handleCellFlag,
370                 resetGame,
371                 startGame,
372                 handleLevelChange
373             }
374         }
375     }).mount('#app')
376 </script>
377 </body>
378 </html>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/833004.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记一次potplayer播放视频错误

如图,播放存在问题解决方式,打开potplayer->选项->滤镜然后更换系统解码器即可作者:qbning出处:http://www.cnblogs.com/qbning/-------------------------------------------个性签名:曾经的我们空有一颗望海的心,却从没为前往大海做过真正的努力如果觉得这篇文章…

【大模型评测】国内外主流评测基准分析(图)

附件 1.作者:Syw 2.出处:http://www.cnblogs.com/syw20170419/ 3.本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 4.如果文中有什么错误,欢迎指出。以免更多的人被误导。

(系列十一)Vue3框架中路由守卫及请求拦截(实现前后端交互)

说明该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发)。该系统文章,我会尽量说的非常详细,做到不管新手、老手都能看懂。说明:OverallAuth2.0 是一个简单、易懂、功能强大的权限+可视化流程管理系统。 友情提醒:本篇文章是属于系列文章,…

MIGO DUMP LCX_RAP_EVENT_RUNTIME CL_RAP_EVENT_MANAGER==========CP

MIGO 收货时发生DUMP运行事务代码:SBGRFCCONF 创建入站目标输入目标BGPF 保存即可TRANSLATE with xEnglishArabic Hebrew PolishBulgarian Hindi PortugueseCatalan Hmong Daw RomanianChinese Simplified Hungarian RussianChinese Traditional Indonesian SlovakCzech Ital…

非煤矿山算法智慧矿山一体机提升机危险区域违规闯入识别边坡监测预警系统详述

在矿山行业中,安全始终是最为关键的议题。随着智能化技术的发展,智慧矿山一体机应运而生,它专为矿山安全监控和管理设计,集成了多种智能化功能,以提升矿山的安全监管能力和生产效率。这款设备不仅能够满足矿山场景下的视频智能化建设需求,还能够通过边缘计算技术实现对矿…

全国职业院校技能大赛

老师说目前这个是省赛,预计12月参加,如果要准备的话,预计要有一个月的时间准备我看了一下往年的题目,确实是平常老师跟我们讲的那种术语什么的

Hadoop搭建集群

不知道为什么会出现这样的结果

使用idea创建Sping Boot 项目 发现不能使用JAVA版本是8或者11版本只能用17版本已经更高

接下来需要一个骚操作, 官方地址: https://start.spring.io阿里云脚手架地址:https://start.aliyun.com/

[题解]P3225 [HNOI2012] 矿场搭建

P3225 [HNOI2012] 矿场搭建 挖煤点坍塌相当于把该点和与其相连的边在图上删掉。 借用wjyyy的题解,我们定义“叶子连通块”为“只包含\(1\)个割点的点双连通分量”,“非叶子连通块”为“包含\(\ge 2\)个割点的点双连通分量”。 如下图,橙色点是割点,红色框圈出的是点双,加粗…

DDCA —— 内存架构和子系统内存控制器

Digital Design and Computer Architecture Lecture21的学习笔记,介绍内存架构和子系统、内存控制器,并详细介绍了DRAM的内部结构。1. 内存架构和子系统 1.1 如何控制访问?访问控制:存储单元的访问是通过 访问晶体管(access transistors) 进行控制的。访问晶体管像开关一…

ubuntu上安装 NVIDIA GeForce RTX 4090驱动

背景 ai服务器上安装完ubuntu系统后,需要安装NVIDIA显卡驱动 官网驱动下载https://www.nvidia.cn/drivers/details/235646/驱动安装 1.卸载原有驱动 sudo apt remove --purge nvidia*2.备份 sudo cp /etc/modprobe.d/blacklist.conf /etc/modprobe.d/blacklist.conf_bak 3.末尾…