Angular4 扫雷小游戏
作者:互联网
扫雷小游戏,可以升级过关,难度随关卡增加。但是有很明显的bug,以后有时间会继续优化!
HTML:
<div class="mainContent"> <div class="bg-white text-center borderb paddingv10"> <button class="flexWidth marginr10" (click)="gameStartFn()">Start</button> <button class="flexWidth marginr10" (click)="gameEndFn()">Stop Game</button> <span>Mine Left: {{this.mineArray.length}}</span> </div> <ul class="mineContainer clear" [ngStyle]="getWidth()"> <li *ngFor="let column of columnArray" (mousedown)="onClickFn(column.index, $event)" oncontextmenu="return false" [ngClass]="{ 'bg-gray': column.clicked == true && column.number == 0}" > <span *ngIf="column.isMine && visibleItem.mine" class="fa fa-bomb fs-26 text-black"></span> <span *ngIf="!column.isOver && !column.isMine && column.number !=0">{{column.number}}</span> <span *ngIf="column.isFlag" class="fa fa-flag"></span> <!-- <span class="text-red">{{column.index}}</span> --> </li> </ul> </div>
CSS:
.mineContainer { margin: 20px auto; box-sizing: border-box; } .mineContainer li { width: 50px; height: 50px; border: solid 1px #fff; float: left; background-color: orange; color: #fff; text-align: center; line-height: 50px; box-sizing: border-box; display: flex; justify-content: center; align-items: center; } .mineContainer li:hover { cursor: pointer; }
TS:
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @Component ({ templateUrl: './mineSweeping.component.html', styleUrls: ['./mineSweeping.component.css'] }) export class MineSweepingComponent implements OnInit { private hitSection: any = { sectionNum: 1, columnNum: '', minMineNum: '' }; // 关卡参数: 关卡数、列数、最小地雷数 private visibleItem: any = { mine: false, location: false }; // 控制是否显示的参数:地雷、标记 private columnArray: Array<any> = []; // 地雷画布数组(好多参数,下面会有赋值) private mineArray: Array<any> = []; // 地雷数组 private rules: any; // 判断点击位置是否为最上下左右列-- private isOver: boolean = false ; // 是否结束 private isSuccess: boolean = false; // 是否成功 constructor(private router: Router){} ngOnInit(){ this.hitSectionInitFn(); this.columnInitFn(); this.mineInitFn(); } hitSectionInitFn(){ // 根据关卡数调整列数,最小地雷总数 this.hitSection.columnNum = this.hitSection.sectionNum * 5; this.hitSection.minMineNum = this.hitSection.sectionNum * 5; } columnInitFn(){ // 地雷画布初始化: 坐标(id)、水平坐标、垂直坐标、是否为雷、周围雷数、是否被点击、是否被标记 this.columnArray = []; for(let i = 0; i < this.hitSection.columnNum ; i++){ for(let j = 0; j < this.hitSection.columnNum; j++) { this.columnArray.push({ index: this.columnArray.length, horizontal: i, vertical: j, isMine: false, number: 0, clicked: false, isFlag: false }); } } } mineInitFn(){ // 地雷初始化 let tempArray = [], tempMineNum; this.mineArray = []; // 根据最小地雷数,随机生成一个 [最小地雷数 - (最小地雷数 + 最小地雷数)]之间的数值,为本关的地雷总数(比如10 - 20之间的数值) tempMineNum = Math.round( Math.random() * this.hitSection.minMineNum + this.hitSection.minMineNum); // 根据地雷总数,随机生成数字数组 for(let i = 0; i < tempMineNum; i++){ tempArray.push( Math.round ( Math.random() * (this.hitSection.columnNum * this.hitSection.columnNum) ) ); } // 数组去重 for(let i = 0; i < tempArray.length; i++){ if(this.mineArray.indexOf(tempArray[i]) == -1){ this.mineArray.push(tempArray[i]); } } // 根据去重数组,赋值给地雷画布数组中的 isMine 参数 for(let i = 0; i < this.columnArray.length; i++) { for(let j = 0; j < this.mineArray.length; j++) { if(this.mineArray[j] == i){ this.columnArray[i].isMine = true; } } } console.log(this.mineArray); } onClickFn(index, event){ if(event.button == 2){ // 点击右键,做雷区标记 this.columnArray[index].isFlag = !this.columnArray[index].isFlag; if(this.columnArray[index].isFlag){ this.mineArray.length--; } else { this.mineArray.length++; } } else { // 点击左键,计算周围雷数 this.checkMineArroundFn(index); } // 每次点击后,查看是否过关 setTimeout(() => { this.ifSuccessFn(); }, 100); } getPositionRules(index: number){ // 判断点击位置是否为最上下左右列 this.rules = { top: this.columnArray[index].horizontal == 0, bottom: this.columnArray[index].horizontal == (this.hitSection.columnNum - 1), left: this.columnArray[index].vertical == 0, right: this.columnArray[index].vertical == (this.hitSection.columnNum - 1) } } checkMineArroundFn(index: number){ // 计算周围雷数 if(this.columnArray[index].clicked ){ return; } this.getPositionRules(index); if(this.columnArray[index].isMine) { this.gameEndFn(); return; } else if (!this.columnArray[index].isMine) { // 这里逻辑比较复杂, 根据点击坐标,计算其上、下、左、右、左上、右上、左下、右下八块位置的雷数,如果是第一列,则不计算上、左上、右上(以此类推) if(!this.rules.top) { if( this.columnArray[(index - this.hitSection.columnNum)].isMine ) { this.columnArray[index].number++; } // top if (!this.rules.left) { if( this.columnArray[(index - this.hitSection.columnNum - 1)].isMine ) { this.columnArray[index].number++; } // top left } if (!this.rules.right) { if( this.columnArray[(index - this.hitSection.columnNum + 1)].isMine ) { this.columnArray[index].number++; } // top right } } if(!this.rules.bottom) { if( this.columnArray[(index + this.hitSection.columnNum)].isMine ) { this.columnArray[index].number++; } // bottom if (!this.rules.left) { if( this.columnArray[(index + this.hitSection.columnNum - 1)].isMine ) { this.columnArray[index].number++; } // bottom left } if (!this.rules.right) { if( this.columnArray[(index + this.hitSection.columnNum + 1)].isMine ) { this.columnArray[index].number++; } // bottom right } } if(!this.rules.left) { if( this.columnArray[(index - 1)].isMine ) { this.columnArray[index].number++; } // left } if(!this.rules.right) { if( this.columnArray[(index + 1)].isMine ) { this.columnArray[index].number++; } //right } this.columnArray[index].clicked = true; } // 如果周围没有雷,则执行下面函数(扩大计算面积,查找周围坐标的附近雷数) if( this.columnArray[index].number == 0 ){ this.checkAroundFn(index); } } checkAroundFn(index: number){ // 扩大计算面积,查找周围坐标的附近雷数(还是如果是第一行,不查找左上、上、右上位置) if(!this.rules.top){ this.checkMineArroundFn(index - this.hitSection.columnNum); if(!this.rules.left) { this.checkMineArroundFn(index - this.hitSection.columnNum - 1); } if(!this.rules.right){ this.checkMineArroundFn(index - this.hitSection.columnNum + 1); } } if(!this.rules.bottom){ this.checkMineArroundFn(index + this.hitSection.columnNum); if(!this.rules.left) { this.checkMineArroundFn(index + this.hitSection.columnNum - 1); } if(!this.rules.right){ this.checkMineArroundFn(index + this.hitSection.columnNum + 1); } } if(!this.rules.left){ this.checkMineArroundFn(index - 1); } if(!this.rules.right){ this.checkMineArroundFn(index + 1); } } gameStartFn(){ // 游戏开始 this.hitSectionInitFn(); this.columnInitFn(); this.mineInitFn(); this.visibleItem = { mine: false, location: false,}; } gameEndFn(){ // 游戏结束 debugger this.visibleItem = { mine: true, location: false }; this.isOver = true; for(let i = 0; i < this.columnArray.length; i++){ this.columnArray[i].clicked = true; this.columnArray[i].isFlag = false; } } ifSuccessFn(){ //判断是否过关 let temCheckSuccess = false; // 查看地雷画布中,所有 isMine 对应的 isFlag 是否同为 true(也就是说,左右雷都被标记) for(let i = 0; i < this.columnArray.length; i++){ if( this.columnArray[i].isFlag != this.columnArray[i].isMine ) { temCheckSuccess = false; return; } else { temCheckSuccess = true; } } // 询问是否进入下一关 if(temCheckSuccess){ this.isSuccess = true; if(this.isSuccess){ let confirmNext = confirm('Congaratulations! You have pass the section ' + this.hitSection.sectionNum + '. \n Would you like go on?') if(confirmNext){ this.hitSection.sectionNum++; this.gameStartFn(); } else { this.router.navigate(['/home']); } } } } getWidth(){ // 根据列数,获取外层盒子宽度 return { width: this.hitSection.columnNum * 50 + 'px' } } }
标签:index,rules,columnArray,columnNum,++,Angular4,小游戏,扫雷,hitSection 来源: https://www.cnblogs.com/junyuan-frontend/p/angular_mineSweeping.html