瓦片地图编辑器——实现卡马克卷轴的编辑,键盘控制游戏移动和鼠标点击游戏编辑通过同一个视口实现。

news2024/9/28 17:35:51

 

左边是游戏地图编辑区,右边是地图缓冲区,解决了地图缓冲区拖动bug,成功使得缓冲区可以更新。

AWSD进行移动

鼠标左右键分别是绘制/拖动

按F1健导出为mapv3.txt

F2清空数组

打印的是游戏数组

easyx开发devcpp 5.11 easyx20220922版本

#include <graphics.h>
#include <stdio.h>
#define ROW 150						// 游戏地图行 
#define COLUMN 150					// 游戏地图列 
//#define ROW 20						// 游戏地图行
//#define COLUMN 20					// 游戏地图列
#define PIXNUM 30						// 一个瓦片边长为 30 像素 
#define SHOWSIZE 10						// 一个视口边长为 5 个瓦片 
#define BUFFERSIZE 3					// 地图缓冲区边长 3 个视口 
#define SHOWSPEED 4						// 游戏地图背景移动速度 
#define SHOWX 300						// 游戏显示区域 
#define SHOWY 300
typedef struct area {
	int lx;								// 左上角坐标
	int ly;
	int rx;								// 右上角坐标
	int ry;
	int high;							// 高度
	int wide;
} area;

typedef struct checkBackgroundBuffer {	// 用于记录缓冲条件的临界数据
	int xmin;
	int ymin;
	int xmax;
	int ymax;
	int adjust;
} bklimit;

typedef struct background {				// 游戏地图背景
	area gamepos;						// 采样区相对于缓冲区的坐标
	area deskpos;						// 改 bug 整理得到一个新结构体,把窗口坐标封装了
	int nowpointx;						// 在整个地图数组映射形成的地图上的坐标
	int nowpointy;
	IMAGE *gamebk;
} bk;

typedef struct backgroundBuffer {							// 游戏背景缓冲区
	area meshpos;
	int meshrow;
	int meshcolumn;
	bklimit bufferlimit;
	IMAGE *mapmesh;											// 缓冲区,长宽各为 3*size*a 个像素
} bkbuffer;
int map[ROW][COLUMN]= {0};
//int map[ROW][COLUMN]= {
//	{0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
//	{0,0,0,0,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
//	{0,0,0,0,0, 0,0,1,0,0, 0,0,2,0,2, 0,0,0,0,0},
//	{0,0,0,0,0, 0,0,0,0,2, 0,0,0,2,0, 0,0,0,0,0},
//	{0,0,0,0,1, 0,0,0,0,0, 0,0,1,0,0, 1,0,0,0,0},
//
//	{0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
//	{0,0,0,0,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
//	{0,0,0,0,0, 0,0,1,0,0, 0,0,2,0,2, 0,0,0,0,0},
//	{0,0,0,0,0, 0,0,0,0,2, 0,0,0,2,0, 0,0,0,0,0},
//	{0,0,0,0,1, 0,0,0,0,0, 0,0,1,0,0, 1,0,0,0,0},
//
//	{0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
//	{0,0,0,0,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
//	{0,0,0,0,0, 0,0,1,0,0, 0,0,2,0,2, 0,0,0,0,0},
//	{0,0,0,0,0, 0,0,0,0,2, 0,0,0,2,0, 0,0,0,0,0},
//	{0,0,0,0,1, 0,0,0,0,0, 0,0,1,0,0, 1,0,0,0,0},
//
//	{0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
//	{0,0,0,0,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
//	{0,0,0,0,0, 0,0,1,0,0, 0,0,2,0,2, 0,0,0,0,0},
//	{0,0,0,0,0, 0,0,0,0,2, 0,0,0,2,0, 0,0,0,0,0},
//	{0,0,0,0,1, 0,0,0,0,0, 0,0,1,0,0, 1,0,0,0,0},
//};

int pixnum=PIXNUM;											// 瓦片的大小正方形像素瓦片的边长
int showsize=SHOWSIZE;
int buffersize = BUFFERSIZE;
bk bkgd;													// background
bkbuffer bkgdbu;											// backgroundbuffer
IMAGE b(3*showsize*pixnum,3*showsize*pixnum);				// mapmesh 缓冲区
IMAGE a(showsize*pixnum,showsize*pixnum);					// 采样区,采样的到的图片就是屏幕上的游戏
// 清除地图
void clearmap();
// 保存编辑完的地图
void savemap();
//读取txt字符表格作为背景数组
void loadmap();
//检测背景是否需要更新
bool buchange() {
	bool changeflag=0;
	while(bkgd.gamepos.lx>bkgdbu.bufferlimit.xmax) {		// if else if变 while 解决鼠标拖动,导致的多次平移问题
		bkgd.gamepos.lx-=bkgdbu.bufferlimit.adjust;
		bkgdbu.meshpos.lx+=showsize;
		changeflag=1;
		printf("死循环\n");
	}
	while(bkgd.gamepos.lx<bkgdbu.bufferlimit.xmin) {
		bkgd.gamepos.lx+=bkgdbu.bufferlimit.adjust;
		bkgdbu.meshpos.lx-=showsize;
		changeflag=1;
	}
	while(bkgd.gamepos.ly>bkgdbu.bufferlimit.ymax) {
		bkgd.gamepos.ly-=bkgdbu.bufferlimit.adjust;
		bkgdbu.meshpos.ly+=showsize;
		changeflag=1;
	}
	while(bkgd.gamepos.ly<bkgdbu.bufferlimit.ymin) {
		bkgd.gamepos.ly+=bkgdbu.bufferlimit.adjust;
		bkgdbu.meshpos.ly-=showsize;
		changeflag=1;
	}
	return changeflag;
}
//刷新背景缓冲区
void freshbuffer() {
	SetWorkingImage(bkgdbu.mapmesh);							// 选择缓冲区为更新对象
	for(int i=0; i<bkgdbu.meshrow; i++) {
		for(int j=0; j<bkgdbu.meshcolumn; j++) {
			switch (map[i+bkgdbu.meshpos.ly][j+bkgdbu.meshpos.lx]) {	// 解决x坐标与数组的对应关系 第二个方括号【】是列数,是横坐标x,控制第几列
				case 0:
					setfillcolor(BLACK);						// 二维数组瓦片是 0,则选择黑色瓦片
					break;
				case 1:
					setfillcolor(WHITE);						// 二维数组瓦片是 1,则选择白色瓦片
					break;
				case 2:
					setfillcolor(GREEN);						// 二维数组瓦片是 2,则选择绿色瓦片
					break;
				case 3:
					setfillcolor(BLUE);							// 二维数组瓦片是 3,则选择蓝色瓦片
					break;
			}
			fillrectangle(j*pixnum,i*pixnum,(j+1)*pixnum,(i+1)*pixnum);						// 贴图瓦片
		}
	}
	SetWorkingImage();
}

//刷新屏幕
void show() {
	SetWorkingImage(bkgdbu.mapmesh);														// 从缓冲区采样
	getimage(bkgd.gamebk,bkgd.gamepos.lx,bkgd.gamepos.ly,showsize*pixnum,showsize*pixnum);
	SetWorkingImage();
	putimage(bkgd.deskpos.lx,bkgd.deskpos.ly,bkgd.gamebk);									// 打印采样区,理解连续更新
	putimage(700,pixnum,bkgdbu.mapmesh);
	if(bkgd.gamebk==NULL) {
		printf("图片是空的\n");
	}
	if(bkgdbu.mapmesh==NULL) {
		printf("图片是空的\n");
	}
}

//检测鼠标是否在某一区域
bool checkarea(ExMessage m,area deskpos) {
	if(m.x>deskpos.lx&&m.y>deskpos.ly&&m.x<deskpos.rx&&m.y<deskpos.ry) {
		return true;
	} else {
		return false;
	}
}

//修改背景数组
void draw(ExMessage msg) {
	int mapx=0;																// 在采样区的坐标
	int mapy=0;
	int mapi=0;																// 当前所在的背景数组瓦片坐标
	int mapj=0;
	int allmapi;															// 对应整个数组的坐标
	int allmapj;
	static int oldmapi=0;													// 上一次绘制的背景数组坐标瓦片坐标
	static int oldmapj=0;
	static int drawflag=0;
	if(drawflag==1&&checkarea(msg,bkgd.deskpos)) {
		mapx=msg.x-bkgd.deskpos.lx;											// 相对于游戏窗口左上角的坐标距离
		mapy=msg.y-bkgd.deskpos.ly;
		mapi=(mapy+bkgd.gamepos.ly)/pixnum;									// 整除瓦片边长,算出来是在缓冲区的哪个瓦片
		mapj=(mapx+bkgd.gamepos.lx)/pixnum;
		allmapi=mapi+bkgdbu.meshpos.ly;										// 计算在相对于整个地图数组左上角 (0,0) 的瓦片位置
		allmapj=mapj+bkgdbu.meshpos.lx;
		if(oldmapi!=allmapi||oldmapj!=allmapj) {							// 如果不相同,才进行绘制, 节约运算
			oldmapi=allmapi;
			oldmapj=allmapj;
			map[allmapi][allmapj]=2;										// 缓冲区的那个瓦片坐标实际上是原来完整地图的那个瓦片坐标。
			printf("游戏采样区网格坐标 x = %d,  y = %d\n",mapj,mapi);
			freshbuffer();
		}
	}
	if(msg.message ==WM_LBUTTONDOWN&&checkarea(msg,bkgd.deskpos)) {
		mapx=msg.x-bkgd.deskpos.lx;											// 相对于游戏窗口左上角的坐标距离
		mapy=msg.y-bkgd.deskpos.ly;
		mapi=(mapy+bkgd.gamepos.ly)/pixnum;									// 整除瓦片边长,算出来是在缓冲区的哪个瓦片
		mapj=(mapx+bkgd.gamepos.lx)/pixnum;
		allmapi=mapi+bkgdbu.meshpos.ly;										// 计算在相对于整个地图左上角 (0,0) 的数组瓦片位置
		allmapj=mapj+bkgdbu.meshpos.lx;
		oldmapi=allmapi;
		oldmapj=allmapj;
		map[allmapi][allmapj]=2;
		printf("游戏采样区网格坐标 x = %d,  y = %d\n",mapj,mapi);
		printf("游戏采样区像素坐标 x = %d,  y = %d\n",bkgd.gamepos.lx,bkgd.gamepos.ly);
		printf("游戏缓冲区网格坐标 x = %d,  y = %d\n",bkgdbu.meshpos.lx,bkgdbu.meshpos.ly);
		freshbuffer();
		drawflag=1;
	} else if(msg.message==WM_LBUTTONUP) {
		drawflag=0;
	}
}
// 右键拖动游戏地图——用坐标变换是无解的,因为鼠标位移detalx detaly的范围持续更新给了数据,
void draft(ExMessage msg) {
	static int flag=0;
	static int oldmx=0;														// 鼠标右键时的鼠标像素坐标
	static int oldmy=0;
	static int gamex=bkgd.nowpointx;										// 旧的采样区位置,加上鼠标拖动的位移就是新的采样区位置
	static int gamey=bkgd.nowpointy;
	SetWorkingImage();
	if(msg.message == WM_RBUTTONDOWN&&checkarea(msg,bkgd.deskpos)) {
		flag=1;																// 长按flag
		oldmx=msg.x;														// 记录拖动的起点
		oldmy=msg.y;
		gamex=bkgd.nowpointx;												// 只能使用绝对坐标,相对坐标 bkgd.gamepos.lx 坐标范围是 0-2*showsize*pixnum ,但是相对坐标可以通过记录改写,但是不如绝对坐标直观好写
		gamey=bkgd.nowpointy;
		printf("msg.x = %d,msg.y = %d\n",msg.x,msg.y);
	} else if(flag==1) {
		bkgd.nowpointx =gamex- (msg.x-oldmx);								// 图片移动的距离等于鼠标移动的距离
		bkgd.nowpointy =gamey- (msg.y-oldmy);								// 移动方向和鼠标移动方向相反
		bkgd.gamepos.lx=bkgd.nowpointx-bkgdbu.meshpos.lx*pixnum;			// 绝对坐标和相对坐标的变换,游戏采样区的像素坐标和网格坐标在buchange() 函数里重新分配,保证游戏采样区的像素坐标范围在 0-2*showsize*pixnum 里
		bkgd.gamepos.ly=bkgd.nowpointy-bkgdbu.meshpos.ly*pixnum;			// nowpointx y 像素坐标改变,然后再修改网格坐标,网格坐标修改完,再到buchange()里增加修改绝对像素坐标
//		printf("msg.x = %d,msg.y = %d\n",msg.x,msg.y);
	}
	if(msg.message == WM_RBUTTONUP) {
		flag=0;
	}
}

//按键移动
void move(ExMessage msg) {
	static int flag_a=0;
	static int flag_d=0;
	static int flag_w=0;
	static int flag_s=0;
	static int movespeed=SHOWSPEED;					// 移动速度
	if(msg.message==WM_KEYDOWN) {		// 开始游戏某个方向移动
		switch(msg.vkcode) {
			case 0x41:					// A
				flag_a=movespeed;
				break;
			case 0x44:					// D
				flag_d=movespeed;
				break;
			case 0x57:					// W
				flag_w=movespeed;
				break;
			case 0x53:					// S
				flag_s=movespeed;
				break;
		}
	} else if(msg.message==WM_KEYUP) {	// 取消某一方向的持续移动
		switch(msg.vkcode) {
			case 0x41:					// A
				flag_a=0;
				break;
			case 0x44:					// D
				flag_d=0;
				break;
			case 0x57:					// W
				flag_w=0;
				break;
			case 0x53:					// S
				flag_s=0;
				break;
		}
	}
//	if(>&&<){
//		+=flah_a;
//	}else{
//		+=flag_a;
//	}
	bkgd.gamepos.lx-=flag_a;			// 左移采样区
	bkgd.gamepos.lx+=flag_d;			// 右移采样区
	bkgd.gamepos.ly-=flag_w;			// 上移采样区
	bkgd.gamepos.ly+=flag_s;			// 下移采样区
}

//初始化地图缓冲区
void initbkbuffer() {
	bkgdbu.mapmesh = &b;													// 挂载地图缓冲区
	bkgdbu.meshpos.lx=0;
	bkgdbu.meshpos.ly=0;
	bkgdbu.meshrow=BUFFERSIZE*showsize;
	bkgdbu.meshcolumn=BUFFERSIZE*showsize;
	bkgdbu.bufferlimit.adjust=showsize*pixnum;								// 缓冲区需要更新的临界条件
	bkgdbu.bufferlimit.xmax=2*showsize*pixnum;								// 超过九宫格就立即更新,采样区默认在九宫格的中心
	bkgdbu.bufferlimit.xmin=0;
	bkgdbu.bufferlimit.ymax=2*showsize*pixnum;
	bkgdbu.bufferlimit.xmin=0;
	freshbuffer();
	SetWorkingImage();
//	putimage(700,pixnum,bkgdbu.mapmesh);									// 缓冲区可视化
}
//初始化地图采样区
void initbk() {
	bkgd.gamebk = &a;														// 如果是在这里声明临时变量 a ,函数执行完毕之后,程序就会销毁变量
	bkgd.gamepos.lx=showsize*pixnum;										// 采样区默认位置
	bkgd.gamepos.ly=showsize*pixnum;
	bkgd.nowpointx=bkgd.gamepos.lx;											// 绝对位置,用于解决gamepos 范围在 0~2*showsize*pixnum 导致的笔刷绘制失败bug
	bkgd.nowpointy=bkgd.gamepos.ly;											// 打表检测,读表时发现的绘制位置始终在一个区域内,才发现的这个bug
	bkgd.deskpos.lx=SHOWX;													// 采样之后的粘贴位置
	bkgd.deskpos.ly=SHOWY;
	bkgd.deskpos.rx=bkgd.deskpos.lx+showsize*pixnum;						// 粘贴区域的大小,用于检测鼠标指针是否在该区域内绘制
	bkgd.deskpos.ry=bkgd.deskpos.ly+showsize*pixnum;
	SetWorkingImage(bkgdbu.mapmesh);
	getimage(bkgd.gamebk,bkgd.gamepos.lx,bkgd.gamepos.ly,showsize*pixnum,showsize*pixnum);					// 加载屏幕地图,开始采样
	SetWorkingImage();
	putimage(bkgd.deskpos.lx,bkgd.deskpos.ly,bkgd.gamebk);					// 粘贴采样结果
}

int main() {
	initgraph(1800,800,1);
	setbkcolor(GREEN);
	cleardevice();
	loadmap();																// 加载地图
	clearmap();
	initbkbuffer();
	initbk();
	ExMessage msg;
	while(1) {
		peekmessage(&msg,EX_KEY|EX_MOUSE,true);
		move(msg);															// 键盘awsd检查
		draft(msg);															// 鼠标右键拖动检查
		draw(msg);															// 鼠标左键绘制
		if(buchange()) {
			freshbuffer();													// 刷新九宫格缓冲区
			printf("九宫格已刷新\n");
		}
		if(msg.message==WM_KEYDOWN) {
			if(msg.vkcode==VK_F1) {
				savemap();
			} else if(msg.vkcode== VK_F2) {
				clearmap();
			}
		}
		show();																// 打印缓冲区,打印新的采样结果,更新游戏背景, 结算完毕统一显示
		Sleep(2);
	}

	return 0;
}
//清楚地图 
void clearmap() {
	for(int i=0; i<ROW; i++) {
		for(int j=0; j<COLUMN; j++) {
			if(i==0||j==0) {
				map[i][j]=1;
			} else {
				map[i][j]=0;
			}
		}
	}
	printf("freash gammap\n");
}
// 保存地图
void savemap() {
	FILE* fp;
	fp=fopen("mapv3.txt","w");
	for(int i=0; i<ROW; i++) {
		for(int j=0; j<COLUMN; j++) {
			fprintf(fp," %d",map[i][j]);
		}
		fprintf(fp,"\n");
	}
	fclose(fp);
	printf("save gammap\n");
	for(int i=0; i<ROW; i++) {
		for(int j=0; j<COLUMN; j++) {
			printf(" %d",map[i][j]);
		}
	}
	printf("map 显示已完成\n");
}

//加载地图
void loadmap() {
	FILE* fp;
	fp=fopen("mapv2.txt","r");
	for(int i=0; i<ROW; i++) {
		for(int j=0; j<COLUMN; j++) {
			fscanf(fp," %d",&map[i][j]);
		}
		fscanf(fp,"\n");
	}
	fclose(fp);
	printf("gammap\n");
	for(int i=0; i<ROW; i++) {
		for(int j=0; j<COLUMN; j++) {
			printf(" %d",map[i][j]);
		}
		printf("\n");
	}
}

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

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

相关文章

《GreenPlum系列》GreenPlum初级教程-GreenPlum详细入门教程

文章目录 GreenPlum详细入门教程第一章 GreenPlum介绍1.MPP架构介绍2.GreenPlum介绍3.GreenPlum数据库架构4.GreenPlum数据库优缺点 第二章 GreenPlum单节点安装1.Docker创建centos容器1.1 拉取centos7镜像1.2 创建容器1.3 进入容器1.4 容器和服务器免密操作1.4.1 生成密钥1.4.…

手动导入jar包到Maven的解决方案(简单有效!)

想要导入一个jar包到项目中&#xff0c;这个jar包在Maven中没有可以尝试以下方式。 第一步 先找到你maven的本地仓库&#xff0c;我的仓库就在这里&#xff0c;你可以根据你安装的maven找到你的目录 第二步 根据坐标创建文件夹。 这个依赖modbus4j.jar&#xff0c;Maven远…

TCP三握四挥(面试需要)

TCP建立连接需要三次握手过程&#xff0c;关闭连接需要四次挥手过程 三次握手 从图中可以看出&#xff0c;客户端在发起connect时&#xff0c;会发起第一次和第三次握手。服务端在接收客户端连接时&#xff0c;会发起第二次握手。 这三次握手&#xff0c;都会通过SYNACK的方式…

论文翻译:On Bringing Robots Home

On Bringing Robots Home 关于引入机器人到家庭 文章目录 On Bringing Robots Home关于引入机器人到家庭1 Introduction1 引言2 Technical Components and Method2 技术组件与方法2.1 Hardware Design2.1 硬件设计2.2 Pretraining Dataset – Homes of New York2.2 预训练数据…

AI研究必备!这些网站你不可不知

AI研究必备&#xff01;这些网站你不可不知 在人工智能的浪潮中&#xff0c;你是否感到手足无措&#xff1f;别担心&#xff0c;今天我就为大家揭晓那些AI研究者们的秘籍——他们常用的网站。这些网站不仅包含了丰富的资源&#xff0c;还能让你的研究之路更加顺畅。让我们一起…

numpy 多项式拟合函数polyfit的使用

import numpy as np def fit(x,y,m,w):if len(x)<m:return Falsexishu np.polyfit(x,y,m,ww)p np.poly1d(xishu) # 构造多项式yfit p(x) # 拟合的y值yresid y - yfit # 残差SSresid sum(pow(yresid, 2)) # 残差平方和SStotal len(y) * np.var(y) # 总体平均方差if SSt…

JAVA用Zxing生成的二维码扫码桩识别出现\000026

使用Zxing生成的二维码&#xff0c;扫码桩扫描偶先扫描出\000026 文章目录 [TOC](文章目录) 前言一、出现原因分析二、解决方式三、iso ECI 字符集编码说明 前言 Hutool QrCodeUtil&#xff08;底层Zxing&#xff09; 生成二维码扫码桩扫描二维码 出现类似&#xff1a;"\…

80.网游逆向分析与插件开发-背包的获取-自动化助手显示物品数据

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;升级Notice类获得背包基址-CSDN博客 码云地址&#xff08;ui显示角色数据 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;3be017de38c50653b1…

Linux: make/Makefile 相关的知识

背景&#xff1a; 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的 规则来指定&#xff0c;哪些文件需要先编译&#xff0c…

【MySQL·8.0·源码】subquery 子查询处理分析(一)

引言 在 SQL 中&#xff0c;子查询属于 Nested Query 的一种形式&#xff0c;根据 Kim 的分类[1]&#xff0c;Nested Query 即嵌套查询是一种 SQL-like 形式的查询语句嵌套在另一 SQL 中&#xff0c;SQL-like 的嵌套子句可以出现在 SELECT、FROM 和 WHERE 子句的任意位置。 在…

数据结构之最优二叉树

数据结构之最优二叉树 1、最优二叉树2、哈夫曼编码 数据结构是程序设计的重要基础&#xff0c;它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发&#xff0c;分析和研究计算机加工的数据的特性&#xff0c;以便为应用所涉及的数…

Elment UI的el-table-column表头旁边有点击按钮类似的操作

Elment UI的el-table-column表头旁边有点击按钮类似的操作 <el-table-column fixed"right" label"操作" ><!-- 表头 --> {{-- <template slot"header" header"scope">--}} {{-- <span…

uniapp设置隐藏原生导航栏(3)

1、单个页面隐藏 在pages.json里配置 (第一种方式) {"path": "pages/home/index","style": {"navigationBarTitleText": "首页","navigationStyle": "custom" // 使用自定义导航栏&#xff0c;系统会关…

在 EggJS 中实现 Redis 上锁

配置环境 下载 Redis Windows 访问 https://github.com/microsoftarchive/redis/releases 选择版本进行下载 - 勾选 [配置到环境变量] - 无脑下一步并安装 命令行执行&#xff1a;redis-cli -v 查看已安装的 Redis 版本&#xff0c;能成功查看就表示安装成功啦~ Mac brew i…

企业内部知识库搭建教程,赶紧收藏起来

在企业运营中&#xff0c;内部知识库搭建是一项重要的挑战&#xff0c;并需要合理的规划与管理。尤其对于中大型企业&#xff0c;内部知识库能够提高工作效率&#xff0c;减轻员工工作压力与突发事件的处理的困扰。下面给大家提供一份完整的内部知识库搭建教程&#xff0c;快看…

如何自信地部署人工智能(AI)

提升业务价值的人工智能方法 人工智能 (AI) 已经在变革业务、降低成本、最大限度地提高收入并增强客户体验。许多组织开始注意到&#xff1a;到 2025 年&#xff0c;AI 市场规模预计将增长到 3909 亿美元&#xff0c;而且该领域的行业也呈现出类似的发展趋势——例如&#xff…

常用界面设计组件 —— 容器组件

2.6 容器组件2.6.1 QGroupBox2.6.2 QScrollArea2.6.3 QToolBox2.6.4 QTabWidget2.6.5 QStackedWidget 2.6 容器组件 为了将界面上的各个组件的分布设计得更加美观&#xff0c;经常 使用一些容器类&#xff0c;如 QgoupBox、QtabWidget、 QToolBox等。 2.6.1 QGroupBox 实例效…

YOLOv7调用摄像头检测报错解决

yolov7detect.py文件调用本地摄像头&#xff0c;把source参数设为0 parser.add_argument(--source, typestr, default0, helpsource) # file/folder, 0 for webcam 报错&#xff1a;cv2.error: OpenCV(3.4.2) 一堆地址:The function is not implemented. Rebuild the library…

洛谷 P1705 爱与愁过火

测试用例 5 2 8 1 7 2 5 4#include<iostream> #include<string.h> using namespace std; int m, r, n; int a[100]; int visit[100] {0}; int sum 0; void traceback(int s,int price,int next){if(s r){if (price > n)sum;return ;}for (int i next ;i &…

Linux命令大全(超详细版)

一 ~ 四章 【点击此处查看】 五、shell 编程 5.1、shell 概述 5.1.1 shell 是什么 Shell是一个命令行解释器&#xff0c;它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序&#xff0c;用户可以用Shell来启动、挂起、停止甚至是编写一些程序。 Shell还是…