您现在的位置是:网站首页> 编程资料编程资料

JavaScript TypeScript实现贪吃蛇游戏完整详细流程_javascript技巧_

2023-05-24 363人已围观

简介 JavaScript TypeScript实现贪吃蛇游戏完整详细流程_javascript技巧_

项目背景及简介

typescript系列到这篇文章正式进入尾声了,我们通过以上学习ts的知识,想要熟悉的掌握必须要写一个小demo综合运用所学的知识,这个项目的目的就是综合ts所学知识,实现面向对象的实际开发!

项目地址 : https://gitee.com/liuze_quan/ts-greedy-snake

多模块需求分析

场景模块需求

  1. 具有长和宽的容器,容器内分成蛇移动和记分牌两个板块
  2. 蛇移动的场景设置边界线,边界线一旦触碰直接结束游戏
  3. 记分牌记录蛇吃到食物的分数以及等级
  4. 蛇吃到食物分数涨一分,每涨一定分数等级提高一级
  5. 等级设有上限
  6. 等级和蛇移动速度有关

食物类模块需求

  1. 在游戏开始时候食物生成在随机位置
  2. 当蛇吃掉食物后食物会再次随机出现(出现的位置不能与蛇身重合)

记分牌模块需求

  1. 设置限制等级
  2. 可以提升等级
  3. 可以增加获取的分数

蛇类模块需求

  1. 游戏开始的时候只有一个方块(蛇头),随后每吃掉一个食物则增加一节身体
  2. 当游戏进行过程中蛇头碰到身体则结束游戏
  3. 蛇的前进是持续的,不能停顿下来,只能去改变方向

控制模块需求

  1. 按下方向键开始游戏
  2. 只能通过四个方向键改变蛇前进的方向
  3. 判断游戏是否结束,蛇是否吃到食物
  4. 控制分数和等级是否相应增长,食物是否刷新

项目搭建

ts转译为js代码

我们需要创建tsconfig.json文件,文件代码如下:

{ "compilerOptions": { "module": "es6", "target": "es6", "strict": true, "noEmitOnError": true } } 

package.json包配置文件

  1. 在这个小项目中我们需要webpack打包工具,所以我们要对package.json文件进行一些配置。
  2. 选择该项目在集成终端中打开并输入代码npm init -y进行项目初始化,这个时候会在你的项目中生成一个初步的package.json文件,然后我们进一步完善
  3. 在集成终端中输入指令npm i -D webpack webpack-cli typescript ts-loader用来下载相关依赖(如果可以看见package.json的depDependencies中更新了你下载的依赖表示下载成功)。i表示install下载的意思,-D意思是下载的作为依赖使用
  4. 继续输入指令npm i -D css-loader 等依赖,这些后面都有用
  5. 请注意上述代码中scripts中的"build": "webpack"键值对,这个设置说明我们可以用npm run build的代码来启用webpack打包工具
{ "name": "part2", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "start": "webpack serve --open" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.18.9", "@babel/preset-env": "^7.18.9", "babel-loader": "^8.2.5", "clean-webpack-plugin": "^4.0.0", "core-js": "^3.24.0", "css-loader": "^6.7.1", "html-webpack-plugin": "^5.5.0", "less": "^4.1.3", "less-loader": "^11.0.0", "postcss": "^8.4.14", "postcss-loader": "^7.0.1", "postcss-preset-env": "^7.7.2", "style-loader": "^3.3.1", "ts-loader": "^9.3.1", "typescript": "^4.7.4", "webpack": "^5.74.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.9.3" } }

webpack.config.js打包工具配置

webpack打包文件配置中,代码注释非常清楚,代码如下:

//引入一个包 const path = require('path'); //引入html插件 const HTMLWebpackPlugin = require('html-webpack-plugin') const { CleanWebpackPlugin } = require("clean-webpack-plugin"); // webpack 中所有的配置信息都写道吗module.exports中 module.exports = { //指定入口文件 entry: './src/index.ts', //指定打包文件所在的目录 output: { //指定打包文件的目录 path: path.resolve(__dirname,'dist'), //打包后文件的名字 filename: "bundle.js", //告诉webpack不使用箭头函数 environment: { arrowFunction: false } }, mode: 'development', //指定webpack打包时要使用的模块 module: { //指定要加载的规则 rules: [ { //test指定规则生成的文件 test: /\.ts$/, //要使用的loader use : [ //配置babel { // 指定加载器 loader: "babel-loader", //设置babel options: { //设置预定义的环境 presets:[ [ //指定环境的插件 "@babel/preset-env", //配置信息 { //要兼容的目标浏览器 targets : { "chrome" : "101" }, //指定core.js的版本 "corejs":"3", //使用core.js的方式 usage 按需加载 "useBuiltIns": "usage" } ] ] } } , 'ts-loader' ], //要排除的文件 exclude: /node-modules/ }, //设置less文件的处理 { test : /\.less$/, use : [ "style-loader", "css-loader", //引入postcss { loader: "postcss-loader", options: { postcssOptions : { plugins: [ [ "postcss-preset-env", { browsers:'last 2 versions' } ] ] } } }, "less-loader" ] } ] }, //配置webpack插件 plugins: [ new CleanWebpackPlugin(), new HTMLWebpackPlugin({ // title: "自定义的title" template: "./src/index.html" }), ], //用来设置引用模块 resolve: { extensions: ['.ts', '.js'] } } 

到这里,我们要配置的文件都已经配置结束,接下来正式进入项目的开发

项目结构搭建

首先要进行我们的html和css样式搭建,搭建出来项目的页面!

html文件

贪吃蛇
SCORE:0
level:1

css文件(这里使用的是less)

// 设置变量 @bg-color: #b7d4a8; //清除默认样式 * { margin: 0; padding: 0; //改变盒子模型的计算方式 box-sizing: border-box; } body{ font: bold 20px "Courier"; } //设置主窗口的样式 #main{ width: 360px; height: 420px; // 设置背景颜色 background-color: @bg-color; // 设置居中 margin: 100px auto; border: 10px solid black; // 设置圆角 border-radius: 40px; // 开启弹性盒模型 display: flex; // 设置主轴的方向 flex-flow: column; // 设置侧轴的对齐方式 align-items: center; // 设置主轴的对齐方式 justify-content: space-around; // 游戏舞台 #stage{ width: 304px; height: 304px; border: 2px solid black; // 开启相对定位 position: relative; // 设置蛇的样式 #snake{ &>div{ width: 10px; height: 10px; background-color: #000; border: 1px solid @bg-color; // 开启绝对定位 position: absolute; } } // 设置食物 #food{ width: 10px; height: 10px; position: absolute; left: 40px; top: 100px; // 开启弹性盒 display: flex; // 设置横轴为主轴,wrap表示会自动换行 flex-flow: row wrap; // 设置主轴和侧轴的空白空间分配到元素之间 justify-content: space-between; align-content: space-between; &>div{ width: 4px; height: 4px; background-color: black; // 使四个div旋转45度 transform: rotate(45deg); } } } // 记分牌 #score-panel{ width: 300px; display: flex; // 设置主轴的对齐方式 justify-content: space-between; } }

项目页面

多模块搭建

在项目开发中我们不可能把所有的代码写到一个文件中,所以项目开发必须会灵活运用模块化开发思想,把实现的功能细化成一个个模块。

完成Food(食物)类

//定义食物类 class Food { element : HTMLElement; constructor() { //获取页面中的food元素并赋给element this.element = document.getElementById('food')!; } //获取食物x轴坐标的方法 get X() { return this.element.offsetLeft; } //获取食物y轴坐标的方法 get Y() { return this.element.offsetTop; } //修改食物位置的方法 change() { //生成随机位置 //食物的最小位置是0 最大是290 let left = Math.round(Math.random() * 29) * 10 let top = Math.round(Math.random() * 29) * 10 this.element.style.left = left + 'px'; this.element.style.top = top + 'px'; } } export default Food

代码分析:

由于在配置typescript时我们设置了strict(严格)模式,因此

  1. this.element = document.getElementById('food')!中如果我们不加!会让编译器不确定我们是否会获取到food的dom元素而发生报错
  2. 准备了get()方法可以在控制模块中随时获取food的具体定位
  3. change()方法为随机刷新一次food的位置
  4. export default Food 代码加在最后。为的是把food成为全局模块暴露出去,这样的话其他的模块可以调用这个food模块

完成ScorePanel(记分牌)类

//定义表示记分牌的类 class ScorePanel { score : number = 0; level : number = 1; scoreSpan :HTMLElement; levelEle : HTMLElement; //设置变量限制等级 maxLevel : number; //设置一个变量多少分升级 upScore : number; constructor(maxLevel : number = 10,Score : number = 10) { this.scoreSpan = document.getElementById('score')!; this.levelEle = document.getElementById('level')!; this.maxLevel = maxLevel this.upScore = Score } //设置加分的方法 AddScore() { this.score++; this.scoreSpan.innerHTML = this.score + '' if (this.score % this.upScore === 0 ) { this.AddLevel() } } //提升等级 AddLevel() { if (this.level < this.maxLevel) { this.levelEle.innerHTML = ++this.level +'' } } } export default ScorePanel

代码分析:

在记分牌模块主要是两种方法AddScore()AddLevel(),分别用来控制分数增加和等级提升,重点也有设置一个变量来限制等级和设置变量来判断多少分上升一个等级

完成Snake(蛇)类

class Snake { //表示蛇头的元素 head : HTMLElement; bodies : HTMLCollectionOf; //获取蛇的容器 element : HTMLElement; constructor() { this.element = 
                
                

-六神源码网