【ts + webpack】贪吃蛇小游戏
目录
一、项目搭建
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",// 设置babeloptions: {// 设置定义的环境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元素并将其复制给elementthis.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中添加一个divthis.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 IEArrowUp UpArrowDown DownArrowLeft LeftArrowRight 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设置为falsethis.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中添加一个divthis.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 IEArrowUp UpArrowDown DownArrowLeft LeftArrowRight 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设置为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 GameControl;
gitee地址:Snake_Game: 使用ts实现一个简单的贪吃蛇小游戏
相关文章:

【ts + webpack】贪吃蛇小游戏
目录 一、项目搭建 1.1 初始化项目 二、项目界面布局 三、完成Food类 四、完成记分牌类 五、初步完成snake类 六、创建游戏控制器类 - 键盘事件 七、GameControl - 使蛇移动 八、蛇撞墙和吃食检测 一、项目搭建 1.1 初始化项目 1.使用init命令生成package.json文件 …...

传统巨头生“变”,中国毫米波雷达市场战火再升级
进入2023年,中国车载毫米波雷达市场战火明显升级。 一方面,愈演愈烈的份额抢夺战不仅仅存在于几大传统巨头之间,也快速转移到与国产供应商之间;随着部分外资巨头的本土化战略深入落地,同时对国产供应商造成了压力。 …...

26岁曾月薪15K,现已失业3个月,我依然没有拿到offer......
我做测试5年,一线城市薪水拿到15K,中间还修了一个专升本,这个年限不说资深肯定也是配得上经验丰富的。今年行情不好人尽皆知,但我还是对我的薪水不是很满意,于是打算出去面试,希望可以搏一个高薪。 但真到面…...
华为OD机试 - 打印文件 | 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 简易压缩算法(Python) | 机试题算法思路 【2023】 华为OD机试题 - 获取最大软件版本号(JavaScript) 华为OD机试 - 猜字谜(Python) | 机试题+算法思路 【2023】 华为OD机试 - 删除指定目录(Python) | 机试题算法思路 【2023】 华为OD机试 …...

【前端】浏览器的渲染流程(完整)
本文主要包含以下内容:浏览器渲染整体流程解析 HTML样式计算布局分层生成绘制指令分块光栅化绘制常见面试题浏览器渲染整体流程浏览器,作为用户浏览网页最基本的一个入口,我们似乎认为在地址栏输入 URL 后网页自动就出来了。殊不知在用户输入…...
华为OD机试 - 有效子字符串 | 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 简易压缩算法(Python) | 机试题算法思路 【2023】 华为OD机试题 - 获取最大软件版本号(JavaScript) 华为OD机试 - 猜字谜(Python) | 机试题+算法思路 【2023】 华为OD机试 - 删除指定目录(Python) | 机试题算法思路 【2023】 华为OD机试 …...
抽象类和接口
抽象类和接口 抽象类和接口的定义 抽象类主要用来抽取子类的通用特性,作为子类的模板,它不能被实例化,只能被用作为子类的超类。 接口是抽象方法的集合,声明了一系列的方法操作,如果一个类实现了某个接口,…...
STM32DSP库汇总
前言 本文仅对stm32的DSP库进行汇总,具体函数使用方式持续更新…… 分类函数名描述 BasicMathFunctions 基础数学函数 abs绝对值add加法dot_prod向量点积mult乘法negate相反数offset 偏置 scale比例缩放shift移位sub减法 ComplexMathFunctions 复数数学函数 conj…...

C++类和对象----思想基础应用
类与对象的思想&基础应用一、类声明1.1、封装类的意义1.1.1、在设计类的时候,属性和行为写在一起,表现事物1.1.2、成员权限1.2、struct和class区别1.3、成员属性设置为私有二、对象的初始化和清理2.1、构造函数&析构函数2.2、构造函数分类方法一…...
力扣解法汇总1792. 最大平均通过率
目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 一所学校里有一些班级,每个班级里有一些学生,现在每个班…...

动手学深度学习(第二版)学习笔记 第二章
官网:http://zh.d2l.ai/ 视频可以去b站找 记录的是个人觉得不太熟的知识 第二章 预备知识 代码地址:d2l-zh/pytorch/chapter_preliminaries 2.1 数据操作 2.1. 数据操作 — 动手学深度学习 2.0.0 documentation 如果只想知道张量中元素的总数&#…...

CMake构建静态库与动态库以及使用
CMake构建静态库与动态库一、任务二、准备工作三、编译共享库四、ADD_LIBRARY指令五、编译静态库5.1、SET_TARGET_PROPERTIES指令5.2、GET_TARGET_PROPERTY指令六、动态库版本号七、安装共享库和头文件八、使用外部共享库和头文件8.1、准备工作8.2、引入头文件搜索路径8.3、为 …...

Linux 系统目录结构
登录系统后,在当前命令窗口下输入命令: ls / 你会看到如下图所示: 树状目录结构: 以下是对这些目录的解释: /bin: bin 是 Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令。 /boot: 这里…...
stable diffusion webui安装与使用(官方超简单教程)
预备依赖 下载miniconda 教程参考:https://blog.csdn.net/weixin_43828245/article/details/124768518安装git 参考教程:https://blog.csdn.net/weixin_46474921/article/details/127091723 下载sd-webui 官网 https://github.com/AUTOMATIC1111/stab…...

机器学习:学习k-近邻(KNN)模型建立、使用和评价
机器学习:学习k-近邻(KNN)模型建立、使用和评价 文章目录机器学习:学习k-近邻(KNN)模型建立、使用和评价一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.数据读取2.数据理解3.数据准备4.算…...
Hive Sampling 抽样函数:Random随机抽样、Block 基于数据块抽样、Bucket table 基于分桶表抽样
Hive Sampling 抽样函数 文章目录Hive Sampling 抽样函数Random随机抽样Block 基于数据块抽样Bucket table 基于分桶表抽样语法在HQL中,可以通过三种方式采样数据:随机采样,存储桶表采样和块采样。Random随机抽样 随机抽样使用rand()函数确保…...
2023年中职网络安全竞赛跨站脚本渗透解析-1(超详细)
跨站脚本渗透 任务环境说明:需求环境可私信博主! 服务器场景:Server2125(关闭链接)服务器场景操作系统:未知访问服务器网站目录1,根据页面信息完成条件,将获取到弹框信息作为flag提交;访问服务器网站目录2,根据页面信息完成条件,将获取到弹框信息作为flag提交;访问服…...

虚拟 DOM 详解
什么是虚拟 dom? 虚拟 dom 本质上就是一个普通的 JS 对象,用于描述视图的界面结构 在vue中,每个组件都有一个render函数,每个render函数都会返回一个虚拟 dom 树,这也就意味着每个组件都对应一棵虚拟 DOM 树 查看虚拟…...
Delphi Http Https 最好的解决方法(一)
当前文章主要解决Delphi调用http、https的常见报错。 开发工具: Delphi XE 10.1 Berlin版本 可能所需的控件包: QDAC 请自行下载。 1. 接口描述 dll_init 接口初始化,程序启动时调用,主要是对工具类实例的创建 dll_post 发送post请求&am…...

Allegro无法打开10度走线命令的原因和解决办法
Allegro无法打开10度走线命令的原因和解决办法 做PCB设计的时候,10度走线也是较为常见的设计方式,Allegro支持10度走线,如下图 需要10度走线的时候,Options只需要勾选Route offset命令即可 但有时options处会看不到10度走线的命令,如下图...

Tomcat全方位监控实施方案指南
#作者:程宏斌 文章目录 一.二进制部署1、安装包信息2、新建配置文件2.1 配置config.yaml文件2.2 上传jar包 3、修改配置3.1 备份3.2 修改bin目录下的startup.sh文件 4、重启tomcat5、访问测试 二.docker部署1、临时方案1.1、重新启动容器1.2…...
设计模式复习小结
1.容易忘得设计原则 接口隔离:指接口中的功能太杂则可以拆分一下。防止实现类实现了接口后自动依赖了一些不需要的功能。不同功能拆分成不同的接口。 里氏代换:强调父类能出现的地方,子类一定能正常跑。 迪米特法则:又称最少知…...

【C#】Quartz.NET怎么动态调用方法,并且根据指定时间周期执行,动态配置类何方法以及Cron表达式,有请DeepSeek
🌹欢迎来到《小5讲堂》🌹 🌹这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解。🌹 🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!&#…...
Python爬虫实战:研究urlparse库相关技术
1 引言 1.1 研究背景与意义 网络爬虫作为互联网数据采集的核心技术,在信息检索、舆情分析、数据挖掘等领域具有广泛应用。随着 Web 技术的发展,现代网站 URL 结构日益复杂,包含路径参数、查询参数、锚点等多种组件,且存在相对路径、URL 编码等问题,给爬虫开发带来了挑战…...

2025年06月05日Github流行趋势
项目名称:onlook 项目地址url:https://github.com/onlook-dev/onlook项目语言:TypeScript历史star数:16165今日star数:1757项目维护者:Kitenite, drfarrell, spartan-vutrannguyen, apps/devin-ai-integrat…...

WordPress子主题RiPro-V5van无授权全开源版(源码下载)
WordPress子主题RiPro-V5van无授权全开源版,直接上使用方法:WordPress后台上传就行 这个主题是1.0版本开源的,有能力的可以二次开发一下加一些自己喜欢的功能。 源码下载:https://download.csdn.net/download/m0_66047725/90952148 更多资…...

【C语言预处理详解(下)】--#和##运算符,命名约定,命令行定义 ,#undef,条件编译,头文件的包含,嵌套文件包含,其他预处理指令
目录 五.#和##运算符 5.1--#运算符 5.2--##运算符 六.命名约定,#undef,命令行定义 6.1--命名约定 6.2--#undef 6.3--命名行定义 七.条件编译 常见的条件编译指令: 1.普通的条件编译: 2.多个分支的条件编译(可以利用条…...

Github 2025-06-03Python开源项目日报 Top10
根据Github Trendings的统计,今日(2025-06-03统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10Rust项目1HTML项目1C项目1 系统设计指南 创建周期:2507 天开发语言:Pyt…...

嵌入式开发之STM32学习笔记day20
STM32F103C8T6 PWR电源控制 1 PWR简介 PWR(Power Control)电源控制单元是STM32微控制器中一个重要的组成部分,它负责管理系统的电源管理功能,以优化功耗并提高效率。PWR负责管理STM32内部的电源供电部分,可以实现可编…...
React Native开发鸿蒙运动健康类应用的项目实践记录
项目名称:HarmonyFitness - 基于React Native的鸿蒙运动健康应用 技术栈:React Native 0.72.5 TypeScript HarmonyOS API ArkTS原生模块 一、环境搭建与项目初始化 双环境配置 React Native环境: npx re…...