typescript 做一个贪吃蛇小游戏

搭建环境

创建 tscofig.json 文件

配置如下

{"compilerOptions": {"target": "es2015","module": "es2015","strict": true,"outDir": "./dist","noEmitOnError": true}
}

创建 webpack.config.js 文件

  1. 安装 webpack

    npm i webpack webpack-cli -D
    
  2. 配置
    配置 webpack 项目工程化,配置项目运行打包,兼容,处理 .ts .css .less html 文件

  3. 安装插件

    npm i html-webpack-plugin webpack-dev-server -D
    
    webpack-dev-server 作用

    webpack 内部服务器,可以在开发阶段项目自动运行,比如修改了代码,会检测到改动并且自动运行,不需要每次都手动运行查看,利于开发效率

    html-webpack-plugin

    html 插件,可用来提供 html 模板,打包后的 dist 文件中的 html 会根据这个模板生成

配置如下

const path = require('path')
// html 插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const htmlPlugin = new HtmlWebpackPlugin({template: './src/index.html',filename: './index.html'
})module.exports = {mode: 'development',entry: './src/index.ts',output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js',environment: {// 兼容 IE ,禁止使用箭头函数arrowFunction: false,// 兼容 IE ,禁止使用es6语法const: false}},module: {rules: [{test: /\.ts$/,use: [// 配置babel{// 指定加载器loader: 'babel-loader',// 设置 babeloptions: {// 设置预定义环境presets: [[// 指定环境插件"@babel/preset-env",// 配置信息{// 要兼容的目标浏览器targets: {"chrome": "58"},// 指定 corejs 版本"corejs": "3",// 使用 corejs 的方式"usage"表示按需加载"useBuiltIns": "usage"}]]}}, 'ts-loader'],exclude: /node_modules/},{test: /\.less$/,use: ["style-loader","css-loader",// 引入 postcss {loader: "postcss-loader",options: {postcssOptions: {plugins: [["postcss-preset-env",{browsers: 'last 2 versions'}]]}}},"less-loader"]}]},plugins: [htmlPlugin],resolve: {extensions: ['.ts', '.js']}
}

创建 package.json 文件

在项目名称是英文的情况下使用

npm init -y

如果项目名称不是英文,使用如下命令,给它设置一个英文名称

npm init

安装项目所需的全部开发依赖,如下

配置就说这么多,下面开始项目代码

采用的是结构与数据分离

先布局基本样式
在项目根目录下创建 src 文件夹,在src 文件夹下创建 index.html 和 index.ts 文件

./src/index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>贪吃蛇</title>
</head><body><div class="box"><div class="top">// 蛇<div id="snake">// 蛇的每一节<div></div></div>// 食物<div id="food"></div></div>// 记分牌<div class="bottom"><div>SCORE:<span id="score">3</span></div><div>LEVEL:<span id="level">1</span></div></div></div>
</body></html>

在 src 目录下创建 style 文件夹存放样式文件 index.less

* {margin: 0;padding: 0;box-sizing: border-box;
}
body {font: bold 20px "Courier";
}.box {width: 360px;height: 420px;background-color: #b7d4a8;border: 10px solid #000;margin: 100px auto;border-radius: 20px;display: flex;flex-direction: column;align-items: center;justify-content: space-evenly;
}.top {width: 304px;height: 304px;border: 2px solid #000;position: relative;
}.bottom {width: 304px;display: flex;justify-content: space-between;
}#snake {position: relative;
}#snake div {width: 10px;height: 10px;background-color: black;border: 1px solid #b7d4a8;position: absolute;top: 0;left: 0;
}#food {width: 10px;height: 10px;background-color: black;position: absolute;border: 1px solid #b7d4a8;
}

在 index.ts 文件中引入样式

import './style/index.less'
  • 不要忘记安装 less


开始业务逻辑代码

在 src 文件下创建 modules 文件夹,存放每个类

Food.ts , 控制食物随机出现的位置

class Food {// 定义一个属性表示事物所对应的元素element: HTMLElementconstructor() {// !感叹号的意思是不用管this.element = document.getElementById('food')!}// 定义一个获取食物X轴坐标的方法get X() {return this.element.offsetLeft}// 定义一个获取食物Y轴坐标的方法get Y() {return this.element.offsetTop}// 修改十五位置的方法change() {// 生成一个随机数// 食物的位置最小时0,最大是290// Math.round(Math.random() * 29) * 10this.element.style.top = Math.round(Math.random() * 29) * 10 + 'px'this.element.style.left = Math.round(Math.random() * 29) * 10 + 'px'}
}// let food = new Food()
// food.change()
// console.log(food.X, food.Y)export default Food

创建 ScorePanel.ts,控制记分牌的变化

// 定义记分牌
class ScorePanel {// score, level 记录分数和等级score = 0level = 1// 分数和等级初始化scoreEle: HTMLElementlevelEle: HTMLElement// shezhibianliangmaxLevel: numbermaxScore: numberconstructor(maxLevel: number = 10, maxScore: number = 10) {this.scoreEle = document.getElementById('score')!this.levelEle = document.getElementById('level')!this.maxLevel = maxLevelthis.maxScore = maxScore}// 设置加分的方法addScore() {this.score++this.scoreEle.innerHTML = this.score + ''if (this.score % this.maxScore === 0) {this.levelUp()}}// 提升等级的方法levelUp() {if (this.level < this.maxLevel) {this.level++this.levelEle.innerHTML = this.level + ''}}
}export default ScorePanel

创建 Snake.ts,控制蛇的长度/位置/是否撞墙或者撞到自己

class Snake {// 表示蛇头的元素head: HTMLElement// 蛇的身体bodies: HTMLCollectionelement: HTMLElementconstructor() {this.element = document.getElementById('snake')!this.head = document.querySelector('#snake > div')!this.bodies = this.element.getElementsByTagName('div')}// 获取蛇的坐标get X() {return this.head.offsetLeft}get Y() {return this.head.offsetTop}// 设置蛇头的坐标set X(value: number) {if (this.X === value) return// 判断是否撞墙 X值的合法范围if (value < 0 || value > 290) {// 蛇撞墙了抛出异常throw new Error("蛇撞墙了");}// 修改水平座标蛇向右走不能往左走if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {// 如果发生了掉头让蛇继续移动if (value > this.X) {value = this.X -10} else {value = this.X + 10}}// 移动身体this.moveBody()this.head.style.left = value + 'px'// 检查有没有撞到自己this.checkHeadBody()}set Y(value: number) {if (this.Y === value) returnif (value < 0 || value > 290) {throw new Error("蛇撞墙了");}// 修改水平座标蛇向右走不能往左走if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {// 如果发生了掉头让蛇继续移动if (value > this.Y) {value = this.Y -10} else {value = this.Y + 10}}// 移动身体this.moveBody()this.head.style.top = value + 'px'// 检查有没有撞到自己this.checkHeadBody()}addBody() {this.element.insertAdjacentHTML('beforeend', '<div></div>')}moveBody() {// 从后往前改,将后面的身体设置位前面的身体位置// 遍历获取所有的身体for (let i = this.bodies.length - 1; i > 0; i--) {let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;(this.bodies[i] as HTMLElement).style.left = X + 'px';(this.bodies[i] as HTMLElement).style.top = Y + 'px';}}checkHeadBody() {for (let i = 1; i < this.bodies.length; i++){if (this.X === (this.bodies[i] as HTMLElement).offsetLeft && this.Y === (this.bodies[i] as HTMLElement).offsetTop) {throw new Error("撞到自己了");}}}
}export default Snake

创建 GameControl.ts,控制蛇的移动,把蛇、食物、记分牌联系到一块

import Snake from "./snake";
import Food from "./food";
import ScorePanel from "./ScorePanel";class GameControl {// 定义三个属性// 蛇snake: Snakefood: FoodscorePanel: ScorePanel// c创建一个属性来存储蛇的移动方向direction: string = 'Right'// 创建一个属性用来记录游戏是否结束isLive: boolean = trueconstructor() {this.snake = new Snake()this.food = new Food()this.scorePanel = new ScorePanel()this.init()}// 游戏初始化方法init() {// 绑定键盘事件// 修改this指向document.addEventListener('keydown', this.keydownHandler.bind(this))// 调用 run 方法this.run()}// 创建键盘按下的函数keydownHandler(e: KeyboardEvent) {// 修改 dirention 的值this.direction = e.key}// 创建控制蛇移动的方法run() {// 根据方向来改变蛇的位置// 获取蛇现在的坐标let X = this.snake.Xlet Y = this.snake.Yswitch (this.direction) {case "ArrowUp":case "Up":Y -= 10break;case "ArrowDown":case "Down":Y += 10break;case "ArrowRight":case "Right":X += 10break;case "ArrowLeft":case "Left":X -= 10break;default:break;}this.checkEat(X, Y)try {this.snake.X = Xthis.snake.Y = Y} catch (e) {alert(' OVER!')this.isLive = false}this.isLive && setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30);}// 定义一个方法判断吃到食物checkEat(X: Number, Y: number) {if (X === this.food.X && Y === this.food.Y) {this.food.change()this.scorePanel.addScore()this.snake.addBody()}}
}export default GameControl

在 src 下的 index.ts 中引入 GameControl 并且实例化,就可以运行代码

import GameControl from './modules/GameControl'new GameControl()

gitee 项目地址:
https://gitee.com/jinyang465/snake-demo

用 typescript 做一个贪吃蛇小游戏相关推荐

  1. Easyx图形库+C++做一个贪吃蛇小游戏 数据结构课程设计

    Easyx图形库+C++做一个贪吃蛇小游戏 数据结构课程设计 程序界面 ① 游戏开始界面(如下图): 显示游戏标题,提供"开始游戏"."游戏模式"和" ...

  2. 如何用python做一个贪吃蛇小游戏并给游戏加上背景音乐(pygame的应用)

    导入模块 import pygame import sys import time import random from pygame.locals import * 定义颜色变量 redColour ...

  3. 100行代码,使用 Pygame 制作一个贪吃蛇小游戏!

    作者 | 周萝卜 来源 | 萝卜大杂烩 相信我们大家都玩过贪吃蛇游戏,今天我们就从头一起来写一个贪吃蛇小游戏,只需要100多行的代码就完成了. 用到的 Pygame 函数 贪吃蛇小游戏用到的函数 功能 ...

  4. python小游戏编程实例-10分钟教你用Python写一个贪吃蛇小游戏,适合练手项目

    另外要注意:光理论是不够的.这里顺便总大家一套2020最新python入门到高级项目实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,还可以跟老司机交 ...

  5. python编程小游戏-10分钟用Python编写一个贪吃蛇小游戏,简单

    贪吃蛇,大家应该都玩过.小编当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最 ...

  6. 10分钟用python编写贪吃蛇小游戏_牛得一批!10分钟用Python编写一个贪吃蛇小游戏...

    贪吃蛇,大家应该都玩过.当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最主要 ...

  7. 10分钟python游戏_牛得一批!10分钟用Python编写一个贪吃蛇小游戏

    贪吃蛇,大家应该都玩过.当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最主要 ...

  8. scratch(图形化编程工具)做一个贪吃蛇的游戏(包含视频讲解+源码)!

    用scratch做一个贪吃蛇游戏! 下边上视频讲解: 代码部分,开始按钮: 开始界面文字动画: 结束页面文字动画: 蛇头代码: 蛇身代码: 食物代码: 好了,今天的教程就分享到这里吧. 本篇文章完整代 ...

  9. 用python写一个贪吃蛇小游戏

    好的,我们可以使用 Python 的 turtle 库来绘制贪吃蛇小游戏. 首先,我们需要导入 turtle 库: import turtle 然后,我们可以创建一个 Turtle 对象,并设置其速度 ...

最新文章

  1. php压缩文件 不能二次开发,PHP 'ZipArchive library is not enabled'异常的解决方法
  2. linux修改容器内的mysql端口映射_修改docker容器端口映射的方法
  3. BDB (Berkeley DB)数据库简单介绍(转载)
  4. html全局浮窗,Html 实现浮动窗口
  5. 管理学生信息android,Android 学生信息管理系统-Go语言中文社区
  6. SVN下载,安装,配置,常用操作 svn教程
  7. 限制文本框(TextBox)只能输入数字(VB6代码)
  8. #pragma 是什么
  9. php将xml转为array,php将xml数据转化为数组(array)
  10. PHP毕业设计源码带论文和答辩、大作业、实例程序源码下载合集【21套】
  11. 注册FaceBook和购买FaceBook小白号的区别
  12. datanucleus+spring 的JDO操作 select save update delete
  13. 2021年安徽省大数据与人工智能应用竞赛本科组(省赛)
  14. linux命令日志抓取,linux抓取某条日志记录的命令
  15. 手机录制的视频怎么旋转回来
  16. php 用count 变量,countif函数的使用方法 PHP的可变变量名的使用方法分享
  17. 使用ML.NET实现德州扑克牌型分类器
  18. 【U3D引擎】没有切换中文选项切换中文模式?
  19. 推荐一个可保存网页的social bookmarking工具Furl
  20. 跨境电商app应该如何开发?

热门文章

  1. CentOS7(8)安装/卸载MySQL
  2. html做出来发给别人链接,FINEBI仪表板的公共链接分享后,将分享的链接发给别人后无法在另外一台电脑上打开该链接网址。...
  3. 清华大学王观堂先生纪念碑铭----陈寅恪
  4. english book1 unit8
  5. Java实现获取long类型的随机数
  6. Unity3D项目升级URP
  7. 小程序 和 web 功能对比_小程序官方推出的Kbone,是如何解决Web 端和小程序同构痛点的?...
  8. Nginx通过OpenSSL创建自签名证书配置HTTPS及二级目录
  9. 苹果笔记本硬盘替换方案
  10. C#的HTTP协议中POST与GET的区别