当前位置:   article > 正文

TS项目(贪吃蛇)

ts项目

1. 项目搭建配置

  1. // webpack.config.js tsconfig.json package.json配置代码
  2. // 1. package.json
  3. {
  4. "name": "part5",
  5. "version": "1.0.0",
  6. "description": "",
  7. "main": "index.js",
  8. "scripts": {
  9. "test": "echo \"Error: no test specified\" && exit 1",
  10. "build": "webpack --mode development",
  11. "start": "webpack serve --open --mode development"
  12. },
  13. "keywords": [],
  14. "author": "",
  15. "license": "ISC",
  16. "devDependencies": {
  17. "@babel/core": "^7.18.13",
  18. "@babel/preset-env": "^7.18.10",
  19. "babel-loader": "^8.2.5",
  20. "clean-webpack-plugin": "^4.0.0",
  21. "core-js": "^3.25.0",
  22. "html-webpack-plugin": "^5.5.0",
  23. "ts-loader": "^9.3.1",
  24. "typescript": "^4.8.2",
  25. "webpack": "^5.74.0",
  26. "webpack-cli": "^4.10.0",
  27. "webpack-dev-server": "^4.10.1"
  28. }
  29. }
  30. // 2. tsconfig.json
  31. {
  32. "compilerOptions": {
  33. "module": "ES2015",
  34. "target": "ES2015",
  35. "strict": true,
  36. "noEmitOnError": true
  37. }
  38. }
  39. // 3 .webpack.config.js
  40. // 引入一个包
  41. const path = require('path');
  42. // 引入html插件
  43. const HTMLWebpackPlugin = require('html-webpack-plugin');
  44. // 引入clean插件
  45. const {CleanWebpackPlugin} = require('clean-webpack-plugin');
  46. // webpack中的所有配置信息都应该写在module.exports中
  47. module.exports = {
  48. // 指定入口文件
  49. entry: "./src/index.ts",
  50. // 指定打包文件所在目录
  51. output: {
  52. // 指定打包的目录
  53. path: path.resolve(__dirname, 'dist'),
  54. // 打包后的文件
  55. filename: "bundle.js",
  56. // 告诉webpack不使用箭头函数
  57. environment: {
  58. arrowFunction: false
  59. }
  60. },
  61. // 指定webpack打包时要使用模块
  62. module: {
  63. // 指定要加载的规则
  64. rules: [
  65. {
  66. // test指定的是规则生效的文件
  67. test: /\.ts$/,
  68. // 要使用的loader
  69. use: [
  70. // 配置babel
  71. {
  72. // 指定加载器
  73. loader: "babel-loader",
  74. // 设置babel
  75. options: {
  76. // 设置预定义的环境
  77. presets: [
  78. [
  79. // 指定环境的插件
  80. "@babel/preset-env",
  81. // 配置信息
  82. {
  83. // 要兼容的目标浏览器
  84. targets: {
  85. "chrome": "88"
  86. },
  87. // 指定corejs版本
  88. "corejs": "3",
  89. // 使用codejs的方式:usage表示按需加载
  90. "useBuiltIns": "usage"
  91. }
  92. ]
  93. ]
  94. }
  95. },
  96. 'ts-loader' // 后面的先执行
  97. ],
  98. // 要排除的文件
  99. exclude: /node_modules/
  100. },
  101. // 设置less文件的处理
  102. {
  103. test: /\.less$/,
  104. use: [ // 从下往上执行,先less 后css 最后style
  105. "style-loader",
  106. // 引入postcss
  107. {
  108. loader: "postcss-loader",
  109. options: {
  110. postcssOptions: {
  111. plugins: [
  112. [
  113. "postcss-preset-env",
  114. {
  115. // 兼容最新的2个浏览器
  116. browsers: 'last 2 versions'
  117. }
  118. ]
  119. ]
  120. }
  121. }
  122. },
  123. "css-loader",
  124. "less-loader"
  125. ]
  126. }
  127. ]
  128. },
  129. // 配置webpack插件
  130. plugins: [
  131. new CleanWebpackPlugin(),
  132. new HTMLWebpackPlugin({
  133. // title: "这是一个自定义的title"
  134. template: "./src/index.html"
  135. })
  136. ],
  137. // 用来设置引用模块, 告诉它凡是以js,ts结尾都是可以使用模块化
  138. resolve: {
  139. extensions: ['.ts', '.js']
  140. }
  141. };

2. 创建part5文件夹

  1. // 创建part文件夹, 将上方三个配置放置part文件夹下方,然后使用npm i安装依赖
  2. // 在part文件夹下创建src,src下创建index.html和index.ts, 然后使用npm run build打包
  3. // 安装less,npm i -D less less-loader css-loader style-loader
  4. // webpack配置完less后,直接npm start运行项目
  5. // 在src下创建style文件夹,style下创建index.less
  6. body {
  7. background: 'red';
  8. }
  9. //index.ts 引入样式, 然后就可以检测页面是否生效
  10. import './style/index.less';
  11. // 继续安装依赖, 然后在webpack配置
  12. npm i -D postcss postcss-loader postcss-preset-env

3. 贪吃蛇ts代码(本例子只填写关于ts,html和css在这不做笔记)

  1. // 定义类
  2. class Food {
  3. // 定义一个属性表示食物所对应的元素
  4. element: HTMLElement;
  5. constructor () {
  6. // 后面不加!会报错,因为document.getElementById('food')可能为空,后面加!表示一定不会为空
  7. this.element = document.getElementById('food')!;
  8. }
  9. // 定义一个获取食物X轴坐标的方法
  10. get X () {
  11. return this.element.offsetLeft;
  12. }
  13. get Y () {
  14. return this.element.offsetTop;
  15. }
  16. // 修改食物的位置
  17. change () {
  18. // 生成一个随机的位置
  19. // 食物的位置最小是0最大是290
  20. // 蛇移动一次就是一格,一格的大小就是10,所以食物的坐标必须是整10
  21. // Math.random(Math.random() * 29); 0-29
  22. const top = Math.round(Math.random() * 29) * 10;
  23. const left = Math.round(Math.random() * 29) * 10;
  24. this.element.style.left = left + 'px';
  25. this.element.style.top = top + 'px';
  26. }
  27. }
  28. // 测试代码
  29. // const food = new Food();
  30. // console.log(food.X, food.Y); // 40 100
  31. // food.change();
  32. // console.log(food.X, food.Y); // 80 180
  33. // 定义表示记分牌的类
  34. class ScorePanel {
  35. // score和level用来记录分数和等级
  36. score = 0;
  37. level = 1;
  38. // 分数和等级所在的元素, 在构造函数中进行初始化
  39. scoreEle: HTMLElement;
  40. levelEle: HTMLElement;
  41. // 设置一格变量限制等级
  42. maxLevel: number;
  43. // 设置一个变量表示多少分时升级
  44. upScore: number
  45. constructor (maxLevel: number = 10, upScore: number = 10) {
  46. this.scoreEle = document.getElementById('score')!;
  47. this.levelEle = document.getElementById('level')!;
  48. this.maxLevel = maxLevel;
  49. this.upScore = upScore;
  50. }
  51. // 设置一个加分的方法
  52. addScore () {
  53. // 分数自增
  54. this.score++;
  55. this.scoreEle.innerHTML = this.score + '';
  56. if (this.score % this.upScore === 0) {
  57. this.levelUp();
  58. }
  59. }
  60. // 提升等级的方法
  61. levelUp() {
  62. if (this.level < this.maxLevel) {
  63. this.levelEle.innerHTML = ++this.level + '';
  64. }
  65. }
  66. }
  67. // 测试
  68. const scorePanel = new ScorePanel();
  69. scorePanel.addScore();
  70. // 蛇的类
  71. class Snack {
  72. // 表示蛇头的元素
  73. head: HTMLElement;
  74. // 蛇的身体(包括蛇头)
  75. bodies: HTMLCollection;
  76. // 获取蛇的容器
  77. element: HTMLElement;
  78. constructor () {
  79. this.element = document.getElementById('snack')!;
  80. this.head = document.querySelector('#snack > div')! as HTMLElement;
  81. this.bodies = document.getElementById('snack')!.getElementsByTagName('div');
  82. }
  83. // 获取蛇的坐标(蛇头)
  84. get X () {
  85. return this.head.offsetLeft;
  86. }
  87. // 获取蛇的Y轴坐标
  88. get Y() {
  89. return this.head.offsetTop;
  90. }
  91. set X (value: number) {
  92. // 如果新值和旧值相同,则直接返回,不再修改
  93. if (this.X === value) {
  94. return;
  95. }
  96. // X的值的合法范围0-290之间
  97. if (value < 0 || value > 290) {
  98. // 进入判断,说明蛇撞墙了, 抛出一个异常
  99. throw new Error('蛇撞墙了');
  100. }
  101. this.head.style.left = value + 'px';
  102. }
  103. set Y (value: number) {
  104. // 如果新值和旧值相同,则直接返回,不再修改
  105. if (this.Y === value) {
  106. return;
  107. }
  108. // Y的值的合法范围0-290之间
  109. if (value < 0 || value > 290) {
  110. // 进入判断,说明蛇撞墙了, 抛出一个异常
  111. throw new Error('蛇撞墙了');
  112. }
  113. this.head.style.top = value + 'px';
  114. }
  115. // 蛇增加身体的方法
  116. addBody() {
  117. // 向element中添加一个div
  118. this.element.insertAdjacentHTML('afterend', "<div></div>");
  119. }
  120. }
  121. // 游戏控制器, 控制其他的所有类
  122. class gameControl {
  123. // 定义三个属性
  124. //
  125. snack: Snack;
  126. // 食物
  127. food: Food;
  128. // 记分牌
  129. scorePanel: ScorePanel;
  130. // 创建一个属性来存储蛇的移动方向
  131. direction: string = '';
  132. // 创建一个属性用来记录游戏是否结束
  133. isLive = true;
  134. constructor () {
  135. this.snack = new Snack();
  136. this.food = new Food;
  137. this.scorePanel = new ScorePanel;
  138. this.init();
  139. }
  140. // 游戏初始化方法, 调用后游戏即开始
  141. init () {
  142. // 绑定键盘按键按下的事件
  143. document.addEventListener('keydown', this.keyDownHandler.bind(this));
  144. // 调用init方法
  145. this.run();
  146. }
  147. // 创建一个键盘按下的响应函数
  148. keyDownHandler = (event: KeyboardEvent) => {
  149. // chrome IE
  150. // ArrowUp up
  151. // ArrowDown down
  152. // ArrowLeft left
  153. // ArrowRight right
  154. // 在IE和Chrome值不一样
  155. // console.log(event.key);
  156. // 需要检查值是否合法(用户是否按了正确的按键)
  157. this.direction = event.key;
  158. }
  159. // 创建一个控制蛇移动的方法
  160. run () {
  161. // 根据方向(this.direction)来使蛇的位置改变
  162. /**
  163. * 向上 top减少
  164. * 向下 top增加
  165. * 向左 left减少
  166. * 向右 left增加
  167. */
  168. // 获取蛇现在的坐标
  169. let X = this.snack.X;
  170. let Y = this.snack.Y;
  171. // 根据按键方向来修改X值和Y值
  172. switch (this.direction) {
  173. case 'ArrowUp':
  174. case 'up':
  175. // 向上移动 top减少
  176. Y -= 10;
  177. break;
  178. case 'ArrowDown':
  179. case 'down':
  180. // 向下移动 top增加
  181. Y += 10;
  182. break;
  183. case 'ArrowLeft':
  184. case 'left':
  185. // 向左移动 left减少
  186. X -= 10;
  187. break;
  188. case 'ArrowRight':
  189. case 'right':
  190. X += 10;
  191. // 向右移动 left增加
  192. break;
  193. }
  194. // 检查蛇是否迟到了食物
  195. this.checkEat(X, Y);
  196. // 修改蛇的X和Y值
  197. try {
  198. // 修改蛇的X和Y值
  199. this.snack.X = X;
  200. this.snack.Y = Y;
  201. } catch (error) {
  202. // 进入catch 说明出现了异常,游戏结束,弹出一个提示信息
  203. alert((error as Error).message);
  204. this.isLive = false;
  205. }
  206. // 开启一个定时调用
  207. this.isLive && setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30);
  208. }
  209. // 定义一个方法,用来检查蛇是否吃到食物
  210. checkEat (X: number, Y: number) {
  211. if (X === this.food.X && Y === this.food.Y) {
  212. // 食物的位置要进行重置
  213. this.food.change();
  214. // 分数增加
  215. this.scorePanel.addScore();
  216. // 蛇增加一节
  217. this.snack.addBody();
  218. }
  219. }
  220. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/1015135
推荐阅读
相关标签
  

闽ICP备14008679号