Angular4 扫雷小游戏

5 篇文章 0 订阅
3 篇文章 0 订阅

扫雷小游戏,可以升级过关,难度随关卡增加。但是有很明显的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)"

οncοntextmenu="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' }

}

 

}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值