Angular4 自制打地鼠游戏

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

前端工程师新手一枚,之前一直做些小设计,以及静态页面的编写工作。刚刚接触 Angular 没有多久,四个月前对于 Javascript也只是会写 alert 之流,现在进步算是很大,下面是自制的打地鼠游戏,是可以升级关卡的哦,希望大神临幸,千万别拍砖。

最后的成品是这样的,这是第四关:

 

HTML:

 

<div class="paddingv10 bg-white borderb text-center">

<span><button (click)="gameStartFn()" class="fixWidth">Start</button></span>

<span>Score: <em>{{score.scoreTotal}}</em></span>

<span>Hit Rate: <em>{{score.hitRate}}%</em></span>

<span>Time Left: <em>{{time.timeLeft}}</em></span>

<span><button (click)="gameOverFn('failed')" class="fixWidth">End</button></span>

</div>

<div class="moleContent clear">

<div>

<ul class="moleField clear">

<li *ngFor="let fd of field; let i = index;">

<div *ngFor="let random of mole.randomDisplay">

<div *ngIf="i == random" class="mole" id="mole" (click)="hitFn(i)"

                         [ngClass]="{ 'moleClicked': i == mole.clickedMole }">

                    </div>

</div>

</li>

</ul>

</div>

</div>

<div *ngIf="gameOver.isOver">

<div class="mask">

<div class="maskInner">

Game Over! <br/>

<button (click)="gameStartFn('restart')" class="flexWidth">Restart Game</button>

</div>

</div>

</div>

<div *ngIf="gameOver.isPassAll">

<div class="mask">

<div class="maskInner">

Conguratulations! You passed all the barries! <br/>

<button (click)="gameStartFn('restart')" class="flexWidth">Restart Game</button>

</div>

</div>

</div>

 

 

CSS:

* {

padding: 0;

margin: 0;

border: 0;

}

body {

background-color: #dedede;

}

button {

height: 26px;

line-height: 26px;

background-color:blueviolet;

color: #fff;

}

button.fixWidth {

width: 80px;

}

button.flexWidth {

padding: 0 10px;

}

button:hover {

cursor: pointer;

}

.paddingv10 {

padding-top: 10px;

padding-bottom: 10px;

}

.paddingt10 {

padding-top: 10px;

}

.paddingb10 {

padding-bottom: 10px;

}

.paddingr30 {

padding-right: 30px;

}

.marginr10 {

margin-right: 10px;

}

.marginl10 {

margin-left: 10px;

}

.borderb {

border-bottom: solid 1px #cccccc;

}

.clear {

clear: both;

}

.clear:before {

content: '';

display: block;

clear: both;

}

.clear:after {

content: '';

display: block;

clear: both;

}

.bg-white {

background-color: #fff;

}

.bg-gray {

background-color: #ccc !important;

}

.text-center {

text-align: center;

}

.text-black {

color: #333;

}

.text-red {

color: lightcoral;

}

.fs-26 {

font-size: 26px;

}

.mask {

position: fixed;

left: 0;

right: 0;

top: 0;

bottom: 0;

width: 100%;

height: 100%;

background: rgba(0,0,0,.6);

font-size: 26px;

color: orange;

font-weight: bolder;

text-align: center;

padding-top: 100px;

}

 

.moleContent {

width: 1020px;

margin: 0 auto;

}

.moleField {

width: 500px;

margin: 10px auto 0;

}

.moleField:hover {

cursor: -webkit-grabbing;

}

.moleField li {

float: left;

width: 100px;

height: 100px;

background-color: gold;

list-style-type: none;

border: 1px #dedede solid;

box-sizing: border-box;

overflow: hidden;

position: relative;

}

.moleField li.score {

animation: scoreAnimation .5s;

position: absolute;

bottom: 500px;

left: 50%;

opacity: 0;

}

.mole {

width: 50px;

height: 50px;

background-color: #ccc;

border-radius: 50%;

position: absolute;

left: 26px;

top: 30px;

animation: moleDisplay 1s;

}

.mole:before, .mole:after {

content: '';

width: 50%;

height: 50%;

background-color: #ccc;

border-radius: 50%;

position: absolute;

top: -20%;

left: -20%;

}

.mole:after {

left: 70%;

}

.mole.tranparent {

opacity: 1;

}

@keyframes moleDisplay {

0% { top: 200px; }

50% { top: 30px; }

100% { top: 30px; }

}

.moleClicked {

animation: moleClickingAnimation .5s;

opacity: 0;

}

.moleClicked:before {

animation: moleClickingLeftEar .5s;

opacity: 0;

top: -200%;

left: -200%;

}

.moleClicked:after {

animation: moleClickingRightEar .5s;

opacity: 0;

top: -200%;

left: 250%;

}

@keyframes moleClickingAnimation {

0% { opacity: 1; }

100% { opacity: 0; }

}

@keyframes moleClickingLeftEar {

0% { opacity: 1; top: -20%; left: -20%; }

100% { opacity: 0; top: -200%; left: -200%; }

}

@keyframes moleClickingRightEar {

0% { opacity: 1; top: -20%; left: 70%; }

100% { opacity: 0; top: -200%; left: 250%; }

}

 

 

TS:

import { Component, OnInit } from '@angular/core';

 

@Component({

templateUrl: './whacMole.component.html',

styleUrls: ['./whacMole.component.css']

})

 

export class WhacMoleComponent implements OnInit {

private barrier: number = 1; // 关卡数

private maxBarrier: number; // 最大关卡数,可以不设置

private field: Array<any> = []; // 田地格子

private columnNum: number; // 田地的行数和列数

private time: any;

private mole: any;

private score: any;

private timeCounting: any;

private disploayMoling: any;

private gameOver: any = { isOver: false, isPassAll: false };

constructor(){ }

 

ngOnInit(){

this.initData();

}

 

initData(){

this.gameOver.isOver = false;

this.gameOver.isPassAll = false;

this.columnNum = this.barrier * 5;

this.time = { timeTotal: 30, timeLeft: 0, autoDisplaySpacing: 3 };

this.time.timeLeft = this.time.timeTotal;

this.mole = { randomDisplay: undefined, clickedMole: undefined, moleShowed: 0 };

this.score = { scoreTotal: 0, hitRate: 0, hitCount: 0};

this.field = [];

for(let i = 0; i < this.columnNum; i++) {

this.field.push( { id: i, clicked: false });

}

}

timeCountFn(){

// 每一秒调用一次函数倒计时

this.timeCounting = setInterval(() => {

this.time.timeLeft--;

if (this.time.timeLeft <= 0){

this.gameStopFn();

}

}, 1000);

}

displayMoleFn(num){

// 根据不同的关卡,每一关传入的参数不同,地鼠出现的频率也不同

this.disploayMoling = setInterval(() => {

this.mole.clickedMole = undefined;

this.mole.randomDisplay = [];

let temRandomDisplay = [];

// 随机生成老鼠出现的位置

for(let i = 0; i < this.barrier; i++){

this.mole.randomDisplay[i] = Math.round(Math.random() * (this.field.length - 1) );

}

// 随机出现老鼠去重

for(let i = 0; i < this.mole.randomDisplay.length; i++){

if(temRandomDisplay.indexOf(this.mole.randomDisplay[i]) == -1){

temRandomDisplay.push(this.mole.randomDisplay[i]);

}

}

this.mole.moleShowed = this.mole.moleShowed + temRandomDisplay.length;

// 重置为未点击状态

for(let i = 0; i < this.field.length; i++){

this.field[i].clicked = false;

}

// 刷新击打百分比

this.hitRateFn();

}, num*1000);

}

hitFn(num) {

// 计算击中数量

if(this.field[num].clicked == true){

return;

}

this.score.hitCount++;

this.score.scoreTotal = this.score.hitCount * 10;

this.mole.clickedMole = num;

this.field[num].clicked = true;

this.hitRateFn();

}

hitRateFn(){

// 计算击中率

let hitRate = this.score.hitCount / this.mole.moleShowed;

this.score.hitRate = Math.floor(hitRate * 100);

}

 

gameStartFn(flag: string){

// 开始游戏

if(flag == 'restart') {

this.barrier = 1;

}

this.initData();

this.timeCountFn();

this.displayMoleFn(this.time.autoDisplaySpacing);

}

gameStopFn(){

// 游戏结束

clearInterval(this.timeCounting);

clearInterval(this.disploayMoling);

// 如果击中率大于60%,可以选择进入下一关;否则,直接game over

if(this.score.hitRate > 60 ) {

let confirmResult = confirm('Section ' + this.barrier + ' is stopping! \n Your total score is ' +

                                        this.score.scoreTotal + '\n Your hit rate is ' + this.score.hitRate +

                                        '\n Would you like to go on to next section?');

if(confirmResult){

this.barrier++;

if(this.barrier > this.maxBarrier){

this.gameOverFn('allpass');

} else {

this.initData();

this.gameStartFn('continue');

}

} else {

this.gameOverFn('failed');

}

} else {

this.gameOverFn('failed');

}

}

gameOverFn(flag: string){

// 游戏结束

clearInterval(this.timeCounting);

clearInterval(this.disploayMoling);

if(flag == 'failed') {

this.gameOver.isOver = true;

this.gameOver.isPassAll = false;

} else if (flag == 'allpass'){

this.gameOver.isOver = false;

this.gameOver.isPassAll = true;

}

}

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值