cocosCreator 之 Graphics绘制基础图形,五角星,线型图,柱形图

news2024/9/25 11:20:23

版本: 3.4.0

环境: Mac


Graphics组件


Graphics组件主要用于绘画使用,属于渲染组件。继承结构:

Graphics
Renderable2D
RenderableComponent
Component

更多继承结构可参考: cocosCreator 之 cc.d.ts

该组件创建后,主要的属性有:
请添加图片描述

  • LineWidth 线条宽度
  • LineJoin 相交线段的拐角类型, 可通过Graphics.LineJoin来设置,主要类型有:
    • BEVEL 斜角
    • ROUND 圆角
    • MITER 尖角
  • LineCap 线条结束端点的样式, 可通过Graphics.LineCap来设置, 主要类型有:
    • BUTT 向线条的每个末端添加平直的边缘
    • ROUND 向线条的每个末端添加圆形线帽
    • SQUARE 向线条的每个末端添加正方形线帽
  • StrokeColor 画笔颜色
  • FillColor 填充颜色,主要应用于图形的构建
  • MiterLimit 最大斜接长度,默认即可

一个简答的示例:

// 绘制线段
// 
export class UI_GraphicBaseLayer extends Component {
  // 绘制组件
  @property(Graphics) graphics: Graphics;

  start () {
    // 设置线段宽度
    this.graphics.lineWidth = 10;
    // 设置线段末端样式
    this.graphics.lineCap = Graphics.LineCap.ROUND;
    // 设置画笔颜色
    this.graphics.strokeColor = Color.RED;
    // 移动路径起点(x,y)
    this.graphics.moveTo(-400, 220);
    // 移动路径终点(x,y)
    this.graphics.lineTo(-200, 220);
    // 绘制
    this.graphics.stroke();
  }
}

通过moveTolineTo其实可以明白绘制一个从(-400, 200)到(-200, 200)的线段,这个是理解绘制的关键点。

该组件可以做很多事情:

  • 用来绘制基础的线段,矩形,圆,椭圆等
  • 用来绘制自定义的五角星,六角形,雷达图等
  • 用来绘制折线图,圆柱图等
  • 用来绘画涂鸦使用
  • 用于同Mask遮罩进行自定义图形裁切,或者模拟刮刮乐效果等

注意:

使用Graphics组件绘制过多的图形或复杂的图形可能会导致性能下降,因为绘制操作需要消耗CPU和GPU资源。

特别是在移动设备等性能较低的设备上,过多的绘图操作可能会导致帧率下降,影响游戏的流畅度。


绘图接口


Graphics组件的主要属性和接口有:

名字说明
lineWidth设置/获取线条宽度
lineJoin设置/获取两条线相交时,所创建的拐角类型,可通过Graphics.LineJoin设置
lineCap设置/获取线条结束端点的样式, 可通过Graphics.LineCap来设置
strokeColor设置/获取画笔颜色
fillColor设置/获取填充颜色
miterLimit设置/获取斜接面限制比例
srcBlendFactor指定源的混合模式,这会克隆一个新材质对象,注意带来的性能和内存损耗
dstBlendFactor指定目标的混合模式,这会克隆一个新材质对象,注意带来的性能和内存损耗
moveTo()设置起始点(x, y)
lineTo()设置结束点(x, y)
quadraticCurveTo()绘制二次贝赛尔曲线
bezierCurveTo()绘制三次贝赛尔曲线
arc()绘制圆弧
ellipse()绘制椭圆
circle()绘制圆
rect()绘制矩形
roundRect()绘制圆角矩形
fillRect()绘制填充矩形
clear()擦除绘画
close()将笔点返回到当前路径起始点的。它尝试从当前点到起始点绘制一条直线
stroke()根据当前的画线样式,绘制当前或已经存在的路径
fill()根据当前的画线样式,填充当前或已经存在的路径

具体的接口代码相关,参考:cc.d.ts

// 自定义图形类
export class Graphics extends Renderable2D {
	// 移动路径起点到坐标(x, y)
	moveTo(x: number, y: number): void;
	// 绘制直线路径(x,y)
	lineTo(x: number, y: number): void;
  /*
  * 绘制三次贝赛尔曲线路径。
  * @param c1x - 第一个控制点的坐标 x 轴。
  * @param c1y - 第一个控制点的坐标 y 轴。
  * @param c2x - 第二个控制点的坐标 x 轴。
  * @param c2y - 第二个控制点的坐标 y 轴。
  * @param x - 最后一个控制点的坐标 x 轴。
  * @param y - 最后一个控制点的坐标 y 轴。
  */
	bezierCurveTo(c1x:number, c1y:number, c2x:number, c2y:number, x:number, y: number): void;
	/**
  * 绘制二次贝赛尔曲线路径。
  * @param cx - 起始控制点的坐标 x 轴。
  * @param cy - 起始控制点的坐标 y 轴。
  * @param x - 终点控制点的坐标 x 轴。
  * @param y - 终点控制点的坐标 x 轴。
  */
	quadraticCurveTo(cx: number, cy: number, x: number, y: number): void;
	/**
  * 绘制圆弧路径。圆弧路径的圆心在 (cx, cy) 位置,半径为 r 
  根据counterclockwise(默认false)指定的方向从startAngle开始绘制,到 endAngle 结束。
  * @param cx - 中心控制点的坐标 x 轴。
  * @param cy - 中心控制点的坐标 y 轴。
  * @param r - 圆弧弧度。
  * @param startAngle - 开始弧度,从正 x 轴顺时针方向测量。
  * @param endAngle - 结束弧度,从正 x 轴顺时针方向测量。
  * @param counterclockwise 如果为真,在两个角度之间逆时针绘制。默认顺时针。
  */
	arc(cx: number, cy: number, r: number, startAngle: number, endAngle: number, counterclockwise: boolean): void;
	/**
	* 绘制椭圆路径。
	* @param cx - 中心点的坐标 x 轴。
	* @param cy - 中心点的坐标 y 轴。
	* @param rx - 椭圆 x 轴半径。
	* @param ry - 椭圆 y 轴半径。
	*/
	ellipse(cx: number, cy: number, rx: number, ry: number): void;
	/**
	* 绘制圆形路径。
	* @param cx - 中心点的坐标 x 轴。
	* @param cy - 中心点的坐标 y 轴。
	* @param r - 圆半径。
	*/
	circle(cx: number, cy: number, r: number): void;
	/**
	* 绘制矩形路径。
	* @param x - 矩形起始坐标 x 轴。
	* @param y - 矩形起始坐标 y 轴。
	* @param w - 矩形宽度。
	* @param h - 矩形高度。
	*/
	rect(x: number, y: number, w: number, h: number): void;
	/**
	* 绘制圆角矩形路径。
	* @param x - 矩形起始坐标 x 轴。
	* @param y - 矩形起始坐标 y 轴。
	* @param w - 矩形宽度。
	* @param h - 矩形高度。
 	* @param r - 矩形圆角半径。
	*/
	roundRect(x: number, y: number, w: number, h: number, r: number): void;
	/**
	* 绘制填充矩形。
	* @param x - 矩形起始坐标 x 轴。
	* @param y - 矩形起始坐标 y 轴。
	* @param w - 矩形宽度。
	* @param h - 矩形高度。
	*/
	fillRect(x: any, y: any, w: any, h: any): void;
	// 擦除之前绘制的所有内容的方法
	clear(): void;
	// 将笔点返回到当前路径起始点的。它尝试从当前点到起始点绘制一条直线
	close(): void;
	// 根据当前的画线样式,绘制当前或已经存在的路径
	stroke(): void;
	// 根据当前的画线样式,填充当前或已经存在的路径
	fill(): void;
}

将这些代码从引擎提取粘贴了下,方便大家进行查阅。

下面将开始具体的示例相关,如果想在浏览器直观的显示出来,可以:

const { ccclass, property, executeInEditMode } = _decorator;
@executeInEditMode(true)			// 设置为true, 在编译器中模拟运行

绘制基础图形


主要绘制:

  • 直线样式
  • 点线样式
  • 圆/椭圆/矩形/半圆
  • 贝塞尔曲线

示例代码:

export class UI_GraphicBaseLayer extends Component {
  @property(Graphics) graphics: Graphics;

  start () {
    // 绘制直线
    this.drawLine();
    // 绘制点线
    this.drawStrokeLine();
    // 绘制图形
    this.drawGraph();
    // 绘制矩形
    this.drawRect();
    // 绘制贝塞尔曲线
    this.drawBezier();
  }

  // 绘制直线
  private drawLine() {
    // 设置线段宽度
    this.graphics.lineWidth = 10;
    // 设置线段末端样式
    this.graphics.lineCap = Graphics.LineCap.ROUND;
    // 设置画笔颜色
    this.graphics.strokeColor = Color.RED;
    // 移动路径起点
    this.graphics.moveTo(-400, 220);
    // 移动路径终点
    this.graphics.lineTo(-200, 220);
    // 绘制
    this.graphics.stroke();
    this.graphics.miterLimit = 10
  }

  // 绘制点线
  private drawStrokeLine() {
    this.graphics.strokeColor = Color.GREEN;
    this.graphics.lineWidth = 10;
    for (let i = 0; i < 5; i++) {
      this.graphics.moveTo(20 + i * 30, 220);
      this.graphics.lineTo(35 + i * 30, 220);
    }
    this.graphics.stroke();
  }

  // 绘制图形
  private drawGraph() {
    this.graphics.strokeColor = Color.BLUE;
    this.graphics.lineWidth = 10;
    this.graphics.lineCap = Graphics.LineCap.BUTT;
    // 矩形
    this.graphics.rect(250, 100, 100, 50);
    // 圆
    this.graphics.circle(-300, 100, 50);
    // 椭圆
    this.graphics.ellipse(-80, 100, 80, 40);
    // 部分圆
    this.graphics.arc(100, 100, 50, 0, Math.PI, true);

    this.graphics.fillColor = Color.BLACK;
    this.graphics.fill();
    this.graphics.stroke();
  }

  // 绘制矩形
  private drawRect() {
    this.graphics.strokeColor = Color.GREEN;
    this.graphics.lineWidth = 10;
    this.graphics.lineCap = Graphics.LineCap.BUTT;
    this.graphics.roundRect(250, -50, 150, 80, 20);
    // 设置填充颜色
    this.graphics.fillColor = Color.RED;
    // 填充
    this.graphics.fill();
    // 绘制
    this.graphics.stroke();
  }

  // 绘制贝塞尔曲线
  private drawBezier() {
    this.graphics.strokeColor = Color.MAGENTA;
    this.graphics.lineWidth = 3;
    this.graphics.moveTo(-300, -100);
    // 二次贝塞尔起点(-300,-100),结束点(-50,-100)
    this.graphics.quadraticCurveTo(-200, -200, -50, -50);

    // 上面是,下面是三次
    this.graphics.moveTo(0, -100);
    // 两个控制点 + 结束点, 三次贝塞尔
    this.graphics.bezierCurveTo(100, -200, 200, 0, 300, -100);
    this.graphics.stroke();
  }
}

示意图:
请添加图片描述


绘制星星


先看效果图:
请添加图片描述

主要实现代码:

@property(Graphics) graphics: Graphics;

start () {  
  this.drawStar(-200, 100, 100, 40, 5);
  this.drawStar(50, 100, 100, 40, 6);
  this.drawStar(300, 100, 100, 40, 7);
}

private drawStar(x: number, y: number, r: number, cr: number, starNum:number, startAngle: number = -18) {
  this.graphics.fillColor = Color.YELLOW;
  this.graphics.strokeColor = Color.RED;
  this.graphics.lineWidth = 5;
  const angle = 360 / starNum;                // 平均角度
  for (let i = 0; i < starNum; i++) {
    if (i === 0) {
      // 首次要 moveTo
      this.graphics.moveTo(
        Math.cos(toRadian(startAngle)) * r + x,
        -Math.sin(toRadian(startAngle)) * r + y
      );
    } else {
      this.graphics.lineTo(
        Math.cos(toRadian(startAngle + i * angle)) * r + x,
        -Math.sin(toRadian(startAngle + i * angle)) * r + y
      );
    }
    this.graphics.lineTo(
      Math.cos(toRadian(startAngle + 36 + i * angle)) * cr + x,
      -Math.sin(toRadian(startAngle + 36 + i * angle)) * cr + y
    );
  }
  // 最后再连接至起始点
  this.graphics.close();
  this.graphics.fill();
  this.graphics.stroke();
}

绘制线型图


先看下效果图:
请添加图片描述

它的组成主要是:

  • 行列线作为背景, 在实际的项目中,针对于行列线会使用图片代替,美观且性能高
  • 数值标记, 比如列数值,行索引
  • 折线图线段, 两点之间连线组成

这种效果,我们需要配置一些数据:

const ORIGIN_POS = new Vec2(-400, -220);            // 原点位置
const LINE_LEN = 800;                               // 行线段长度
const LINE_SPACE = 50;                              // 行间距
const COL_SAPACE = 60;                              // 列间距
const MAX_LINE = 10;                                // 最大行列数
const MAX_VAULE = 450;                              // 最大数值

通过原点位置,行列间距可以计算行的起始位置和行文本的位置

通过行线段长度和原点位置可以计算出线段结束位置,并绘制行线段

通过最大数值、最大行列数,可以计算出当前点的位置

因此行列背景和数值标记的示例代码如下:

export class UI_GraphicBrokenLineLayer extends Component {
  @property(Graphics) graphics: Graphics;                 // 绘图节点
  @property(Node) labelParent: Node;                      // 标签父节点
  
  start() {
    this.graphics.clear();
    this.labelParent.removeAllChildren();

    this.initBrokenLine();
  }

  // 初始化折线图背景
  private initBrokenLine() {
    // 初始化背景
    for(let i = 0; i < 10; ++i) {
      this.graphics.lineWidth = 4;
      this.graphics.strokeColor = Color.BLUE;
      this.graphics.moveTo(ORIGIN_POS.x, ORIGIN_POS.y + i * LINE_SPACE);
      this.graphics.lineTo(ORIGIN_POS.x + LINE_LEN, ORIGIN_POS.y + i * LINE_SPACE);
      this.graphics.stroke();
    }

    // 初始化标记文本
    for (let i = 0; i < 2; ++i) {
      for (let j = 0; j < 10; j++) {
        const labelNode = new Node("label");
        labelNode.parent = this.labelParent;
        const label = labelNode.addComponent(Label);
        label.fontSize = 20;
        label.lineHeight = 20;
        if (i === 0) {
          // 行
          const posY = (j !== 0) ? ORIGIN_POS.y  + j * LINE_SPACE : ORIGIN_POS.y  + j * LINE_SPACE - 10;
          labelNode.setPosition(v3(ORIGIN_POS.x - 30, posY, 0));
          label.string = (0 + j * 50).toString();
        } else {
          // 列(第一列不显示数字)
          labelNode.setPosition(v3(ORIGIN_POS.x + (j * COL_SAPACE), ORIGIN_POS.y - 30, 0));
          const content = (j === 0) ? "" : j.toString();
          label.string = content;
        }
      }
    }
  }

关于折线图的显示, 为了更直观,采用的是随机数值获取,并可被50整除,代码处理:

// 获取随机数值
private getRandValues(): number[] {
  const min = 0;
  const max = MAX_VAULE
  const values: number[] = [];
  for (let i = 0; i < MAX_LINE; ++i) {
    let value = Math.floor(Math.random() * (max - min + 1)) + min;
    value = Math.floor(value / 50) * 50;
    values.push(value);
  }

  return values;
}

根据每个数值需要计算点的位置,计算公式:

  • 点的位置 = 原始位置 + 点的宽度/高度
  • 点的宽度 = 当前数值/最大数值 * 最大长度
// 获取位置
private getPointPos(values: number[]): Vec2[] {
  const poses: Vec2[] = [];
  const maxColLen = (MAX_LINE - 1) * LINE_SPACE;
  for (let i = 0; i < MAX_LINE; ++i) {
    const curWidth = i * COL_SAPACE;
    const curHeight = values[i]/MAX_VAULE * maxColLen;
    const startPos = v2(ORIGIN_POS.x + curWidth, ORIGIN_POS.y + curHeight);
    poses.push(startPos);
  }
  return poses
}

最后绘制点的位置和两点之间连线

// 该接口在onStart中调用下即可
private drawBrokenLine() {
  // 获取随机数值
  const values = this.getRandValues();
  // 根据数值获取位置点
  const vecPos = this.getPointPos(values);

  // 绘制线
  for (let i = 0; i < values.length - 1; ++i) {
    const startPos = vecPos[i];
    const endPos = vecPos[i + 1];

    this.graphics.lineWidth = 4;
    this.graphics.strokeColor = Color.WHITE;
    this.graphics.lineJoin = Graphics.LineJoin.ROUND;
    this.graphics.lineCap = Graphics.LineCap.ROUND;
    this.graphics.moveTo(startPos.x, startPos.y);
    this.graphics.lineTo(endPos.x, endPos.y);
    this.graphics.stroke();
  }

  // 绘制点
  if (this._isShowPoint) {
    for (let i = 0; i < values.length; ++i) {
      const startPos = vecPos[i];
      this.graphics.lineWidth = 30;
      this.graphics.strokeColor = Color.RED;
      this.graphics.lineJoin = Graphics.LineJoin.ROUND;
      this.graphics.lineCap = Graphics.LineCap.ROUND;

      // 
      this.graphics.circle(startPos.x, startPos.y, 10);
      this.graphics.fillColor = Color.RED;
      this.graphics.fill();
      this.graphics.moveTo(startPos.x, startPos.y);
      this.graphics.lineTo(startPos.x, startPos.y);  
    }
  }
  this.graphics.stroke();
}

绘制圆柱图


先看下效果图:

请添加图片描述

理解线型图后,圆柱图其实反而就容易了, 因为它的起始位置除了X轴都是固定的,我们需要计算:

最终Y位置 = 原点Y位置 + 当前高度即可, 主要代码实现:

// 绘制柱形图
private drawPill() {
  // 获取随机数值
  const values = this.getRandValues();
  console.log(values);
  // 根据数值获取位置点
  const maxColLen = (MAX_LINE - 1) * LINE_SPACE;

  // 绘制柱形
  for (let i = 1; i < values.length; ++i) { 
    const height = values[i]/MAX_VAULE * maxColLen;
    if (height > 0) {
      const posX = ORIGIN_POS.x + (i - 0) * COL_SAPACE - 15;

      this.graphics.lineWidth = 2;
      this.graphics.lineJoin = Graphics.LineJoin.ROUND;
      this.graphics.lineCap = Graphics.LineCap.SQUARE;
      this.graphics.rect(posX, ORIGIN_POS.y, 30, height);
      this.graphics.fillColor = Color.RED;
      this.graphics.fill();
    }

  }
  this.graphics.stroke();
}

// 获取随机数值
private getRandValues(): number[] {
  const min = 0;
  const max = MAX_VAULE
  const values: number[] = [];
  for (let i = 0; i < MAX_LINE; ++i) {
    let value = Math.floor(Math.random() * (max - min + 1)) + min;
    value = Math.floor(value / 50) * 50;
    values.push(value);
  }

  return values;
}

涂鸦

涂鸦的实现,需要通过触摸点获取位置相关,进行绘画,因此主要逻辑是:

@property(Graphics) graphics_2: Graphics;           // 涂鸦绘图

protected onEnable(): void {
  this.graphics_2.node.on(Node.EventType.TOUCH_START, this.touchStartEvent, this);
	this.graphics_2.node.on(Node.EventType.TOUCH_MOVE, this.touchMoveEvent, this);
}

protected onDisable(): void {
  this.graphics_2.node.off(Node.EventType.TOUCH_START, this.touchStartEvent, this);
	this.graphics_2.node.off(Node.EventType.TOUCH_MOVE, this.touchMoveEvent, this);
}

private touchStartEvent(event: EventTouch) {
  const pos = event.getUILocation();
  const transform = this.node.getComponent(UITransform);
  const out = transform.convertToNodeSpaceAR(v3(pos.x, pos.y, 0));
  this.graphics_2.moveTo(out.x, out.y);
}

private touchMoveEvent(event: EventTouch) {
  const pos = event.getUILocation();
  const transform = this.node.getComponent(UITransform);
  const out = transform.convertToNodeSpaceAR(v3(pos.x, pos.y, 0));
  this.graphics_2.lineTo(out.x, out.y);
  this.graphics_2.stroke();
  this.graphics_2.moveTo(out.x, out.y);
}

// 点击清空
public clickClearEvent() {
  this.graphics_2.clear();
}

效果图:

请添加图片描述


其他

更多示例代码可参考Gitee UIExample

请添加图片描述

本篇博客的编写,参考了:kuokuo分享的技术博客

在这里感谢作者的分享,祝大家生活开心!

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

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

相关文章

Android Studio 创建项目不自动生成BuildConfig文件

今天在AS上新建项目发现找不到BuildConfig文件&#xff0c;怎么clear都不行。通过多方面查找发现原来gradle版本不同造成的&#xff0c;Gradle 8.0默认不生成 BuildConfig 文件。 如上图&#xff0c;8.0版本是没有source文件夹 上图是低于8.0版本有source文件夹 针对这个问题&…

Jenkins学习笔记1

CI 服务器&#xff1a; 认识Jenkins&#xff1a; Jenkins是一个可扩展的持续集成&#xff08;CI&#xff09;引擎&#xff0c;是一个开源项目&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使得软件持续集成变成可能。Jenkins非常易于安装和配置&#xff0c;简单易…

算法leetcode|83. 删除排序链表中的重复元素(rust重拳出击)

文章目录 83. 删除排序链表中的重复元素&#xff1a;样例 1&#xff1a;样例 2&#xff1a;提示&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 83. 删除排序链表中的重复元素&#xff1a; 给…

Docker从认识到实践再到底层原理(六-1)|Docker容器基本介绍+命令详解

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

vue+element plus 使用table组件,清空用户的选择项

<el-table ref"tableRef"> .... </el-table> <script lang"ts" setup> import { onMounted, reactive, ref, nextTick } from vue const clearBtn () > {console.log(清空用户的选择项)tableRef.value.clearSelection() } </scr…

【论文阅读 09】融合门控自注意力机制的生成对抗网络视频异常检测

2021年 中国图象图形学报 摘 要 背景&#xff1a; 视频异常行为检测是智能监控技术的研究重点&#xff0c;广泛应用于社会安防领域。当前的挑战之一是如何提高异常检测的准确性&#xff0c;这需要有效地建模视频数据的空间维度和时间维度信息。生成对抗网络&#xff08;GANs&…

[学习记录] 设计模式 3. 观察者模式

观察者模式 参考&#xff1a; bugstack 虫洞栈Refactoringhttps://www.cnblogs.com/myseries/p/8735490.htmlhttps://www.jianshu.com/p/4f1cd513a72d 当一个行为发生时传递信息给另外一个用户接收做出相应的处理&#xff0c;两者之间没有直接的耦合关联。 在我们编程开发中也…

9.20 QT作业

widget.h #include <QPainter> //画家 #include <QTimerEvent> #include <QTime> #include<QTimer> //定时器类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widge…

物联网如何助力乡村数字经济发展

在当今移动互联网时代&#xff0c;信息化数字化已经渗透了我们生活的方方面面&#xff0c;数字物联网转型也成为各个产业的重要动力。对于广大乡村来说&#xff0c;得益于网络基础设施的全面建成覆盖&#xff0c;乡村各产业也迎来数字化新业态转型&#xff0c;创新诞生了基于物…

高效管理,轻松追踪——Chrono Plus for Mac任务管理工具

Chrono Plus for Mac是一款专注于任务管理和跟踪的应用程序。它提供了一种直观、清晰的界面&#xff0c;使您能够轻松创建、安排和分类任务。无论是个人项目还是团队合作&#xff0c;Chrono Plus都能为您提供一种有效组织和管理任务的方式。 这个应用程序具有多种强大的功能&a…

windows Visual Studio 2022 opengl开发环境配置

1. 安装glew(GL), GLFW, glm, soil2-debug 还需要premake生成visual studio solution cmake for windows也要安装一个&#xff0c; 但是不用安装MinGW64, bug多 下载源码&#xff0c;找到xxx.sln文件用visual stidio打开solution编译代码&#xff0c;找到xxx.lib, xxx.dll文件…

嵌入式Linux--进程间通讯--消息队列

1.需要知道的问题&#xff1a; 1、如何创建消息队列&#xff08;A\B使用同一个队列通信&#xff09; 2、如何加消息到队列&#xff08;队列是链表&#xff09; 3、如何从队列拿到消息 消息队列&#xff1a; 消息队列&#xff0c;是消息的链接表&#xff0c;存放在内核中。一个…

爬虫异常处理技巧分享

在进行爬虫数据采集的过程中&#xff0c;我们常常会遇到网络波动和自动化验证等异常情况。这些问题可能导致爬虫运行中断或被识别为机器请求而受到限制。本文将分享一些实用的爬虫异常处理技巧&#xff0c;帮助您规避网络波动和自动化验证&#xff0c;提高数据采集的稳定性和成…

轻量型服务器能支撑多少人访问?

一、服务器配置影响访问人数 服务器的配置是影响轻量型服务器能够支撑的访问人数的关键因素之一。通常而言&#xff0c;轻量型服务器的配置普遍不高&#xff0c;适合小型团队或个人使用。如果服务器配置较低&#xff0c;那么支撑访问人数的能力也会受到限制。较为简单的应用程序…

在GIS(地理信息系统)中,常见的地理文件记录

在GIS&#xff08;地理信息系统&#xff09;中&#xff0c;常见的地理文件包括以下几种&#xff1a; .cpg&#xff08;Code Page文件&#xff09;&#xff1a;这个文件是指定地理数据文件编码的文件&#xff0c;它告诉软件如何正确地读取和解释地理数据文件中的字符编码。比如…

[BJDCTF2020]EasySearch Apache SSI漏洞

这道题有点意思 是SSI 漏洞 照样 我们先熟悉SSI漏洞是什么 SSI 服务端包含 SSI 提供了对现有html增加动态的效果是嵌入 html的指令 只有网页被调用了 才会执行允许执行命令 所以会造成rce 使用条件 当文件上传的时候 无法上传php但是服务器开启了 SSI CGI支持就可以通过 …

第二证券:算力概念强势拉升,竞业达涨停,南凌科技等大涨

算力概念20日盘中强势拉升&#xff0c;到发稿&#xff0c;竞业达涨停&#xff0c;南凌科技涨近10%&#xff0c;拓维信息涨近9%&#xff0c;亚康股份、神州数码涨约5%&#xff0c;青云科技涨逾4%。 音讯面上&#xff0c;9月19日&#xff0c;国际大学生程序设计竞赛&#xff08;…

Vue语法

目录 事件处理器 是什么 案列 表单的综合案列 定义 常用功能 组件通信 定义 父传子 ​编辑 子传父 事件处理器 是什么 事件处理器是一种函数&#xff0c;用于响应和处理事件的触发。在编程中&#xff0c;当特定事件发生时&#xff0c;可以通过事件处理器来执行相应的…

正则表达式的学习笔记

[!note] 其实这个正则表达式整体上不难, 自从这个 gpt 出来之后这种正则表达式已经不需要我们去写了, 我们并不需要自己能够去写特别深奥的代码, 我们可以将这个正则表达式交给 gpt 去做, 我们只需要能够看懂就行了, 所以学习这个正则表达式, 自己写不出来那种比较难的正则没有…

Apache Doris 快速入门

1. 基本概念 FE&#xff0c;Frontend&#xff0c;前端节点&#xff0c;接收用户查询请求&#xff0c;SQL解析&#xff0c;执行计划生成&#xff0c;元数据管理&#xff0c;节点管理等 BE&#xff0c;Backend&#xff0c;后端节点&#xff0c;数据存储&#xff0c;执行查询计划…