TypeScript实现贪吃蛇效果

news/2024/7/7 7:39:29/文章来源:https://www.cnblogs.com/GodsLayer/p/18268782

项目参考教程:贪吃蛇案例

1.项目搭建

1.1 项目结构搭建

创建一个名为xxx的项目

项目初始化

npm init -y

安装后面需要用到的依赖,在package.json中查看

 

 

 

 

 

 

 

 

 

 

项目根目录创建名为tsconfig.json的文件并更改内容如下:

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

项目根目录创建名为twebpack.config.js的文件并更改内容如下:

//引入一个包
const path = require("path");
//引入html插件
const HTMLWebpackPlugin = require("html-webpack-plugin");
//引入clean插件
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const {options} = require("less");
//webpack中的所有配置信息都应该写在module.exports中
module.exports = {mode: "development",//指定入口文件entry: "./src/index.ts",//指定打包文件所在目录output: {//打包后文件的目录path: path.resolve(__dirname, "dist"),filename: "bundle.js",//告诉我们webpack不使用箭头函数environment: {arrowFunction: false,},},//指定webpack打包时要使用的模块module: {//指定要再加载的规则rules: [{//test规则生效的文件test: /\.ts$/,use: [//配置babel{//指定加载器loader: "babel-loader",//设置babeloptions: {//设置预定义的环境presets: [[//指定环境的插件"@babel/preset-env",//配置信息{//要兼容的目标浏览器targets: {chrome: "88",ie: "11",},//指定corejs的版本corejs: "3",//按需使用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"],},
};

创建如下目录

 

 

 

 

编写index.html文件内容

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"/><title>贪吃蛇</title>
</head>
<body>
<!--主容器-->
<div id="main"><!--游戏舞台--><div id="stage"><!--蛇--><div id="snake"><!--蛇的内部div,表示蛇的各个部分--><div></div></div><!--食物--><div id="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>

编写index.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: 15px;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;flex-flow: row wrap;justify-content: space-between;align-content: space-between;transform: rotate(45deg);& > div {width: 4px;height: 4px;background-color: black;}}}//积分牌#score-panel {width: 300px;display: flex;justify-content: space-between;}
}

编写index.ts文件内容

import './style/index.less';

最终搭建项目如图所示(项目名称不做严格要求)

 

 

 

 

 

 

 

 

1.2 项目启动

在终端运行npm run build编译项目

运行npm start启动项目,如下为项目启动成功、

效果如图

 

 

 

 

 

 

 

 

 

 

2.编写Food类

index.ts添加如下内容

//定义食物Food
class Food {//定义一个属性表示食物对应的元素element: HTMLElement;constructor() {//获取页面中的food元素并赋值给elementthis.element = document.getElementById('food')!;}//获取食物x轴坐标的方法get x() {return this.element.offsetLeft;}//获取食物y轴坐标的方法get y() {return this.element.offsetTop;}//修改食物位置change() {//生成随机位置//食物的随机位置最小是0,最大是290//蛇移动一次就是一格,一格就是10,所以食物的坐标必须是整10let top = Math.round(Math.random() * 30) * 10;let left = Math.round(Math.random() * 30) * 10;this.element.style.left = top + 'px';this.element.style.top = left + 'px'}
}

3.编写ScorePanel

在index.ts添加代码

class ScorePanel {//score和level用来记录分数和等级score = 0;level = 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 + '';}}
}const scorePanel = new ScorePanel(100, 2);
for (let i = 0; i < 200; i++) {scorePanel.addScore();
}

运行代码效果如图

 

 

 

 

 

 

 

 

 

4.模块化

在src下创建名为modules的文件夹

 

 

 

 

 

 

 

 

 

创建Food.ts文件

将index.ts的Food类代码复制到Food.ts文件中

 

在Food.ts添加代码将模块暴露出去

export default Food;

ScorePanel类进行同样操作

在index.ts中引入模块并调用

 

5.编写snake类

class Snake {//蛇头的元素head: HTMLElement;bodies: HTMLCollection;//获取蛇的容器element: HTMLElement;constructor() {this.element = document.getElementById('snake')!;this.head = document.querySelector('#snake > div') as HTMLElement;this.bodies = this.element.getElementsByTagName('div');}//获取蛇的坐标(蛇头坐标)get X() {return this.head.offsetLeft;}get Y() {return this.head.offsetTop;}//设置蛇头的坐标set X(value) {this.head.style.left = value + 'px';}set Y(value) {this.head.style.top = value + 'px';}//设置蛇增加身体的方法addBody() {this.element.insertAdjacentHTML("beforeend","<div></div>")}
}

6.GameControoller实现

src下创建GamaController类,用来管理Food类、scorePanel类和Snake类,并将其暴露,并在index.ts中引入该模块

 

 

 

 

import Snake from "./snake";
import Food from "./Food";
import ScorePanel from "./ScorePanel";//游戏控制器 控制其他所有类
class GameController {//定义三个属性snake: Snake;food: Food;scorePanel: ScorePanel;//创建一个属性来存储移动方向(按键的方向)dirdction: string = '';constructor() {this.snake = new Snake();this.food = new Food();this.scorePanel = new ScorePanel();this.init();}//游戏初始化方法,调用后游戏开始init() {document.addEventListener('keydown', this.keydownhandler.bind(this));}//创建一个键盘按下的响应函数keydownhandler(event: KeyboardEvent) {//需要检查event.key的值是否合法(是否按了四个方向键)//修改direction属性this.dirdction = event.key;}
}export default GameController;

6.1 GameController实现蛇的移动

在GameController中添加代码实现跑

import Snake from "./snake";
import Food from "./Food";
import ScorePanel from "./ScorePanel";//游戏控制器 控制其他所有类
class GameController {//定义三个属性snake: Snake;food: Food;scorePanel: ScorePanel;//创建一个属性来存储移动方向(按键的方向)dirdction: string = '';//创建一个属性来记录游戏是否结束isLive = true;constructor() {this.snake = new Snake();this.food = new Food();this.scorePanel = new ScorePanel();this.init();}//游戏初始化方法,调用后游戏开始init() {document.addEventListener('keydown', this.keydownhandler.bind(this));//调用方法使蛇移动this.run();}//创建一个键盘按下的响应函数keydownhandler(event: KeyboardEvent) {//需要检查event.key的值是否合法(是否按了四个方向键)//修改direction属性this.dirdction = event.key;}//控制蛇移动run() {/** 根据方向(this.diretion)来使蛇的位置改变* 向上  top  减少* 向上  top  增加* 向左  left  减少* 向右  left  增加* *///获取蛇现在坐标let X = this.snake.X;let Y = this.snake.Y;//根据按键方向修改X值和Y值switch (this.dirdction) {case "ArrowUp":case "Up":Y -= 10;break;case "ArrowDown":case "Down":Y += 10;break;case "ArrowLeft":case "Left":X -= 10;break;case "ArrowRight":case "Right":X += 10;break;}//修改蛇的x和Ythis.snake.X = X;this.snake.Y = Y;//开启定时调用this.isLive && setTimeout(this.run.bind(this), 300 * (this.scorePanel.level - 1) * 30);//等级越高速度越快}
}export default GameController;

6.2 蛇撞墙和吃食的检测

snake.ts做如下修改

 

 

 

 

 

 

 

 

 

 

 

 

snake.ts

class Snake {//蛇头的元素head: HTMLElement;bodies: HTMLCollection;//获取蛇的容器element: HTMLElement;constructor() {this.element = document.getElementById('snake')!;this.head = document.querySelector('#snake > div') as HTMLElement;this.bodies = this.element.getElementsByTagName('div');}//获取蛇的坐标(蛇头坐标)get X() {return this.head.offsetLeft;}get Y() {return this.head.offsetTop;}//设置蛇头的坐标set X(value) {//如果新值和旧值相等,则直接返回不修改if (this.X === value) {return;}//X的合法值为0~290之间if (value < 0 || value > 290) {//进入判断说明蛇撞墙了throw new Error('蛇撞墙了!')}this.head.style.left = value + 'px';}set Y(value) {//如果新值和旧值相等,则直接返回不修改if (this.Y === value) {return;}//Y的合法值为0~290之间if (value < 0 || value > 290) {//进入判断说明蛇撞墙了throw new Error('蛇撞墙了!')}this.head.style.top = value + 'px';}//设置蛇增加身体的方法addBody() {this.element.insertAdjacentHTML("beforeend", "<div></div>")}
}export default Snake;

GameController.ts做如下修改

import Snake from "./snake";
import Food from "./Food";
import ScorePanel from "./ScorePanel";//游戏控制器 控制其他所有类
class GameController {//定义三个属性snake: Snake;food: Food;scorePanel: ScorePanel;//创建一个属性来存储移动方向(按键的方向)dirdction: string = '';//创建一个属性来记录游戏是否结束isLive = true;constructor() {this.snake = new Snake();this.food = new Food();this.scorePanel = new ScorePanel();this.init();}//游戏初始化方法,调用后游戏开始init() {document.addEventListener('keydown', this.keydownhandler.bind(this));//调用方法使蛇移动this.run();}//创建一个键盘按下的响应函数keydownhandler(event: KeyboardEvent) {//需要检查event.key的值是否合法(是否按了四个方向键)//修改direction属性this.dirdction = event.key;}//控制蛇移动run() {/** 根据方向(this.diretion)来使蛇的位置改变* 向上  top  减少* 向上  top  增加* 向左  left  减少* 向右  left  增加* *///获取蛇现在坐标let X = this.snake.X;let Y = this.snake.Y;//根据按键方向修改X值和Y值switch (this.dirdction) {case "ArrowUp":case "Up":Y -= 10;break;case "ArrowDown":case "Down":Y += 10;break;case "ArrowLeft":case "Left":X -= 10;break;case "ArrowRight":case "Right":X += 10;break;}//检查蛇是否吃到了食物this.checkEat(X, Y);//修改蛇的x和Ytry {this.snake.X = X;this.snake.Y = Y;} catch (e) {//进入catch,说明出现异常,游戏结束,弹出提示信息alert((e as Error).message + 'GAME OVER!');//将isLive设置为falsethis.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 GameController;

6.2 设置蛇吃食后增加身体长度

 

 

 

 

 

在snake.ts中修改

class Snake {//蛇头的元素head: HTMLElement;bodies: HTMLCollection;//获取蛇的容器element: HTMLElement;constructor() {this.element = document.getElementById("snake")!;this.head = document.querySelector("#snake > div") as HTMLElement;this.bodies = this.element.getElementsByTagName("div");}//获取蛇的坐标(蛇头坐标)get X() {return this.head.offsetLeft;}get Y() {return this.head.offsetTop;}//设置蛇头的坐标set X(value) {//如果新值和旧值相等,则直接返回不修改if (this.X === value) {return;}//X的合法值为0~290之间if (value < 0 || value > 290) {//进入判断说明蛇撞墙了throw new Error("蛇撞墙了!");}//移动身体this.moveBody();this.head.style.left = value + "px";}set Y(value) {//如果新值和旧值相等,则直接返回不修改if (this.Y === value) {return;}//Y的合法值为0~290之间if (value < 0 || value > 290) {//进入判断说明蛇撞墙了throw new Error("蛇撞墙了!");}   //移动身体this.moveBody();this.head.style.top = value + "px";}//设置蛇增加身体的方法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';}}
}export default Snake;

6.3 优化

蛇在向右走走时,不能按←键,反之亦然

6.3.1 移动方向的优化

 

 

 

 

 

 

 

 

snake.ts代码修改

class Snake {//蛇头的元素head: HTMLElement;bodies: HTMLCollection;//获取蛇的容器element: HTMLElement;constructor() {this.element = document.getElementById("snake")!;this.head = document.querySelector("#snake > div") as HTMLElement;this.bodies = this.element.getElementsByTagName("div");}//获取蛇的坐标(蛇头坐标)get X() {return this.head.offsetLeft;}get Y() {return this.head.offsetTop;}//设置蛇头的坐标set X(value) {//如果新值和旧值相等,则直接返回不修改if (this.X === value) {return;}//X的合法值为0~290之间if (value < 0 || value > 290) {//进入判断说明蛇撞墙了throw new Error("蛇撞墙了!");}//修改X时,在修改水平坐标,蛇在左右移动,Y轴同理,反之亦然if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {// console.log('水平方向掉头')//如果发生掉头,继续向反方向掉头if (value > this.X) {//如果新值大于旧值。则说明蛇在向右走。此时发生掉头,继续向左走value = this.X - 10;} else {value = this.X + 10;}}//移动身体this.moveBody();this.head.style.left = value + "px";}set Y(value) {//如果新值和旧值相等,则直接返回不修改if (this.Y === value) {return;}//Y的合法值为0~290之间if (value < 0 || value > 290) {//进入判断说明蛇撞墙了throw new Error("蛇撞墙了!");}//修改Y时,在修改水平坐标,蛇在上下移动,X轴同理,反之亦然if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {// console.log('水平方向掉头')//如果发生掉头,继续向反方向掉头if (value > this.Y) {//如果新值大于旧值。则说明蛇在向右走。此时发生掉头,继续向左走value = this.Y - 10;} else {value = this.Y + 10;}}//移动身体this.moveBody();this.head.style.top = value + "px";}//设置蛇增加身体的方法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';}}
}export default Snake;

6.3.2 穿越身体的优化

穿越身体撞到自己游戏结束

 

 

 

 

 

 

 

 

snake.ts修改

class Snake {//蛇头的元素head: HTMLElement;bodies: HTMLCollection;//获取蛇的容器element: HTMLElement;constructor() {this.element = document.getElementById("snake")!;this.head = document.querySelector("#snake > div") as HTMLElement;this.bodies = this.element.getElementsByTagName("div");}//获取蛇的坐标(蛇头坐标)get X() {return this.head.offsetLeft;}get Y() {return this.head.offsetTop;}//设置蛇头的坐标set X(value) {//如果新值和旧值相等,则直接返回不修改if (this.X === value) {return;}//X的合法值为0~290之间if (value < 0 || value > 290) {//进入判断说明蛇撞墙了throw new Error("蛇撞墙了!");}//修改X时,在修改水平坐标,蛇在左右移动,Y轴同理,反之亦然if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {// console.log('水平方向掉头')//如果发生掉头,继续向反方向掉头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) {//如果新值和旧值相等,则直接返回不修改if (this.Y === value) {return;}//Y的合法值为0~290之间if (value < 0 || value > 290) {//进入判断说明蛇撞墙了throw new Error("蛇撞墙了!");}//修改Y时,在修改水平坐标,蛇在上下移动,X轴同理,反之亦然if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {// console.log('水平方向掉头')//如果发生掉头,继续向反方向掉头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++) {let bd = this.bodies[i] as HTMLElement;if (this.X === bd.offsetLeft && this.Y === bd.offsetTop) {throw new Error('撞到自己了!!!')}}}
}export default Snake;

 

7 得分测试

为了便于测试,加快升级速度,修改GameController代码

 

 

 

 

 

至此,完结撒花!!!

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

m基于Googlenet深度学习的运动项目识别系统matlab仿真,包括GUI界面

1.算法仿真效果 matlab2022a仿真结果如下: 2.算法涉及理论知识概要基于GoogLeNet深度学习的运动项目识别系统,是利用深度神经网络技术,尤其是GoogLeNet架构,来自动识别视频或图像中的人类运动类型的过程。GoogLeNet(也称为Inception网络)在2014年由Google团队提出,因其高…

模拟集成电路设计系列博客——7.5.6 时间交错型ADC

7.5.6 时间交错型ADC 我们可以通过将多个ADC做并行来实现非常高速的ADC[Black, 1980]。下图展示了一个四通道时间交错型ADC的架构图:此处,\(\phi_0\)是一个四倍于\(\phi_1\)到\(\phi_4\)的速率的时钟。此外,\(\phi_1\)到\(\phi_4\)彼此都落后一个\(\phi_0\)的周期。这样每个…

(构造) CF1758D Range = √Sum

题意:思路:先钦定这个序列的和为4n^{2} ,那么差值就是2n 考虑一个初始序列1,2,3,⋯,n−1,2n+1.现在我们要做的就是将这个序列变成合法的我可以进行整体都+x的操作使得这个序列的和尽量逼近4n^{2}。直接算出每个数应该加上的x,还会有一点剩余,加到a[n-1]上即可,a[n-1]+n=…

Java探秘:揭秘栈帧的神秘面纱与内存占用之谜

哈喽,大家好,我是木头左!深入理解Java栈帧 在Java虚拟机(JVM)的运行时数据区中,每一个线程都有自己的栈(Stack),而栈中的每一个元素就是一个栈帧(Stack Frame)。当一个方法被调用时,一个新的栈帧会被创建并压入到栈中。这个栈帧包含了方法的局部变量、参数以及返回地…

数据库和Flask项目搭建

1 sqlalchemy原生操作 # 操作原生sql ---》用得少 import pymysql import threading # 1 导入 from sqlalchemy import create_engine from sqlalchemy.engine.base import Engine # 2 创建引擎 engine = create_engine("mysql+pymysql://root:1234@127.0.0.1:3306/cnblog…

flask定制Excel命令

定制excel命令并插入到数据库中 import osfrom flask import Flask from flask.cli import AppGroup import click import pymysql from openpyxl import load_workbookapp = Flask(__name__)@app.cli.group() def excel():"""Excel related commands."&qu…

flask的简单使用

1 flask介绍 #1 python 界的web框架-Django:大而全,你要的东西都有 [orm,缓存,认证]django-ninja-flask:小而精,所有web开发需要的东西,借助于第三方集成-web.py-----同步框架--进程线程架构--3.x以后支持异步--tornado sanicfastapi:高性能小而精,借助于第三方:orm…

模拟集成电路设计系列博客——7.5.5 折叠型ADC

7.5.5 折叠型ADC 我们刚了解完输入放大器的数量如何通过插值型架构来减少。但是对于一个N bit的ADC来说,仍然需要\(2^N\)个锁存比较器。这个大量的比较器数量可以通过折叠型ADC架构来减少。折叠型ADC架构类似于两步型ADC,一组LSB分离于一组MSB进行独立的查找。但是,相比两步…

240627构造

20240627构造专题 写在前面:出场即巅峰(明日模拟赛RP++) 一.何为构造 就是通过对一道题题面的分析可以发现某种规律(类似于不完全归纳法),然后发掘本质,就可以很快的解题,但是显然我还没有掌握 二.一些技巧 1.寻找特殊性质,从而求解 2.估算上界(也就是对最优情况进行…

别人工作8小时,我只需1小时!这些宝藏网站我都替你收集好了!

mac免费应用,效率工具,编程工具,设计网站,图片网站,通通一网打尽软件mac应用下载 很多破解版应该都可以找到snipaste: 截图工具,快捷截图,贴图等功能。幕布: 快速编辑思维导图。sublime text: 文档编辑器(打开速度贼快)。visual studio code: 新一代编辑器(插件非常…

VLC工具使用指南

一、引言 VLC(VideoLAN Client)是一款功能强大的免费开源跨平台多媒体播放器和框架,能够播放大多数多媒体文件以及DVD、音频CD、VCD和各种流媒体协议。无论是本地视频文件还是网络视频流,VLC都能轻松应对。本文将详细介绍VLC工具的基本用法和高级功能。 二、安装与设置 下载…

递归示例-指定数字以内的所有排列组合(Reduce)

指定数字以内的所有排列组合: 定义名称版:=pmtt(指定数字)pmtt=LAMBDA(x,IF(x=1,1,VSTACK(pmtt(x-1),REDUCE(SEQUENCE(x),SEQUENCE(,x-1)^0*x,LAMBDA(a,b,TOCOL(a&SEQUENCE(,b)))))))不定义名称版:=LET(fx,LAMBDA(npmtt,x,IF(x=1,1,VSTACK(npmtt(npmtt,x-1),REDUCE(SEQU…

nodejs解压zip/rar文件到本地,并获取到解压进度

方案:解压到本地的大小 / zip文件总大小(解压后的) ,得出解压进度 先得出解压后的文件大小,然后解压到本地const AdmZip = require("adm-zip"); const JSZip = require(jszip);// 指定ZIP文件的路径 const admZip = new AdmZip("D:\\Users\\whr4220\\Downloa…

畅联云看视频卡顿、画质不清原因可能是一些参数没有配置对

在畅联云平台观看视频时,很多用户可能会遇到卡顿和画质不清晰的问题。这些问题往往由多种因素共同导致,包括网络带宽与传输质量、视频编码与压缩、服务器性能与负载均衡,以及视频源质量等。本文我们将重点说一下摄像机上面的一些可能影响视频卡顿和画质的参数。 打开摄像机w…

R语言独立成分分析fastICA、谱聚类、支持向量回归SVR模型预测商店销量时间序列可视化|附代码数据

全文链接:http://tecdat.cn/?p=31948 原文出处:拓端数据部落公众号 本文利用R语言的独立成分分析(ICA)、谱聚类(CS)和支持向量回归 SVR 模型帮助客户对商店销量进行预测。 首先,分别对商店销量的历史数据进行了独立成分分析,得到了多个独立成分;其次,利用谱聚类方法…

Profibus协议转Modbus协议网关模块在船舶中的应用

本文主要介绍了Profibus协议转Modbus协议网关模块(XD-MDPB100)在船舶中的应用。 Profibus转Modbus网关能实现Profibus总线和Modbus协议之间的数据转换与对接,为船舶系统之间的信息交换提供便利。一、背景 在当今数字化快速发展的时代,船舶作为重要的交通工具之一,也在不断…

sessionStorage 能在多个标签页之间共享数据吗?

🧑‍💻 写在开头 点赞 + 收藏 === 学会🤣🤣🤣 最近,我的一个朋友在面试中被一个关于 sessionStorage 的问题难住了。我们来聊聊这个话题。sessionStorage 能在多个标签页之间共享数据吗?在回答这个问题之前我们先来聊聊另一个存储API localstorage localstorage与s…

2024-06-27 java spring boot项目用maven打包报错:xxx-0.0.1-SNAPSHOT.jar中没有主清单属性

问题如下: 原因:打包文件pom.xml配置问题<skip>true</skip>不能为true!为true时,此处引用网友的解释: 在spring-boot-maven-plugin的配置中设置 <skip>true</skip> 时,实际上你告诉Maven在执行构建生命周期时跳过这个插件的运行。此插件负责将你的…

如何设计一个好的测试用例

如何理解一个“好的”测试用例? “好的”测试用例一定是一个完备的集合,它能够覆盖所有等价类以及各种边界值,而跟能够发现缺陷无关。 举例子: 被测软件 --- 鱼塘 软件缺陷 --- 鱼 测试用例集 --- 渔网 “好的”测试用例集就是一张能够覆盖整个鱼塘的大鱼网,只要鱼塘里有鱼…