【ts + webpack】贪吃蛇小游戏

news2024/12/28 4:14:31

目录

 一、项目搭建

1.1 初始化项目

二、项目界面布局

三、完成Food类

四、完成记分牌类

五、初步完成snake类

六、创建游戏控制器类 - 键盘事件

七、GameControl - 使蛇移动

八、蛇撞墙和吃食检测


 一、项目搭建

1.1 初始化项目

1.使用init命令生成package.json文件

npm init -y

2.在根目录创建src文件夹、tsconfig.json文件、weboack.config.js文件

3.在src文件夹下创建index.ts、index.html、style文件夹、module文件夹

4.在style文件夹内创建index.less文件

5.运行以下命令,安装所需的18个依赖

npm i webpack webpack-cli webpack-server typescript ts-loader style-loader less-loader less css-loader postcss postcss-loader postcss-preset-env core-js html-webpack-plugin clean-webpack-plugin babel-loader @babel/preset-env @babel/core -D

安装完毕后,你的文件结构应该是这样


 安装依赖说明


 6.配置package.json

在"script"对象中,添加如下命令

"build": "webpack",
"start": "webpack server --open"

7.配置tsconfig.json

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

8.配置webpack.config.js

// 引入一个包
const path = require("path")
// 引入hmtl插件
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")

module.exports = {
  entry: "./src/index.ts",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",

    // 告诉webpack不适用箭头函数
    environment: {
      arrowFunction: false,
      const: false,
    },
  },
  mode: 'development' ,
  // 指定webpack打包时使用的模块
  module: {
    // 指定要加载的规则
    rules: [
      {
        // test指定规则生效的文件
        test: /\.ts$/,
        use: [
          // 配置babel
          {
            // 指定加载器
            loader: "babel-loader",
            // 设置babel
            options: {
              // 设置定义的环境
              presets: [
                [
                  "@babel/preset-env",
                  {
                    // 要兼容的目标浏览器
                    targets: {
                      browsers: ["last 2 versions"],
                      ie: 11,
                    },
                    // 指定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",
        ],
      },
    ],
  },

  // 配置webpack插件
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: "./src/index.html",
      filename: "index.html",
    }),
  ],

  // 用来设置模块
  resolve: {
    extensions: [".ts", ".js"],
  },
}

二、项目界面布局

1.打开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 id="main">
    <!-- 设置游戏的舞台 -->
    <div id="stage">
      <!-- 设置蛇 -->
      <div id="snake">
        <!-- snake内部的div  表示蛇的各部分 -->
        <div></div>
      </div>

      <!-- 设置食物 -->
      <div id="food">
        <!-- 添加4个div 设置food的样式 -->
        <div></div>
        <div></div>
        <div></div>
        <div></div>
      </div>
    </div>

    <!-- 设置游戏的记分牌 -->
    <div id="score-panel">
      <div>SCORE: <span id="score">0</span></div>
      <div>LEVEL: <span id="level">1</span></div>
    </div>
  </div>
</body>
</html>

2.在index.ts中引入index.less

三、完成Food类

1.在modules文件夹中创建Food.ts文件

2.定义获取食物的x,y坐标的方法,修改食物的位置方法等

// 定义食物类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
    // 蛇移动一次就是一格,一格的大小就是10,所以就要求食物的位置必须是10的倍数

    let top = Math.round(Math.random() * 29) * 10;
    let left = Math.round(Math.random() * 29) * 10;

    this.element.style.left = left + "px";
    this.element.style.top = top + "px";
  }
}

export default Food;

四、完成记分牌类

1.在modules文件夹下创建ScorePanel.ts文件

2.定义属性:分数、等级、最大等级以及升级所需分数

3.定义方法:加分方法、提升等级方法

// 定义表示记分牌的类
class ScorePanel {
  // score和level用来记录分数和等级
  score: number = 0;
  level: number = 1;

  // 分数和等级所在的元素,在构造函数中进行初始化
  scoreEle: HTMLElement;
  levelEle: HTMLElement;

  // 设置变量限制等级
  maxLevel: number;
  // 设置变量表示多少分升级
  upScore: number;

  constructor(maxLevel: number = 10, upScore: number = 10) {
    this.scoreEle = document.getElementById("score")!;
    this.levelEle = document.getElementById("level")!;
    this.maxLevel = maxLevel;
    this.upScore = upScore;
  }

  // 设置一个加分的方法
  addScore() {
    this.scoreEle.innerHTML = ++this.score + "";
    // 判断分数是多少
    if (this.score % this.upScore === 0) {
      this.levelUp();
    }
  }

  // 提升等级的方法
  levelUp() {
    if (this.level < this.maxLevel) this.levelEle.innerHTML = ++this.level + "";
  }
}

export default ScorePanel;

五、初步完成snake类

1.在modules文件夹中创建Snake.ts文件

2.定义属性:蛇头、蛇的身体

3.定义方法:获取蛇的x,y坐标方法、设置x,y坐标的方法,蛇的身体增加的方法

class Snake {
  // 表示蛇头的元素
  hand: HTMLElement;
  // 蛇的身体(包括舌头)
  bodies: HTMLCollection;
  // 获取蛇的容器
  element: HTMLElement;

  constructor() {
    this.element = document.getElementById("snake")!;
    this.hand = document.querySelector("#snake > div")!;
    this.bodies = this.element.getElementsByTagName("div")!;
  }

  // 获取蛇的x坐标
  get X() {
    return this.hand.offsetLeft;
  }
  // 获取蛇的y坐标
  get Y() {
    return this.hand.offsetTop;
  }

  set X(value) {
    this.hand.style.left = `${value}px`;
  }

  set Y(value) {
    this.hand.style.top = `${value}px`;
  }

  // 蛇增加身体的方法
  addBody() {
    // 向element中添加一个div
    this.element.insertAdjacentHTML("beforeend", "<div></div>");
  }

}

export default Snake;

六、创建游戏控制器类 - 键盘事件

1.在modules文件夹中创建GameControl.ts文件

2.引入其他3个文件

3.定义属性:蛇、食物、记分牌、移动方向

4.定义方法:游戏初始化、键盘按下事件

// 引入其他类
import Snake from "./Snake";
import Food from "./Food";
import ScorePanel from "./ScorePanel";

// 游戏控制器,控制其他的所有类
class GameControl {
  // 定义三个属性
  // 蛇
  snake: Snake;
  food: Food;
  scorePanel: ScorePanel;

  // 创建一个属性来存储蛇的移动方向(也就是按键的方向)
  direction: string = "";

  constructor() {
    this.snake = new Snake();
    this.food = new Food();
    this.scorePanel = new ScorePanel();

    this.init();
  }

  // 游戏初始化方法,调用后游戏即开始
  init() {
    // 绑定键盘按下事件
    document.addEventListener("keydown", this.keydownHandle.bind(this));
  }

  /*
  Chrome           IE
  ArrowUp          Up
  ArrowDown       Down
  ArrowLeft       Left
  ArrowRight      Right
  */

  // 创建一个键盘按下的相应函数
  keydownHandle(event: KeyboardEvent) {
    // 修改direction属性
    this.direction = event.key;
  }
}

export default GameControl;

七、GameControl - 使蛇移动

1.创建方法:使蛇移动

// 创建一个控制蛇移动的方法
  run() {
    /* 根据方向(this.direction)来使蛇的位置改变
      向上 top 减少
      向下 top 增加
      向左 left 减少
      向右 left 增加
    */

    // 获取蛇现在的坐标
    let x: number = this.snake.X;
    let y: number = this.snake.Y;

    // 根据舍得方向计算坐标值
    switch (this.direction) {
      case "ArrowUp":
      case "Up":
      case "w":
      case "W":
        // 向上移动  top 减少
        y -= 10;
        break;
      case "ArrowDown":
      case "Down":
      case "s":
      case "S":
        // 向下移动 top 增加
        y += 10;
        break;
      case "ArrowLeft":
      case "Left":
      case "a":
      case "A":
        // 向左移动 left 减少
        x -= 10;
        break;
      case "ArrowRight":
      case "Right":
      case "d":
      case "D":
        // 向右移动 right 增加
        x += 10;
        break;
    }

    // 修改蛇的位置
      this.snake.X = x;
      this.snake.Y = y;

}

2.在index.ts中引入GameControl文件,并new GameControl()调用

// 引入样式
import "./style/index.less";

import GameControl from "./modules/GameControl";

new GameControl();

3.此时我们的蛇已经可以移动了,但是它不是实时移动的,接下来我们添加定时调用方法

setTimeout(this.run.bind(this), 300);

 4.接下来完成一些逻辑补充,创建一个变量用来检测蛇是不是还活着


  // 创建一个属性用来记录游戏是否结束
  isLive: boolean = true;

八、蛇撞墙和吃食检测

1.修改Snake.ts中set x和 set y 的内容

set X(value) {
    // 如果新值和旧值相同,则直接返回不再修改
    if (this.X === value) return;
    // x的值的合法范围0-290之间
    if (value < 0 || value > 290) {
      // 进入判断说明蛇撞墙了,抛出一个异常
      throw new Error("蛇撞墙了");
    }
    this.hand.style.left = `${value}px`;
  }

  set Y(value) {
    // 如果新值和旧值相同,则直接返回不再修改
    if (this.Y === value) return;
    // x的值的合法范围0-290之间
    if (value < 0 || value > 290) {
      // 进入判断说明蛇撞墙了,抛出一个异常
      throw new Error("蛇撞墙了!");
    }
    this.hand.style.top = `${value}px`;
  }

 2.在GameControl中添加异常捕获

// 使用异常捕获来处理所有的游戏结束事件,减少代码
    try {
      // 修改蛇的位置
      this.snake.X = x;
      this.snake.Y = y;
    } catch (e: any) {
      // 进入到catch,说明出现了异常,游戏结束,弹出一个提示信息
      alert(e.message + "GAME OVER,请刷新页面后重新开始游戏");
      // 将isLive设置为false
      this.isLive = false;
    }

3. 此时我们控制蛇撞墙就会弹窗,但是我们的蛇还能掉头,接下来我们处理这个问题

4.打开Snake文件,增加set x 和 set y 的逻辑

set X(value) {
    // 如果新值和旧值相同,则直接返回不再修改
    if (this.X === value) return;

    // x的值的合法范围0-290之间
    if (value < 0 || value > 290) {
      // 进入判断说明蛇撞墙了,抛出一个异常
      throw new Error("蛇撞墙了");
    }
    // 修改x时,是在修改水平坐标,蛇在左右移动,蛇在向左移动时,不能向右掉头,反之亦然
    if (
      this.bodies[1] &&
      (this.bodies[1] as HTMLElement).offsetLeft === value
    ) {
      // 如果发生了掉头,让蛇向反方向继续移动
      if (value > this.X) {
        // 如果新值value大于旧值x,则说明蛇在向右走,此时发生掉头,应该使蛇继续向左走
        value = this.X - 10;
      } else {
        value = this.X + 10;
      }
    }
    this.hand.style.left = `${value}px`;
  }

  set Y(value) {
    // 如果新值和旧值相同,则直接返回不再修改
    if (this.Y === value) return;
    // x的值的合法范围0-290之间
    if (value < 0 || value > 290) {
      // 进入判断说明蛇撞墙了,抛出一个异常
      throw new Error("蛇撞墙了!");
    }

    // 修改y时,是在修改垂直坐标,蛇在上下移动,蛇在向上移动时,不能向下掉头,反之亦然
    if (
      this.bodies[1] &&
      (this.bodies[1] as HTMLElement).offsetLeft === value
    ) {
      // 如果发生了掉头,让蛇向反方向继续移动
      if (value < this.Y) {
        // 如果新值value大于旧值y,则说明蛇在向上走,此时发生掉头,应该使蛇继续向下走
        value = this.Y - 10;
      } else {
        value = this.Y + 10;
      }
    }
    this.hand.style.top = `${value}px`;
  }

5.此时我们掉头蛇就不会掉头了,接下来我们处理我们的蛇的身体

// 添加一个蛇身体移动的方法
  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`;
    }
  }

6.在set x,set y中调用moveBody方法

7.现在我们发现我么的蛇还能够穿过自己的身体,接下来我们处理这个问题

// 检查蛇头是否撞到身体的方法
  checkHeadBody() {
    // 获取所有的身体,检查其是否和蛇头的坐标发生重叠
    for (let i = 1; i < this.bodies.length; i++) {
      let bd = this.bodies[i] as HTMLElement;
      console.log(this.X, bd.offsetLeft, this.Y, bd.offsetTop);

      if (this.X === bd.offsetLeft && this.Y === bd.offsetTop) {
        // 进入判断说明蛇头撞到了身体,游戏结束
        throw new Error("撞到自己了!");
      }
    }
  }

8.在set x,set y中调用checkHeadBody方法

9.完整Snake文件

class Snake {
  // 表示蛇头的元素
  hand: HTMLElement;
  // 蛇的身体(包括舌头)
  bodies: HTMLCollection;
  // 获取蛇的容器
  element: HTMLElement;

  constructor() {
    this.element = document.getElementById("snake")!;
    this.hand = document.querySelector("#snake > div")!;
    this.bodies = this.element.getElementsByTagName("div")!;
  }

  // 获取蛇的x坐标
  get X() {
    return this.hand.offsetLeft;
  }
  // 获取蛇的y坐标
  get Y() {
    return this.hand.offsetTop;
  }

  set X(value) {
    // 如果新值和旧值相同,则直接返回不再修改
    if (this.X === value) return;

    // x的值的合法范围0-290之间
    if (value < 0 || value > 290) {
      // 进入判断说明蛇撞墙了,抛出一个异常
      throw new Error("蛇撞墙了");
    }

    // 修改x时,是在修改水平坐标,蛇在左右移动,蛇在向左移动时,不能向右掉头,反之亦然
    if (
      this.bodies[1] &&
      (this.bodies[1] as HTMLElement).offsetLeft === value
    ) {
      // 如果发生了掉头,让蛇向反方向继续移动
      if (value > this.X) {
        // 如果新值value大于旧值x,则说明蛇在向右走,此时发生掉头,应该使蛇继续向左走
        value = this.X - 10;
      } else {
        value = this.X + 10;
      }
    }

    // 移动的时候调用身体方法
    this.moveBody();

    this.hand.style.left = `${value}px`;
    // 检查有没有撞到自己
    this.checkHeadBody();
  }

  set Y(value) {
    // 如果新值和旧值相同,则直接返回不再修改
    if (this.Y === value) return;
    // x的值的合法范围0-290之间
    if (value < 0 || value > 290) {
      // 进入判断说明蛇撞墙了,抛出一个异常
      throw new Error("蛇撞墙了!");
    }

    // 修改y时,是在修改垂直坐标,蛇在上下移动,蛇在向上移动时,不能向下掉头,反之亦然
    if (
      this.bodies[1] &&
      (this.bodies[1] as HTMLElement).offsetLeft === value
    ) {
      // 如果发生了掉头,让蛇向反方向继续移动
      if (value < this.Y) {
        // 如果新值value大于旧值y,则说明蛇在向上走,此时发生掉头,应该使蛇继续向左走
        value = this.Y - 10;
      } else {
        value = this.Y + 10;
      }
    }

    // 移动的时候调用身体方法
    this.moveBody();

    this.hand.style.top = `${value}px`;
    // 检查有没有撞到自己
    this.checkHeadBody();
  }

  // 蛇增加身体的方法
  addBody() {
    // 向element中添加一个div
    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++) {
      let bd = this.bodies[i] as HTMLElement;
      console.log(this.X, bd.offsetLeft, this.Y, bd.offsetTop);

      if (this.X === bd.offsetLeft && this.Y === bd.offsetTop) {
        // 进入判断说明蛇头撞到了身体,游戏结束
        throw new Error("撞到自己了!");
      }
    }
  }
}

export default Snake;

10.完整GameControl文件

// 引入其他类
import Snake from "./Snake";
import Food from "./Food";
import ScorePanel from "./ScorePanel";

// 游戏控制器,控制其他的所有类
class GameControl {
  // 定义三个属性
  // 蛇
  snake: Snake;
  food: Food;
  scorePanel: ScorePanel;

  // 创建一个属性来存储蛇的移动方向(也就是按键的方向)
  direction: string = "";
  // 创建一个属性用来记录游戏是否结束
  isLive: boolean = true;

  constructor() {
    this.snake = new Snake();
    this.food = new Food();
    this.scorePanel = new ScorePanel();

    this.init();
  }

  // 游戏初始化方法,调用后游戏即开始
  init() {
    // 绑定键盘按下事件
    document.addEventListener("keydown", this.keydownHandle.bind(this));
    this.run();
  }

  /*
  Chrome           IE
  ArrowUp          Up
  ArrowDown       Down
  ArrowLeft       Left
  ArrowRight      Right
  */

  // 创建一个键盘按下的相应函数
  keydownHandle(event: KeyboardEvent) {
    // 修改direction属性
    this.direction = event.key;
  }

  // 创建一个控制蛇移动的方法
  run() {
    /* 根据方向(this.direction)来使蛇的位置改变
      向上 top 减少
      向下 top 增加
      向左 left 减少
      向右 left 增加
    */

    // 获取蛇现在的坐标
    let x: number = this.snake.X;
    let y: number = this.snake.Y;

    // 根据舍得方向计算坐标值
    switch (this.direction) {
      case "ArrowUp":
      case "Up":
      case "w":
      case "W":
        // 向上移动  top 减少
        y -= 10;
        break;
      case "ArrowDown":
      case "Down":
      case "s":
      case "S":
        // 向下移动 top 增加
        y += 10;
        break;
      case "ArrowLeft":
      case "Left":
      case "a":
      case "A":
        // 向左移动 left 减少
        x -= 10;
        break;
      case "ArrowRight":
      case "Right":
      case "d":
      case "D":
        // 向右移动 right 增加
        x += 10;
        break;
    }

    // 检查蛇是否吃到了食物
    this.checkEat(x, y);

    // 使用异常捕获来处理所有的游戏结束事件,减少代码
    try {
      // 修改蛇的位置
      this.snake.X = x;
      this.snake.Y = y;
    } catch (e: any) {
      // 进入到catch,说明出现了异常,游戏结束,弹出一个提示信息
      alert(e.message + "GAME OVER,请刷新页面后重新开始游戏");
      // 将isLive设置为false
      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;

gitee地址:Snake_Game: 使用ts实现一个简单的贪吃蛇小游戏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/359963.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

日期时间控件my97初步探索

因为要写period entry 的项目&#xff0c;需要Report StartDate 和 Report EndDate&#xff0c;于是乎咨询前端同学&#xff0c;推荐my97 官方网站 http://www.my97.net/ 确实有点看起来古老的网站 点击下载能够下载包的资源&#xff0c;以及示例文件 demo示例、Api等 http…

Vue3使用Echarts实现自定义地图(使用阿里云数据可视化平台)

Vue3使用Echarts实现自定义地图 1.获取地图JSON文件 推荐使用 阿里云数据可视化平台 选择你想要使用地图区域并下载JSON文件 2.把地图JSON文件引入Vue3项目中 放在src/assets中 引入你想要使用地图的组件中 3.使用Echarts创建地图 准备地图容器 <template> <…

链路聚合基本概念

聚合组&#xff08;Link Aggregation Group&#xff0c;LAG&#xff09;&#xff1a;若干条链路捆绑在一起所形成的的逻辑链路。每个聚合组唯一对应着一个逻辑接口&#xff0c;这个逻辑接口又被称为链路聚合接口或Eth-Trunk接口。成员接口和成员链路&#xff1a;组成Eth-Trunk接…

win11/10+Azure kinect DK配置 VS2019/2017/2015的方法(简单,亲测可以)

首先下载文件&#xff1a;文件的下载和安装方法参考我的博客(131条消息) WIN11/win10Azure Kinect DK详细驱动配置教程&#xff08;亲测&#xff09;_Vertira的博客-CSDN博客安装好VS2019,创建好控制台c工程。这些都很简单&#xff0c;不细说。配置&#xff1a;首先配置环境变量…

如何快速掌握DDT数据驱动测试?

如何快速掌握DDT数据驱动测试&#xff1f; 目录&#xff1a;导读 前言 实施数据驱动步骤 数据驱动测试环境准备 测试步骤 数据存储 数据存在当前脚本中 json文件读取测试数据进行数据驱动测试 从xml读取数据进行数据驱动测试 总结 写在最后 前言 网盗概念相同的测试…

《Linux运维实战:Centos7.6基于docker-compose一键离线部署rabbitmq3.9.16+haproxy镜像模式高可用负载均衡集群》

一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面向不通的客户安装我们的业务系统&#xff0c;而作为基础组件中的重要的一环&#xff0c;我们需要针对不同的客户环境需要多次部署 rabbitmq镜像模式高可用负载均衡集群&#xff0c;作为一个运维工程师&#xff0c;提升…

LeetCode 793. 阶乘函数后 K 个零

f(x) 是 x! 末尾是 0 的数量。回想一下 x! 1 * 2 * 3 * ... * x&#xff0c;且 0! 1 。 例如&#xff0c; f(3) 0 &#xff0c;因为 3! 6 的末尾没有 0 &#xff1b;而 f(11) 2 &#xff0c;因为 11! 39916800 末端有 2 个 0 。 给定 k&#xff0c;找出返回能满足 f(x) …

Django框架之类视图

类视图 思考&#xff1a;一个视图&#xff0c;是否可以处理两种逻辑&#xff1f;比如get和post请求逻辑。 如何在一个视图中处理get和post请求 注册视图处理get和post请求 以函数的方式定义的视图称为函数视图&#xff0c;函数视图便于理解。但是遇到一个视图对应的路径提供…

【Vue/基础知识】Vue基础知识(一)

如果觉得我的分享有一定帮助&#xff0c;欢迎关注我的微信公众号 “码农的科研笔记”&#xff0c;了解更多我的算法和代码学习总结记录。或者点击链接扫码关注 【Vue/基础知识】Vue基础知识&#xff08;一&#xff09; 1、v-show 和 v-if 指令的共同点和不同点&#xff1f; 共…

【建议收藏】2023年最新最全PMP 报考条件和流程在这里!

PMP考试是由美国项目管理协会PMI发起的项目管理专业人士资格认证考试&#xff0c;在中国国内由中国国际人才交流基金会举办考试&#xff0c;考生在报名参加PMP考试前了解下PMP考试报名条件和流程是必须要做的功课&#xff0c;下面我为大家详细介绍2023年PMP考试报名条件和流程&…

音频信号处理笔记(二)

文章目录1.1.3 过零率1.1.4 谱质心和子带带宽1.1.5 短时傅里叶分析法1.1.6 小波变换相关课程&#xff1a; 音频信号处理及深度学习教程傅里叶分析之掐死教程&#xff08;完整版&#xff09;更新于2014.06.06 - 知乎 (zhihu.com)1.1.3 过零率 过零率&#xff1a;是一个信号符号…

[软件工程导论(第六版)]第7章 实现(复习笔记)

文章目录7.1 编码7.2 软件测试基础7.2.1 软件测试的目标7.2.2 软件测试的准则7.2.3 测试方法7.2.4 测试步骤7.2.5 测试阶段的信息流7.3 单元测试&#xff08;模块测试&#xff09;7.4 集成测试7.5 确认测试&#xff08;验收测试&#xff09;7.6 白盒测试技术7.7 黑盒测试技术7.…

微型光纤光谱仪的光路性能指标

标题光路指标波长范围灵敏度分辨率&#xff08;波长&#xff09;波长准确度与波长重复性光路稳定性杂散光与二级衍射效应光路指标 波长范围 对于微型光纤光谱仪来说&#xff0c;波长范围的概念有两个层面&#xff1a; 由灵敏度所限制的范围&#xff08;Useable range&#xf…

python学习之10行代码制作炫酷的词云图(匹配指定图形形状)

文章目录前言一、需要准备什么&#xff1f;二、代码实现&#xff08;示例&#xff09;三、读入数据四、结果展示五、修改词云颜色后的运行结果展示&#xff1a;总结前言 想必大家有一个问题&#xff1a;什么是词云呢&#xff1f; 词云又叫名字云&#xff0c;是对文本数据中出…

java调用elasticSearch api

java操作es有两种方式 通过操作es的9300端口&#xff0c;9300是tcp端口&#xff0c;集群节点之间通信也是通过9300端口&#xff0c;会通过9300和es建立一个长连接&#xff0c;下面的es的依赖可以直接操作 但是随着es的版本的提升spring-data需要封装不同版本的es的jar包&#x…

Windows命令大全

Windows命令大全命令简介运行流程CMD命令—文件管理CMD命令—磁盘管理CMD命令—系统管理CMD命令—进程管理CMD命令—控制台管理CMD命令—其他管理Windows运行工具操作示例命令简介 CMD命令是一种命令提示符&#xff0c;CMD是command的缩写&#xff0c;即命令提示符&#xff08…

QT(57)-QWT+VS2019+QT5.12.4环境配置-x86

1.下载QWT源码。 2.用VS2019-MSVC2019编译生成6个文件。 3.配置6个文件&#xff0c;把6个文件放对应的目录下。 4. 用自带的example检测配置环境。 1.下载QWT源码 Qwt Users Guide: Qwt - Qt Widgets for Technical Applications2.用VS2019-MSVC2019编译生成6个文件. #qw…

测试工程师如何提高自动化测试覆盖率

前言 自动化测试一直是测试人员的核心技能&#xff0c;也是测试的重要手段之一。尤其是在今年所谓的互联网寒冬的行情下&#xff0c;各大企业对测试人员的技术水平要求的很高&#xff0c;而测试人员的技术水平主要集中在三大自动化测试领域&#xff0c;再加测试辅助脚本的编写…

350-401-补充

补充 拖图 Cloud和On-Premise&#xff1b; Cloud&#xff1a; easy to scale the capacity up and down highly agile On-Premises&#xff1a; infrstructure requires large and regular investments highly customizable 云: 易于扩大和缩小容量 非常敏捷 本地: 基础设施…

nodejs基于vue 网上商城购物系统

可定制框架:ssm/Springboot/vue/python/PHP/小程序/安卓均可开发 目录 1 绪论 1 1.1课题背景 1 1.2课题研究现状 1 1.3初步设计方法与实施方案 2 1.4本文研究内容 2 2 系统开发环境 4 2. 3 系统分析 6 3.1系统可行性分析 6 3.1.1经济可行性 6 3.1.2技术可行性 6 3.1.3运行可行…