贪吃蛇,童年的回忆

在做任何东西之前,你会觉得没有一点点头绪,从而因为胆怯而惊恐放弃,但在开始之后,你会慢慢找到思路,然后一步一步克服困难。

先给出完整代码,然后再拆分说明

贪吃蛇小游戏完整代码

一、little-game.component.ts

import { Component, OnInit } from '@angular/core';
import { EventManager } from'@angular/platform-browser' 
@Component({
  selector: 'app-little-game',
  templateUrl: './little-game.component.html',
  styleUrls: ['./little-game.component.css']
})
export class LittleGameComponent implements OnInit {

  start:boolean=false;//控制着游戏的开始
  isShow:boolean=true;//控制着小蛇的显示
  foodColors:string[]=['yellow','green','orange','purple','blue','pink','cyan'];
  foodColor:string;
  foodX:number;//食物的位置left
  foodY:number;//食物的位置top
  snake=[{top:120,left:60},{top:120,left:30},{top:120,left:0}];//用于初始化小蛇
  intervalId:any;//该变量作为时间函数的id,可用于停止游戏
  speed:number=600;//决定小蛇移动的速度,会随着小蛇的长度改变,设置不同的速度
  direction:string="right";//移动方向
  moveX:number=60;//小蛇蛇头的位置
  moveY:number=120;
  maxClientX:number=document.documentElement.clientWidth;//可见屏幕宽度
  maxClientY:number=document.documentElement.clientHeight;

startGame(){//开始游戏按钮触发函数
    this.start=true;
    this.isShow=false;
    this.intervalId=setInterval(()=>{
    this.snakeMove();
    },this.speed);
   
  }

snakeMove(){//小蛇移动函数
   var snake=document.querySelectorAll(".snake");
   switch(this.direction){//更改头snake_head移动的方向,每次移动30px
     case 'left':{this.moveX-=30;break;}
     case 'top':{this.moveY-=30;break;}
     case 'right':{this.moveX+=30;break;}
     case 'bottom':{this.moveY+=30;break;}
   } 
   for(var i=snake.length-1;i>0;i--){//使snake_body移动
      snake[i].setAttribute('style',`${snake[i-1].getAttribute('style')}`);
   }
      snake[0].setAttribute('style',`top:${this.moveY}px ;left:${this.moveX}px;background-color:${this.foodColors[Math.round(Math.random()*6)]}`);
      this.rightPosition();
      this.eatFood();
      this.speedUp(snake.length);
}

setDirection(keyCode){//改变小蛇移动方向函数
    switch(keyCode){
      case 37:{
        if(this.direction!="right"){//如果小蛇正在向右移动,则按<--不起作用
           this.direction="left";
            }
              break;}
      case 38:{
        if(this.direction!="bottom"){
           this.direction="top";
              }
        break;}
      case 39:{
        if(this.direction!="left"){
          this.direction="right";
        }
        break;}
      case 40:{
        if(this.direction!="top"){
          this.direction="bottom";
        }
        break;}
      case 27:{
        clearInterval(this.intervalId);
        this.start=false;
        document.getElementById("start").innerHTML="暂停游戏";
          break;}
    }
}

beginning(){//游戏开始时初始化snake的样子
    var snake=document.querySelectorAll('.snake');
    for(var i=0;i<snake.length;i++){
      snake[i].setAttribute('style',`top:${this.snake[i].top}px ; left:${this.snake[i].left}px;background-color:${this.foodColors[Math.round(Math.random()*6)]}`);
    }
}

speedUp(len:number){//设置游戏难度
    if(len<=5){
      this.speed=600;
    }else if(len>5&&len<=10){
      this.speed=400;
    }else{
      this.speed=200;
    }
}

rightPosition(){//判断小蛇是否撞墙
    var obj=document.getElementById("start");
    var body=document.getElementById("container");
   if(this.moveX>=this.maxClientX||this.moveY>=this.maxClientY||this.moveX<=0||this.moveY<=0){//如果满足这些条件,则说明小蛇撞墙了,游戏结束
        clearInterval(this.intervalId);
        obj.innerHTML="游戏结束";
        body.setAttribute("style","background-image:url('https://desk-fd.zol-img.com.cn/t_s1440x900c5/g5/M00/0C/06/ChMkJlgpWByIXzZAAAwLNmXG1M8AAXuiwIjv3EADAtO870.jpg')")
        this.start=false;
   }
}

createFood(){//生成食物,只需当食物被吃掉后修改食物的位置以及颜色表示生成新的食物
    var food=document.getElementById("food");
    this.foodX=Math.round(Math.random()*this.maxClientX);
    this.foodY=Math.round(Math.random()*this.maxClientY);
    this.foodColor=this.foodColors[Math.round(Math.random()*6)];//生成0~6的随机整数,以随机生成食物颜色
    food.setAttribute('style',`top:${this.foodY}px;left:${this.foodX}px;background-color:${this.foodColor}`);
}

eatFood(){//小蛇吃食物
    var distanceX=Math.abs(this.foodX-this.moveX);//食物距离加绝对值
    var distanceY=Math.abs(this.foodY-this.moveY);
    if(distanceX<15&&distanceY<15){
      var snake=document.getElementById("snake");//一整条小蛇,看成整体
      var snakeBodies=document.querySelectorAll(".snake");//将小蛇分成由每个div组成
      snake.appendChild(snakeBodies[1].cloneNode());
      this.createFood();//吃到食物,生成新的食物
    }
}

  constructor(private eventListener :EventManager) { }

  ngOnInit(): void {
    this.eventListener.addGlobalEventListener('window','keydown',(event:any)=>{//监听键盘函数
      this.setDirection(event.keyCode);
    });
    this.beginning();
    this.createFood();
  }
}

二、little-game.component.html

<div class="container" id="container">
    <div [hidden]="isShow" id="snake">
      <div class="snake snake_head" id="snake_head"></div>
      <div class="snake" ></div>
      <div class="snake" ></div>
    </div>
    <div [hidden]="isShow" class="food" id="food" background-color: white></div>
  <div [hidden]="start" class="start" id="start" (click)="startGame()" >开始游戏</div>
</div>

三、little-game.component.css

*{
    margin:0px;
    padding:0px;
}

.container{
    height:760px;
    width:1500px;
    margin:5px auto;
    border:5px solid rgb(231, 16, 16);
    background-image: url("https://desk-fd.zol-img.com.cn/t_s1920x1200c5/g2/M00/0F/09/ChMlWV54MFGIBJkSAALF0XNHM_YAANzwgLaF2gAAsXp119.jpg");
    background-size: 100% 100%;
    background-repeat: no-repeat;
    background-origin: border-box;
    position: absolute;
}
.start{
    height:60px;
    width:120px;
    margin:0px auto;
    margin-top:450px;
    text-align: center;
    line-height: 60px;
    border:1px transparent rgb(207, 29, 29);
    border-radius: 80%;
    background-color: blueviolet;
    background-origin: border-box;
    cursor: pointer;
}

.snake{
    position: absolute;
    height:30px;
    width:30px;
}
.snake_head{
    border-radius:50%;
}
.food{
    position: absolute;
    height:30px;
    width:30px;
}

四、运行效果
1.游戏初始界面
在这里插入图片描述
2.小蛇初始化
在这里插入图片描述
3.小蛇吃食物
在这里插入图片描述
4.小蛇触碰边界,游戏结束
在这里插入图片描述

拆分说明

一、首先得建立游戏框架吧
这里不多说,界面就是上面的鲨鱼视图+一些css样式修饰
二、贪吃蛇游戏得有条小蛇

snake=[{top:120,left:60},{top:120,left:30},{top:120,left:0}];//用于初始化小蛇
beginning(){//游戏开始时初始化snake的样子
    var snake=document.querySelectorAll('.snake');
    for(var i=0;i<snake.length;i++){
     	 snake[i].setAttribute('style',`top:${this.snake[i].top}px ; left:${this.snake[i].left}px;background-color:${this.foodColors[Math.round(Math.random()*6)]}`);
    }
}

三、先不考虑小蛇怎么吃东西,得先让小蛇动起来才有机会吃东西,要动起来则要引入“计时”事件,让它每隔一定时间改变小蛇样式,小蛇不就动起来了吗?

this.intervalId=setInterval(()=>{//每隔this.speed毫秒就调用一次this.snakeMove()方法移动小蛇
    this.snakeMove();
    },this.speed);

snakeMove(){//小蛇移动函数
   var snake=document.querySelectorAll(".snake");
   switch(this.direction){//根据小蛇snake_head移动的方向,每次移动30px
     case 'left':{this.moveX-=30;break;}
     case 'top':{this.moveY-=30;break;}
     case 'right':{this.moveX+=30;break;}
     case 'bottom':{this.moveY+=30;break;}
   } 
   for(var i=snake.length-1;i>0;i--){//使snake_body后一块样式等于前一块样式就可以移动
      snake[i].setAttribute('style',`${snake[i-1].getAttribute('style')}`);
   }
      snake[0].setAttribute('style',`top:${this.moveY}px ;left:${this.moveX}px;background-color:${this.foodColors[Math.round(Math.random()*6)]}`);
}    

四、小蛇总不能一直只往一个方向移动吧,得用键盘的上下左右键改变小蛇方向,要获得键盘信息,就需先引入键盘监听事件

import { EventManager } from'@angular/platform-browser' 

constructor(private eventListener :EventManager) { }

ngOnInit(): void {
    this.eventListener.addGlobalEventListener('window','keydown',(event:any)=>{//监听键盘函数
      this.setDirection(event.keyCode);//每当有按键盘就调用该方法
    });
  }  

setDirection(keyCode){//改变小蛇移动方向函数
    switch(keyCode){
      case 37:{
        if(this.direction!="right"){//如果小蛇正在向右移动,则按向左键不起作用
           this.direction="left";
            }
              break;}
      case 38:{
        if(this.direction!="bottom"){
           this.direction="top";
              }
        break;}
      case 39:{
        if(this.direction!="left"){
          this.direction="right";
        }
        break;}
      case 40:{
        if(this.direction!="top"){
          this.direction="bottom";
        }
        break;}
      case 27:{//按esc键,暂停游戏
        clearInterval(this.intervalId);
        this.start=false;
        document.getElementById("start").innerHTML="暂停游戏";
          break;}
    }
}

五、小蛇可以随意走动了,是不是该吃食物了,要吃食物得先有食物,然后再吃,根据蛇头位置与食物位置作比较,判断是否吃到食物

ngOnInit(): void {//游戏开始时,先生成食物
  this.createFood();
 }
 
createFood(){//生成食物,只需当食物被吃掉后修改食物的位置以及颜色表示生成新的食物
    var food=document.getElementById("food");
    this.foodX=Math.round(Math.random()*this.maxClientX);
    this.foodY=Math.round(Math.random()*this.maxClientY);
    this.foodColor=this.foodColors[Math.round(Math.random()*6)];//生成0~6的随机整数,以随机生成食物颜色
    food.setAttribute('style',`top:${this.foodY}px;left:${this.foodX}px;background-color:${this.foodColor}`);
}

eatFood(){//小蛇吃食物
    var distanceX=Math.abs(this.foodX-this.moveX);//食物距离加绝对值
    var distanceY=Math.abs(this.foodY-this.moveY);
    if(distanceX<15&&distanceY<15){
      var snake=document.getElementById("snake");//一整条小蛇,看成整体
      var snakeBodies=document.querySelectorAll(".snake");//将小蛇分成由每个div组成
      snake.appendChild(snakeBodies[1].cloneNode());
      this.createFood();//吃到食物,生成新的食物
    }
}

六、小蛇撞墙不是应该挂掉吗?这里没有小蛇咬死自己的规则,根据小蛇头部位置与边界位置判断是否撞墙,撞墙则结束游戏

rightPosition(){//判断小蛇是否撞墙
        var obj=document.getElementById("start");
        var body=document.getElementById("container");
   if(this.moveX>=this.maxClientX||this.moveY>=this.maxClientY||this.moveX<=0||this.moveY<=0){//如果满足这些条件,则说明小蛇撞墙了,游戏结束
        clearInterval(this.intervalId);
        obj.innerHTML="游戏结束";
        body.setAttribute("style","background-image:url('https://desk-fd.zol-img.com.cn/t_s1440x900c5/g5/M00/0C/06/ChMkJlgpWByIXzZAAAwLNmXG1M8AAXuiwIjv3EADAtO870.jpg')")
        this.start=false;
   }
}

七、小蛇长大了,应该移动的更快来加大难度吧,缩小“计时”事件的调用时间即可

speedUp(len:number){//设置游戏难度
    if(len<=5){
      this.speed=600;
    }else if(len>5&&len<=10){
      this.speed=400;
    }else{
      this.speed=200;
    }
}

上面就是搞贪吃蛇游戏的思路,能力有限,仅能这样了。。。

猜你喜欢

转载自blog.csdn.net/weixin_43334673/article/details/105509770