AI智能
改变未来

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


TypeScript实战 – 贪吃蛇(1)

目的

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

界面


分析

总体来说,整个游戏中所含的类可以分为四个:蛇(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_pos20000tion"><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">0</span></div><div class="snake_body_item">grade:<span class="score">0</span></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. 使用
      document.querySelector

      获取食物元素

    2. 使用
      offsetTop

      offsetLeft

      获取食物的位置

      get

      set

      设置食物的位置

    3. 因为我们屏幕的有效长宽是290px,每次移动10px,所以我们只需要取0-29的随机数,最后再乘以10就行了。使用
      Math.random

      Math.round

      实现随机取数

    4. 赋值给食物元素的样式
  • 具体代码

    // 定义食物类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();

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

Scoreboard类

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

  • 实现步骤

      我们需要定义四个变量,存放等级

      level

      和积分

      score

      ,等级显示元素和积分显示元素

    1. 如果还想自定义升级的规则和最大等级可以定义两个变量去控制
    2. 升级和积分增加都是先将现在的
      level

      score

      自增后往各自的元素的

      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)

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

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » TypeScript实战 — 贪吃蛇游戏(1)–项目简介与具体实现、实现食物类和计分板类