TypeScript实战 -- 贪吃蛇游戏(1)--项目简介与具体实现、实现食物类和计分板类

TypeScript实战 -- 贪吃蛇游戏(1)--项目简介与具体实现、实现食物类和计分板类_第1张图片

TypeScript实战 – 贪吃蛇(1)

目的

使用typescript以及面向对象的方式编写简易版贪吃蛇的项目,实现:蛇自主移动,吃到食物检测并增加身体长度,食物随机生成,计分板,撞墙检测,键盘事件检测等基本功能。

界面

TypeScript实战 -- 贪吃蛇游戏(1)--项目简介与具体实现、实现食物类和计分板类_第2张图片
TypeScript实战 -- 贪吃蛇游戏(1)--项目简介与具体实现、实现食物类和计分板类_第3张图片

分析

总体来说,整个游戏中所含的类可以分为四个:蛇(Snake),食物(Food),计分板(Scoreboard),游戏控制器(GameController)。

  • Snake:获取与设置蛇身体部分的位置,增加长度,处理撞墙,检测是否吃到自己,禁止掉头
  • Food:获取与设置食物位置,随机改变位置
  • Scoreboard:获取积分和等级,增加积分,增加等级
  • GameController:控制游戏开始和结束,吃到食物检测,蛇移动,调用其他各对象的方法完成游戏的逻辑。

还需要一个HTML作为界面展示,具体typescript简单项目搭建,webpack配置可以看我另外一个文章讲了如何从0开始搭建简单的webpack编译ts的项目

HTML整体结构与样式不多赘述

注意的地方就是:因为每次吃到食物后,增加一段,增加的是蛇容器里面的子元素,所以我们对于蛇的样式需要加在蛇的子元素上,而蛇容器不必加样式和定位

HTML:

<html>
<head>
  <title>贪吃蛇title>
head>
<body>
  <div class="snake_postion">
    <div class="snake_body">
      <div class="snake_body_screen">
        
        <div class="snake">
          <div>div>
        div>
        
        <div class="food">div>
      div>
      <div class="snake_body_score_level">
        <div class="snake_body_item">level:
          <span class="level">0span>
        div>
        <div class="snake_body_item">grade:
          <span class="score">0span>
        div>
      div>
    div>
  div>
body>

html>

CSS(将主要用到的列了出来):

/* 定位总游戏盒子  */
.snake_postion{
     
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
/* 游戏盒子  */
.snake_body{
     
  width: 324px;
  height: 400px;
  background: #1e272e;
  border-radius: 10px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 10px;
  box-shadow: 0 0 15px #1e272e;
}
/* 屏幕 */
.snake_body_screen{
     
  background: #485460;
  height: 304px;
  box-sizing: border-box;
  border-radius: 6px;
  border: 2px solid #808e9b;
  position: relative;
}
/* 记分板 */
.snake_body_score_level{
     
  border-radius: 6px;
  text-align: center;
  font-size: 20px;
  color: #fff;
  line-height: 50px;
  display: flex;
}
/* 记分板各项 */
.snake_body_item{
     
  width: 50%;
  font-size: 14px;
  text-shadow: 0 0 10px #222f3e;
}
/* 蛇身体 */
.snake > div{
     
  width: 10px;
  height: 10px;
  background: #222f3e;
  border: 1px solid #808e9b;
  position: absolute;
  border-radius: 2px;
}
/* 蛇头 */
.snake > div:nth-child(1){
     
  width: 10px;
  height: 10px;
  background: #3c6382;
  border: 1px solid #808e9b;
  position: absolute;
  border-radius: 2px;
  left: 20px;
  top: 20px;
}
/* 食物 */
.food{
     
  width: 10px;
  height: 10px;
  background: #222f3e;
  border: 1px solid #808e9b;
  position: absolute;
  left: 120px;
  top: 100px;
  border-radius: 2px;
}

各类的具体分析与实现

我们最好将各类分成各个模块,这样好维护。

因为从分析来看,食物类和计分板类是最简单的两个类,所以先将它们实现

Food类

食物类包含了获取和设置食物位置,随机改变食物位置

  • 实现步骤

    1. 定义存放食物元素的变量
    2. 使用document.querySelector获取食物元素
    3. 使用offsetTopoffsetLeft获取食物的位置getset设置食物的位置
    4. 因为我们屏幕的有效长宽是290px,每次移动10px,所以我们只需要取0-29的随机数,最后再乘以10就行了。使用Math.randomMath.round实现随机取数
    5. 赋值给食物元素的样式
  • 具体代码

    // 定义食物类
    class Food{
           
      // 定义存储元素的变量
      private element: HTMLElement;
    
      constructor() {
           
        // 拿到元素
        this.element = document.querySelector(".food")!;
      }
    
      get X() {
           
        // 得到left值
        return this.element.offsetLeft;
      }
    
      get Y() {
           
        // 得到top值
        return this.element.offsetTop;
      }
    
      // 吃到一个事物改变位置
      change() {
           
        // 这里left和top需要分别拿,不然就只能走对角线了
        let left = Math.round(Math.random() * 29) * 10;
        let top = Math.round(Math.random() * 29) * 10;
        // 赋值给food实现随机改变位置
        this.element.style.left = left + 'px';
        this.element.style.top = top + 'px';
      }
    }
    
    export default Food;
    

    测试代码

    项目入口文件index.ts增加如下测试代码

    import Food from './modules/Food';
    
    const testFood = new Food();
    testFood.change();
    

    然后刷新多次页面查看食物随机改变的效果

TypeScript实战 -- 贪吃蛇游戏(1)--项目简介与具体实现、实现食物类和计分板类_第4张图片

Scoreboard类

包含了获取积分和等级,增加积分,增加等级的功能

  • 实现步骤

    1. 我们需要定义四个变量,存放等级level和积分score,等级显示元素和积分显示元素
    2. 如果还想自定义升级的规则和最大等级可以定义两个变量去控制
    3. 升级和积分增加都是先将现在的levelscore自增后往各自的元素的innerHTML添加即可
  • 具体代码

    // 定义记分牌
    class LevelScore{
           
      // 等级
      private level: number = 1;
      // 积分
      private score: number = 0;
      // 控制升级规则(每吃多少个升一级)
      private levelItem: number;
      // 最大等级
      private maxLevel: number;
    
      // 显示等级的元素
      private levelElement: HTMLElement;
      // 显示积分的元素
      private scoreElement: HTMLElement;
    
      // 给出初始值定义初始规则:吃10个食物升一级,最高等级10及
      constructor(leveItem: number = 10, maxLevel: number = 10) {
           
        this.levelItem = leveItem;
        this.maxLevel = maxLevel;
        this.levelElement = document.querySelector(".level")!;
        this.scoreElement = document.querySelector(".score")!;
      }
    
      // 增加积分
      addScore() {
           
        this.scoreElement.innerHTML = ++this.score + '';
        // 如果当前的积分和升级规则规定的个数取余为0,说明达到规定个数升级
        if (this.score % this.levelItem === 0) {
           
          this.levelUp();
        }
      }
    
      levelUp() {
           
        if (this.level < this.maxLevel) {
           
          this.levelElement.innerHTML = ++this.level + '';
        }
      }
      
      getlevel() {
           
        return this.level;
      }
      getScore() {
           
        return this.score;
      }
    }
    
    export default LevelScore;
    

测试代码

项目入口文件index.ts增加如下测试代码

import LevelScore from './modules/LevelScore'

const testLevelScore = new LevelScore();
setInterval(()=>{
     
  testLevelScore.addScore();
},1000)

查看页面对于我们增加分数和增加等级规则的测试

TypeScript实战 -- 贪吃蛇游戏(1)--项目简介与具体实现、实现食物类和计分板类_第5张图片

你可能感兴趣的:(TypeScript,typescript,游戏,贪吃蛇游戏,贪吃蛇)