DevC++ easyx实现视口编辑--像素绘图板与贴图系统

到了最终成果阶段了,虽然中间有一些代码讲起来没有意思,纯靠debug,+1-1解决贴图网格不重合问题,这次是一个分支结束。

想着就是把瓦片贴进大地图里。

延续这几篇帖子,开发时间也从2023年的4月16到了6月2号,80小时基本砸进去才出靠谱效果。

45天平均每天两小时。

DevC++ easyx实现图片拖动,一种悬浮窗实现原理与完整代码-CSDN博客

DevC++ easyx实现悬浮窗放入网格,与在函数分离过程中遇到的BUG下理解 函数的作用时域 以及 初始化与复位的关系。-CSDN博客 DevC++ easyx实现地图拖动,超过屏幕大小的巨大地图的局部显示在屏幕的方法——用悬浮窗的原理来的实现一个视口-CSDN博客

 

这次迭代过程是,贴图放到视口上,然后视口直接再粘贴到大地图上,然后就导致绘图瓦片重叠,而且也没来及考虑复位问题,就立马意识到还没设置网格。这里走的是网格贴图路线。

然后网格检测贴图位置,属于哪个网格,鼠标松开就被嵌入到哪个网格上。

然后这里设置的是网格长宽80像素,就用了数据图像位置变换:x=x-x%80;这样保留能被80整除的部分,然后px=x/80,得到所属网格的序号,这样就存储了贴图。

至于边界,就是处理鼠标位移和大地图坐标变化的问题。视口和采样区域是1:1,或者说是视口复制粘贴到大地图上成为采样图片,所以视口上鼠标移动多少,就是采样图上移动多少,然后算出来鼠标位置和视口左上角的距离,在大地图里,可以拿采样图左上角的坐标再加上这个数据,就是鼠标实际在大地图里面的坐标。

不多说,上效果

先放一个局部代码,跑不起来,因为适配的代码太庞大,文章后面有两个版本-集成版和cpp .h组合版

extern IMAGE maptile;

void didshow(IMAGE *set,IMAGE maptile,ExMessage m,int show_x,int show_y,int nowlx,int nowly) {
	static int flag=0;
	static int oldx=-8,oldy=-8;
	int putx,puty;
	IMAGE olds(80,80);

	if(m.message==WM_LBUTTONDOWN) {

		SetWorkingImage(set);
		putx=nowlx+m.x-show_x;
		puty=nowly+m.y-show_y;
		putx=putx-putx%80;
		puty=puty-puty%80;

		putimage(putx,puty,&maptile);

		SetWorkingImage();

	} else{
		if(putx==oldx&&puty==oldy) {
		} else  {
			if(m.message==WM_LBUTTONDOWN) {
			}
			printf("show   %d %d\n",m.x,m.y);
			SetWorkingImage(set);
			putx=nowlx+m.x-show_x;
			puty=nowly+m.y-show_y;

			putx=putx-putx%80;
			puty=puty-puty%80;
			putimage(putx,puty,&maptile);

			oldx=putx;
			oldy=puty;
			SetWorkingImage();

		}

	}
}

代码比较多,先放一个整合版,.h分类版本看下面其他代码

这里是整合版。

devc++里新建项目,选择Multimedia里的Easyx

然后复制粘贴跑就行。

按键操作说明:

 “本程序采用外装easy x拓展库的DEVc++制作而成
是跳一跳游戏配套编辑器

性质与单通道技能不同,是起跳前动画

操作说明

左键长按在网格绘制
右键在网格设置锚点

拖动网格左上角图片到中间的绿色区域暂存
左键点击绿色区域,
在黄色区域的左上角就会出现相同形状,说明已选择

然后在黄色区域左键长按或者单击左键,实现贴图
黄色区域右键移动大地图

按F1 清屏
按F2 导出为 png格式图片,自动命名为“gamemap”


gamemap0,gamemap1,gamemap2....gamemap9为游戏可以读取的有效文件,分别对应关卡1,2,3,4....9

粘贴到游戏目录实现自定义背景”

这是整合版,新建项目,复制粘贴就能跑

#include<stdio.h>
#include<graphics.h>
//INputboX
#include<windows.h>
//Sleep(2000);
//在中断休止
#include <conio.h>
// kbhit(void);检测按键,无也继续下去
#include<string.h>
//保存导入输入



//#include"oripic.h"
//#include"show.h"
//#include"draw.h"
//#include"flowsave.h"
//#include"movecheck.h"
//#include"buttoncheck.h"
//#include"keycheck.h"


int w=3600;
int h=800;
int w2=3,h2=7;
int x2=650,y2=100;
int showx3=101,showy3=100;



extern int w,h; 


IMAGE set(w,h);

struct pixlocal {
	short x;
	short y;
};

struct skline {
	int lenth=0;
	int setx,sety;
	struct pixlocal a[10000];
} nf,ndnf;


struct drawdesksize {
	int x;
	int y;
	int a;
	int h;
	int sizetile=8;
	int smx;
	int smy;
} ddm;



IMAGE maptile(ddm.a/ddm.sizetile,ddm.h/ddm.sizetile);

struct pircle {
	IMAGE img2;
	IMAGE img3;
	int orilx,orily;
	int nowlx,nowly;
	int a,h;
//	原有图片的左上角坐标
	int m1x=0,m1y=0;
	int  putflag=0;
	int  drawflag=0;
	struct skline b;
} save;


struct picsave {
	int lx;
	int ly;
	int wide;
	int h;
	int useflag;
	struct skline b;
} a[28];






void oripicdesk(int a,int h) {
	initgraph(a,h,EX_SHOWCONSOLE);
	setbkcolor(WHITE);
	cleardevice();
//	创制绘图界面,背景色设置,以背景色填充。
	setlinecolor(BLACK);
	setlinestyle(PS_SOLID,1);
//	不含实线,矩形的面积为8*8;含实线,9*9.
	rectangle(0,0,a-2,h-1);
	//确定工作界面范围
	setfillcolor(WHITE);
}

void oridrawdesksize(struct drawdesksize* ddm,int x,int y) {
	ddm->x=x;
	ddm->y=y;
	ddm->a=640;
	ddm->h=640;
	ddm->sizetile=8;
	ddm->smx=ddm->x-ddm->a/ddm->sizetile;
	ddm->smy=ddm->y-ddm->h/ddm->sizetile;
}

void drawdesk(struct drawdesksize ddm) {
	int i,j;
	int square=ddm.sizetile;
	for(i=ddm.x; i<=ddm.x+ddm.a-square; i+=square) {
		for(j=ddm.y; j<ddm.y+ddm.h; j+=square) {
			fillrectangle(i,j,i+square,j+square);
		}
	}
	rectangle(ddm.smx-1,ddm.smy-1,ddm.x,ddm.y);
}

void oripircle(struct pircle *save,struct drawdesksize *ddm) {
	save->orilx=ddm->smx,save->orily=ddm->smy;
	save->nowlx=ddm->smx,save->nowly=ddm->smy;
	save->a=ddm->a/ddm->sizetile;
	save->h=ddm->h/ddm->sizetile;
//	原有图片的左上角坐标
	save->m1x=0,save->m1y=0;
	save->putflag=0;
	save->drawflag=0;
}



void oriset(IMAGE *set,struct drawdesksize ddm,int w,int h) {

	SetWorkingImage(set);
	setbkcolor(YELLOW);

	cleardevice();
	setlinecolor(BLACK);

	for(int i=0; i<h; i+=ddm.a/ddm.sizetile) {
		for(int j=0; j<w; j+=ddm.h/ddm.sizetile)
			rectangle(j+1,i+1,j+ddm.a/ddm.sizetile,i+ddm.h/ddm.sizetile);
	}
	line(0, 0, 800, 1400);
	SetWorkingImage();
}






extern struct skline nf,ndnf;


extern IMAGE maptile;

void didshow(IMAGE *set,IMAGE maptile,ExMessage m,int show_x,int show_y,int nowlx,int nowly) {
	static int flag=0;
	static int oldx=-8,oldy=-8;
	int putx,puty;
	IMAGE olds(80,80);

	if(m.message==WM_LBUTTONDOWN) {

		SetWorkingImage(set);
		putx=nowlx+m.x-show_x;
		puty=nowly+m.y-show_y;
		putx=putx-putx%80;
		puty=puty-puty%80;

		putimage(putx,puty,&maptile);

		SetWorkingImage();

	} else{
		if(putx==oldx&&puty==oldy) {
		} else  {
			if(m.message==WM_LBUTTONDOWN) {
			}
			printf("show   %d %d\n",m.x,m.y);
			SetWorkingImage(set);
			putx=nowlx+m.x-show_x;
			puty=nowly+m.y-show_y;

			putx=putx-putx%80;
			puty=puty-puty%80;
			putimage(putx,puty,&maptile);

			oldx=putx;
			oldy=puty;
			SetWorkingImage();

		}

	}
}




void show(IMAGE *set,ExMessage m,int show_x,int show_y,int show_wideth,int show_height) {
//	视口的图片大小,视口的大小,在窗口的坐标,视口的大小
	static int nowlx,nowly,pic_wide,pic_heigh;
	static int m1x,m1y;
	static int drawflag,putflag,attachflag;
	static	IMAGE olds(show_wideth,show_height);
	static	IMAGE news(show_wideth,show_height);
	static int m2x,m2y;
//	加速移动设置,自动移动设置。
	static int flag=1;

	if(flag==1) {
		pic_wide=show_wideth;
		pic_heigh=show_height;
		m1x=0;
		m1y=0;
		m2x=0;
		m2y=0;
		drawflag=0;
		putflag=0;
		attachflag=0;
		flag=0;
		setlinecolor(BLACK);
		rectangle(show_x,show_y,show_x+show_wideth,show_y+show_height);
		BeginBatchDraw();
		SetWorkingImage(set);
		getimage(&olds,nowlx,nowly,pic_wide,pic_heigh);
		SetWorkingImage();
		putimage(show_x,show_y,&olds);
		EndBatchDraw();
	} else {
		if(m.message==WM_LBUTTONDOWN) {

			if(m.ctrl&&m.x>show_x&&m.x<show_x+show_wideth&&m.y>show_y&&m.y<show_y+show_height) {
				putflag=true;
//					启动批复制粘贴
//					printf("%d\n",door.putflag);
				SetWorkingImage(set);
				getimage(&olds,nowlx,nowly,pic_wide,pic_heigh);
//					获取视口里的图片
//
				m1x=m.x;
				m1y=m.y;
				m2x=m.x;
				m2y=m.y;
//					printf("%d %d\n",m1x,m1y);
				SetWorkingImage();
			} else if (m.x>show_x&&m.x<show_x+show_wideth&&m.y>show_y&&m.y<show_y+show_height) {
//				printf("333333\n");


				didshow(set,maptile,m,show_x,show_y,nowlx,nowly);

				attachflag=true;
			}



		} else if(attachflag==true&&m.x>show_x&&m.x<show_x+show_wideth&&m.y>show_y&&m.y<show_y+show_height) {
			didshow(set,maptile,m,show_x,show_y,nowlx,nowly);
			if(m.message==WM_LBUTTONUP) {
				attachflag=false;
			}
			SetWorkingImage(set);
			getimage(&olds,nowlx,nowly,pic_wide,pic_heigh);
			SetWorkingImage();
			putimage(show_x,show_y,&olds);
		} else if(putflag==true) {
	
			BeginBatchDraw();
			SetWorkingImage();


			SetWorkingImage(set);

			nowlx=nowlx-5*(m.x-m1x);
			nowly=nowly-5*(m.y-m1y);
//			进行了位移放大。
//			位移同鼠标位移方向相反,大小相同
			m1x=m.x;
			m1y=m.y;
			getimage(&olds,nowlx,nowly,pic_wide,pic_heigh);
//			获取新地方的底图,为了下次重现,不干扰下次获取临近底图。
//		putimage(save->nowlx,save->nowly,&save->img2);
			SetWorkingImage();
			putimage(show_x,show_y,&olds);
//			putimage(500,500,&save->img3);

			EndBatchDraw();

//			一次绘图出来,没有屏闪了
			if(m.message==WM_LBUTTONUP||m.ctrl==0) {
				putflag=0;
			}
		}
	}

}










extern IMAGE maptile;

//用于设置绘图画布大小 




//用于记录轨迹 
void remem(struct ExMessage m,int *lenth,struct drawdesksize ddm) {
	int i=*lenth;
	static int oldx=-ddm.sizetile,
	           oldy=-ddm.sizetile,
	           a=ddm.sizetile,
	           h=ddm.sizetile;
	if(m.x>oldx&&m.x<oldx+a&&m.y>oldy&&m.y<oldy+h) {
//节约运算,只在绘制时进行坐标变换
	} else {

		int px=0,py=0,qx=0,qy=0;
		int mapqx=0,mapqy=0;
		//修正可涂色范围,防止溢出。y<不可等于640+100,x等于640+600-1是边界小方块的最右侧像素
		px=m.x-ddm.x;
		py=m.y-ddm.y;
		//修正600的偏移,601=600+1;0==1%8 ,600=600+(601-600)%8
		qx=px-px%a;
		qy=py-py%h;
		
		mapqx=qx/a;
		mapqy=qy/h;
		
		px=ddm.x+qx;
		py=ddm.y+qy;

		

		setfillcolor(BLACK);
		fillrectangle(px,py,px+ddm.sizetile,py+ddm.sizetile) ;
		nf.a[i].x = mapqx;
		nf.a[i].y = mapqy;


		i++;
		*lenth=i;
		nf.lenth=*lenth;


		printf("%d %d %d\n",i-1,nf.a[i-1].x,nf.a[i-1].y);
		putpixel(ddm.smx+nf.a[i-1].x,ddm.smy+nf.a[i-1].y,BLACK);
		oldx=px;
		oldy=py;


	}
}


void draw(ExMessage m,int *lenth) {
//	绘制的函数
	static int flag=0;
	if(m.message==WM_LBUTTONDOWN) {
		remem(m,lenth,ddm);
//		printf("222\n");
		flag=1;
	} else if(flag==1) {
		remem(m,lenth,ddm);
		if(m.message==WM_LBUTTONUP) {
			flag=0;
		}
	}
}





void drawmousecheck(ExMessage m,int *lenth,struct drawdesksize * ddm) {
 
		if(m.x>ddm->x&&m.x<ddm->x+ddm->a&&m.y>ddm->y&&m.y<ddm->y+ddm->h) {
			draw(m,lenth);
//			printf("333\n");
		}
	

}




void oriflowsave(int x,int y,int w,int h){
	setfillcolor(GREEN);
		int i;
		int num=0;
		for(int j=0; j<h; j++) {
			for(i=1; i<=w; i++) {
				a[num].lx=x+1+i*81;
				a[num].ly=y+1+j*81;
				a[num].wide=80;
				a[num].h=80;
				a[num].useflag=0;
				fillrectangle(a[num].lx,a[num].ly,a[num].lx+a[num].wide,a[num].ly+a[num].h);
				num++;
			}
		}
}

void rehave(ExMessage m,int w,int h) {
	int i;
	int num=0;
	for(int j=0; j<w; j++) {
		for(i=1; i<=h;i++) {
			if(m.x>a[num].lx&&m.x<a[num].lx+a[num].wide&&m.y>a[num].ly&&m.y<a[num].ly+a[num].h) {
				if(a[num].useflag==1) {
					ndnf=a[num].b;
					break;
				}
			}
			num++;
		}
	}
}

void pickpen(ExMessage m,int w,int h) {
	int i,j;
	int num=0;
	for(j=0; j<w; j++) {
		for(i=1; i<=h; i++) {
			if(m.x>a[num].lx&&m.x<a[num].lx+a[num].wide&&m.y>a[num].ly&&m.y<a[num].ly+a[num].h) {
				if(a[num].useflag==1) {
					getimage(&maptile,a[num].lx,a[num].ly,80,80);
					fillrectangle(20,80,100,160);
					putimage(20,80,&maptile);
				}
			}
			num++;
		}
	}
}

void flowsave(ExMessage m,struct pircle *save,int w,int h) {
	if(m.message==WM_LBUTTONDOWN) {
		pickpen(m,w,h);
	} else if(m.message==WM_LBUTTONUP) {
//		单机直接粘贴bug但是可以作为长按的刷新,接入其他地方
		int i;
		int num=0;
		for(int j=0; j<w; j++) {
			for(i=1; i<=h; i++) {
				if(m.x>a[num].lx&&m.x<a[num].lx+a[num].wide&&m.y>a[num].ly&&m.y<a[num].ly+a[num].h) {
					if(a[num].useflag==0) {
						a[num].b=nf;

						if(save->nowlx!=save->orilx&&save->nowly!=save->orily) {
							putimage(save->nowlx,save->nowly,&save->img3);
						} else {
							getimage(&save->img2,save->orilx,save->orily,save->a,save->h);
						}
						putimage(a[num].lx,a[num].ly,&save->img2);



						save->nowlx=save->orilx;
						save->nowly=save->orily;
						save->m1x=0;
						save->m1y=0;
//						printf("%d\n",save->m1x);
						save->putflag=false;
						a[num].useflag=1;
						break;
					}
				}
				num++;
			}
		}
	}
	if(m.message==WM_RBUTTONDOWN) {
		rehave(m,w,h);
	}

}





extern int w2,h2;


void movecheck(struct ExMessage m,struct pircle *save) {

	if(save->putflag==0&&m.message==WM_LBUTTONDOWN) {
		if(save->m1x==0&&save->m1y==0&&m.x>save->orilx&&m.x<save->orilx+save->a&&m.y>save->orily&&m.y<save->orily+save->h) {
			getimage(&save->img2,save->orilx,save->orily,save->a,save->h);
			getimage(&save->img3,save->orilx,save->orily,save->a,save->h);
			save->m1x=m.x;
			save->m1y=m.y;
			save->putflag=true;
			printf("2222\n");
		} else if(m.x>save->nowlx&&m.x<save->nowlx+save->a&&m.y>save->nowly&&m.y<save->nowly+save->h) {
			save->putflag=true;
			getimage(&save->img2,save->orilx,save->orily,save->a,save->h);

			save->m1x=m.x;
			save->m1y=m.y;
//			printf("11111\n");
		}
	} else if(save->putflag==true) {
		BeginBatchDraw();

		putimage(save->nowlx,save->nowly,&save->img3);
		save->nowlx=save->nowlx+m.x-save->m1x;
		save->nowly=save->nowly+m.y-save->m1y;
		save->m1x=m.x;
		save->m1y=m.y;
		getimage(&save->img3,save->nowlx,save->nowly,save->a,save->h);
		putimage(save->nowlx,save->nowly,&save->img2);

		EndBatchDraw();

		if(m.message==WM_LBUTTONUP) {
			save->putflag=0;
		}
//			一次绘图出来,没有屏闪了
	}

}


void buttonscheck(ExMessage m,struct pircle *save) {
	static int flag=0;
	if(flag==0) {
		rectangle(20,20,60,40);
		flowsave(m,save,w2,h2);
		flag=1;
	}
	movecheck(m,save);


	flowsave(m,save,w2,h2);
	

}




extern IMAGE set;



//重置绘图版功能
void ori(struct drawdesksize ddm) {

	int i,j;
	int square=ddm.sizetile;
	setfillcolor(WHITE);
	setlinecolor(GREEN);
	for(i=ddm.x; i<=ddm.x+ddm.a-square; i+=square) {
		for(j=ddm.y; j<ddm.y+ddm.h; j+=square) {
			fillrectangle(i,j,i+square,j+square);
		}
	}
	for(i=ddm.smx; i<ddm.smx+ddm.a/ddm.sizetile; i++) {
		for(j=ddm.smy; j<ddm.smy+ddm.h/ddm.sizetile; j++) {
		putpixel(i,j,WHITE);
		}
	}
//	rectangle(ddm.smx-1,ddm.y-1,ddm.x,ddm.y);

}


void pixnf(int lenth,struct drawdesksize ddm) {
//		小地图打印
	int i=0;
	for(i=0; i<lenth; i++) {
		putpixel(ddm.smx+nf.a[i].x,ddm.smy+nf.a[i].y,WHITE);
		if(i%55==0)
			Sleep(1);
	}
	for(i=0; i<lenth; i++) {
		putpixel(ddm.smx+nf.a[i].x,ddm.smy+nf.a[i].y,BLACK);
		if(i%55==0)
			Sleep(1);
	}
}

void keycheck(ExMessage m,int *lenth) {
	switch(m.vkcode) {
		case VK_F1:
			ori(ddm);
			*lenth=0;
//				优化清屏后叠加在小地图bug'
			break;


		case VK_F2 :
			saveimage(_T("gamemap.png"),&set);

			break;

		case VK_F5 :
			static int limf5=0;
			if(limf5==0) {
				pixnf(*lenth,ddm);

				limf5=1;
				break;
			} else {
				limf5=0;
			}
//				限制一次按动,一次调用,因为获取getmessage函数有连续两次探测。

			break;
	}

}




int main() {

	oripicdesk(1800,870);
	oridrawdesksize(&ddm,1000,100);
	oripircle(&save,&ddm);
	oriset(&set,ddm,w,h);
//初始化表格,界面
	setlinecolor(BLACK);
	oriflowsave(x2,y2,w2,h2);
	drawdesk(ddm);
	


	ExMessage m;
	int lenth=0;

	while (1) {
		m = getmessage(EX_MOUSE | EX_KEY);
		drawmousecheck(m,&lenth,&ddm);
		
		keycheck(m,&lenth);

		buttonscheck(m,&save);

		show(&set,m,showx3,showy3,600,700);
	}

	closegraph();


	return 0;
}

 

上面的整合版本是展示

下面是实际开发.h组合cpp的版本

 分类说明

.h版本的功能模块

主函数,可以看出来一次循环执行内容,功能与名称相统一。

main.cpp文件代码

新建项目,复制粘贴,有的保存为cpp,有的保存为.h文件

原始版本:

#include<stdio.h>
#include<graphics.h>
//INputboX
#include<windows.h>
//Sleep(2000);
//在中断休止
#include <conio.h>
// kbhit(void);检测按键,无也继续下去
#include<string.h>
//保存导入输入


#include"oripic.h"
#include"show.h"
#include"draw.h"
#include"flowsave.h"
#include"movecheck.h"
#include"buttoncheck.h"
#include"keycheck.h"


int w=3600;
int h=800;
int w2=3,h2=7;
int x2=650,y2=100;
int showx3=101,showy3=100;


int main() {

	oripicdesk(1800,870);
	oridrawdesksize(&ddm,1000,100);
	oripircle(&save,&ddm);
	oriset(&set,ddm,w,h);
//初始化表格,界面
	setlinecolor(BLACK);
	oriflowsave(x2,y2,w2,h2);
	drawdesk(ddm);
	


	ExMessage m;
	int lenth=0;

	while (1) {
		m = getmessage(EX_MOUSE | EX_KEY);
		drawmousecheck(m,&lenth,&ddm);
		
		keycheck(m,&lenth);

		buttonscheck(m,&save);

		show(&set,m,showx3,showy3,600,700);
	}

	closegraph();


	return 0;
}




 

oripic.h文件代码

初始化,但是这个函数属于最后写的,把一些代码整合,美观一点。其他没啥用




extern int w,h; 


IMAGE set(w,h);

struct pixlocal {
	short x;
	short y;
};

struct skline {
	int lenth=0;
	int setx,sety;
	struct pixlocal a[10000];
} nf,ndnf;


struct drawdesksize {
	int x;
	int y;
	int a;
	int h;
	int sizetile=8;
	int smx;
	int smy;
} ddm;



IMAGE maptile(ddm.a/ddm.sizetile,ddm.h/ddm.sizetile);

struct pircle {
	IMAGE img2;
	IMAGE img3;
	int orilx,orily;
	int nowlx,nowly;
	int a,h;
//	原有图片的左上角坐标
	int m1x=0,m1y=0;
	int  putflag=0;
	int  drawflag=0;
	struct skline b;
} save;


struct picsave {
	int lx;
	int ly;
	int wide;
	int h;
	int useflag;
	struct skline b;
} a[28];






void oripicdesk(int a,int h) {
	initgraph(a,h,EX_SHOWCONSOLE);
	setbkcolor(WHITE);
	cleardevice();
//	创制绘图界面,背景色设置,以背景色填充。
	setlinecolor(BLACK);
	setlinestyle(PS_SOLID,1);
//	不含实线,矩形的面积为8*8;含实线,9*9.
	rectangle(0,0,a-2,h-1);
	//确定工作界面范围
	setfillcolor(WHITE);
}

void oridrawdesksize(struct drawdesksize* ddm,int x,int y) {
	ddm->x=x;
	ddm->y=y;
	ddm->a=640;
	ddm->h=640;
	ddm->sizetile=8;
	ddm->smx=ddm->x-ddm->a/ddm->sizetile;
	ddm->smy=ddm->y-ddm->h/ddm->sizetile;
}

void drawdesk(struct drawdesksize ddm) {
	int i,j;
	int square=ddm.sizetile;
	for(i=ddm.x; i<=ddm.x+ddm.a-square; i+=square) {
		for(j=ddm.y; j<ddm.y+ddm.h; j+=square) {
			fillrectangle(i,j,i+square,j+square);
		}
	}
	rectangle(ddm.smx-1,ddm.smy-1,ddm.x,ddm.y);
}

void oripircle(struct pircle *save,struct drawdesksize *ddm) {
	save->orilx=ddm->smx,save->orily=ddm->smy;
	save->nowlx=ddm->smx,save->nowly=ddm->smy;
	save->a=ddm->a/ddm->sizetile;
	save->h=ddm->h/ddm->sizetile;
//	原有图片的左上角坐标
	save->m1x=0,save->m1y=0;
	save->putflag=0;
	save->drawflag=0;
}



void oriset(IMAGE *set,struct drawdesksize ddm,int w,int h) {

	SetWorkingImage(set);
	setbkcolor(YELLOW);

	cleardevice();
	setlinecolor(BLACK);

	for(int i=0; i<h; i+=ddm.a/ddm.sizetile) {
		for(int j=0; j<w; j+=ddm.h/ddm.sizetile)
			rectangle(j+1,i+1,j+ddm.a/ddm.sizetile,i+ddm.h/ddm.sizetile);
	}
	line(0, 0, 800, 1400);
	SetWorkingImage();
}

 

这就是本篇文案解决的问题后产生的代码,

可以和DevC++ easyx实现悬浮窗放入网格,与在函数分离过程中遇到的BUG下理解 函数的作用时域 以及 初始化与复位的关系。-CSDN博客

与DevC++ easyx实现地图拖动,超过屏幕大小的巨大地图的局部显示在屏幕的方法——用悬浮窗的原理来的实现一个视口-CSDN博客 

对比看一看代码,这就是视口编辑代码的族谱。 

视口代码。maptile就是粘贴的瓦片,set就是大地图,其他函数参数是视口位置坐标,自己换点数据试试,自然而然。

show.h文件代码






extern struct skline nf,ndnf;


extern IMAGE maptile;

void didshow(IMAGE *set,IMAGE maptile,ExMessage m,int show_x,int show_y,int nowlx,int nowly) {
	static int flag=0;
	static int oldx=-8,oldy=-8;
	int putx,puty;
	IMAGE olds(80,80);

	if(m.message==WM_LBUTTONDOWN) {

		SetWorkingImage(set);
		putx=nowlx+m.x-show_x;
		puty=nowly+m.y-show_y;
		putx=putx-putx%80;
		puty=puty-puty%80;

		putimage(putx,puty,&maptile);

		SetWorkingImage();

	} else{
		if(putx==oldx&&puty==oldy) {
		} else  {
			if(m.message==WM_LBUTTONDOWN) {
			}
			printf("show   %d %d\n",m.x,m.y);
			SetWorkingImage(set);
			putx=nowlx+m.x-show_x;
			puty=nowly+m.y-show_y;

			putx=putx-putx%80;
			puty=puty-puty%80;
			putimage(putx,puty,&maptile);

			oldx=putx;
			oldy=puty;
			SetWorkingImage();

		}

	}
}




void show(IMAGE *set,ExMessage m,int show_x,int show_y,int show_wideth,int show_height) {
//	视口的图片大小,视口的大小,在窗口的坐标,视口的大小
	static int nowlx,nowly,pic_wide,pic_heigh;
	static int m1x,m1y;
	static int drawflag,putflag,attachflag;
	static	IMAGE olds(show_wideth,show_height);
	static	IMAGE news(show_wideth,show_height);
	static int m2x,m2y;
//	加速移动设置,自动移动设置。
	static int flag=1;

	if(flag==1) {
		pic_wide=show_wideth;
		pic_heigh=show_height;
		m1x=0;
		m1y=0;
		m2x=0;
		m2y=0;
		drawflag=0;
		putflag=0;
		attachflag=0;
		flag=0;
		setlinecolor(BLACK);
		rectangle(show_x,show_y,show_x+show_wideth,show_y+show_height);
		BeginBatchDraw();
		SetWorkingImage(set);
		getimage(&olds,nowlx,nowly,pic_wide,pic_heigh);
		SetWorkingImage();
		putimage(show_x,show_y,&olds);
		EndBatchDraw();
	} else {
		if(m.message==WM_LBUTTONDOWN) {

			if(m.ctrl&&m.x>show_x&&m.x<show_x+show_wideth&&m.y>show_y&&m.y<show_y+show_height) {
				putflag=true;
//					启动批复制粘贴
//					printf("%d\n",door.putflag);
				SetWorkingImage(set);
				getimage(&olds,nowlx,nowly,pic_wide,pic_heigh);
//					获取视口里的图片
//
				m1x=m.x;
				m1y=m.y;
				m2x=m.x;
				m2y=m.y;
//					printf("%d %d\n",m1x,m1y);
				SetWorkingImage();
			} else if (m.x>show_x&&m.x<show_x+show_wideth&&m.y>show_y&&m.y<show_y+show_height) {
//				printf("333333\n");


				didshow(set,maptile,m,show_x,show_y,nowlx,nowly);

				attachflag=true;
			}



		} else if(attachflag==true&&m.x>show_x&&m.x<show_x+show_wideth&&m.y>show_y&&m.y<show_y+show_height) {
			didshow(set,maptile,m,show_x,show_y,nowlx,nowly);
			if(m.message==WM_LBUTTONUP) {
				attachflag=false;
			}
			SetWorkingImage(set);
			getimage(&olds,nowlx,nowly,pic_wide,pic_heigh);
			SetWorkingImage();
			putimage(show_x,show_y,&olds);
		} else if(putflag==true) {
	
			BeginBatchDraw();
			SetWorkingImage();


			SetWorkingImage(set);

			nowlx=nowlx-5*(m.x-m1x);
			nowly=nowly-5*(m.y-m1y);
//			进行了位移放大。
//			位移同鼠标位移方向相反,大小相同
			m1x=m.x;
			m1y=m.y;
			getimage(&olds,nowlx,nowly,pic_wide,pic_heigh);
//			获取新地方的底图,为了下次重现,不干扰下次获取临近底图。
//		putimage(save->nowlx,save->nowly,&save->img2);
			SetWorkingImage();
			putimage(show_x,show_y,&olds);
//			putimage(500,500,&save->img3);

			EndBatchDraw();

//			一次绘图出来,没有屏闪了
			if(m.message==WM_LBUTTONUP||m.ctrl==0) {
				putflag=0;
			}
		}
	}

}

 

draw.h文件代码

这是绘制瓦片纹理的像素绘图板的绘制矩形像素部分。

做了一点优化,如果还是属于原来的方块,就不执行绘制了。减少重复绘制。







extern IMAGE maptile;

//用于设置绘图画布大小 




//用于记录轨迹 
void remem(struct ExMessage m,int *lenth,struct drawdesksize ddm) {
	int i=*lenth;
	static int oldx=-ddm.sizetile,
	           oldy=-ddm.sizetile,
	           a=ddm.sizetile,
	           h=ddm.sizetile;
	if(m.x>oldx&&m.x<oldx+a&&m.y>oldy&&m.y<oldy+h) {
//节约运算,只在绘制时进行坐标变换
	} else {

		int px=0,py=0,qx=0,qy=0;
		int mapqx=0,mapqy=0;
		//修正可涂色范围,防止溢出。y<不可等于640+100,x等于640+600-1是边界小方块的最右侧像素
		px=m.x-ddm.x;
		py=m.y-ddm.y;
		//修正600的偏移,601=600+1;0==1%8 ,600=600+(601-600)%8
		qx=px-px%a;
		qy=py-py%h;
		
		mapqx=qx/a;
		mapqy=qy/h;
		
		px=ddm.x+qx;
		py=ddm.y+qy;

		

		setfillcolor(BLACK);
		fillrectangle(px,py,px+ddm.sizetile,py+ddm.sizetile) ;
		nf.a[i].x = mapqx;
		nf.a[i].y = mapqy;


		i++;
		*lenth=i;
		nf.lenth=*lenth;


		printf("%d %d %d\n",i-1,nf.a[i-1].x,nf.a[i-1].y);
		putpixel(ddm.smx+nf.a[i-1].x,ddm.smy+nf.a[i-1].y,BLACK);
		oldx=px;
		oldy=py;


	}
}


void draw(ExMessage m,int *lenth) {
//	绘制的函数
	static int flag=0;
	if(m.message==WM_LBUTTONDOWN) {
		remem(m,lenth,ddm);
//		printf("222\n");
		flag=1;
	} else if(flag==1) {
		remem(m,lenth,ddm);
		if(m.message==WM_LBUTTONUP) {
			flag=0;
		}
	}
}





void drawmousecheck(ExMessage m,int *lenth,struct drawdesksize * ddm) {
 
		if(m.x>ddm->x&&m.x<ddm->x+ddm->a&&m.y>ddm->y&&m.y<ddm->y+ddm->h) {
			draw(m,lenth);
//			printf("333\n");
		}
	

}

flowsave.h文件

绿色网格检测白色瓦片用于暂存。


void oriflowsave(int x,int y,int w,int h){
	setfillcolor(GREEN);
		int i;
		int num=0;
		for(int j=0; j<h; j++) {
			for(i=1; i<=w; i++) {
				a[num].lx=x+1+i*81;
				a[num].ly=y+1+j*81;
				a[num].wide=80;
				a[num].h=80;
				a[num].useflag=0;
				fillrectangle(a[num].lx,a[num].ly,a[num].lx+a[num].wide,a[num].ly+a[num].h);
				num++;
			}
		}
}

void rehave(ExMessage m,int w,int h) {
	int i;
	int num=0;
	for(int j=0; j<w; j++) {
		for(i=1; i<=h;i++) {
			if(m.x>a[num].lx&&m.x<a[num].lx+a[num].wide&&m.y>a[num].ly&&m.y<a[num].ly+a[num].h) {
				if(a[num].useflag==1) {
					ndnf=a[num].b;
					break;
				}
			}
			num++;
		}
	}
}

void pickpen(ExMessage m,int w,int h) {
	int i,j;
	int num=0;
	for(j=0; j<w; j++) {
		for(i=1; i<=h; i++) {
			if(m.x>a[num].lx&&m.x<a[num].lx+a[num].wide&&m.y>a[num].ly&&m.y<a[num].ly+a[num].h) {
				if(a[num].useflag==1) {
					getimage(&maptile,a[num].lx,a[num].ly,80,80);
					fillrectangle(20,80,100,160);
					putimage(20,80,&maptile);
				}
			}
			num++;
		}
	}
}

void flowsave(ExMessage m,struct pircle *save,int w,int h) {
	if(m.message==WM_LBUTTONDOWN) {
		pickpen(m,w,h);
	} else if(m.message==WM_LBUTTONUP) {
//		单机直接粘贴bug但是可以作为长按的刷新,接入其他地方
		int i;
		int num=0;
		for(int j=0; j<w; j++) {
			for(i=1; i<=h; i++) {
				if(m.x>a[num].lx&&m.x<a[num].lx+a[num].wide&&m.y>a[num].ly&&m.y<a[num].ly+a[num].h) {
					if(a[num].useflag==0) {
						a[num].b=nf;

						if(save->nowlx!=save->orilx&&save->nowly!=save->orily) {
							putimage(save->nowlx,save->nowly,&save->img3);
						} else {
							getimage(&save->img2,save->orilx,save->orily,save->a,save->h);
						}
						putimage(a[num].lx,a[num].ly,&save->img2);



						save->nowlx=save->orilx;
						save->nowly=save->orily;
						save->m1x=0;
						save->m1y=0;
//						printf("%d\n",save->m1x);
						save->putflag=false;
						a[num].useflag=1;
						break;
					}
				}
				num++;
			}
		}
	}
	if(m.message==WM_RBUTTONDOWN) {
		rehave(m,w,h);
	}

}

 

 

 movecheck.h文件

就是DevC++ easyx实现图片拖动,一种悬浮窗实现原理与完整代码-CSDN博客

 





extern int w2,h2;


void movecheck(struct ExMessage m,struct pircle *save) {

	if(save->putflag==0&&m.message==WM_LBUTTONDOWN) {
		if(save->m1x==0&&save->m1y==0&&m.x>save->orilx&&m.x<save->orilx+save->a&&m.y>save->orily&&m.y<save->orily+save->h) {
			getimage(&save->img2,save->orilx,save->orily,save->a,save->h);
			getimage(&save->img3,save->orilx,save->orily,save->a,save->h);
			save->m1x=m.x;
			save->m1y=m.y;
			save->putflag=true;
			printf("2222\n");
		} else if(m.x>save->nowlx&&m.x<save->nowlx+save->a&&m.y>save->nowly&&m.y<save->nowly+save->h) {
			save->putflag=true;
			getimage(&save->img2,save->orilx,save->orily,save->a,save->h);

			save->m1x=m.x;
			save->m1y=m.y;
//			printf("11111\n");
		}
	} else if(save->putflag==true) {
		BeginBatchDraw();

		putimage(save->nowlx,save->nowly,&save->img3);
		save->nowlx=save->nowlx+m.x-save->m1x;
		save->nowly=save->nowly+m.y-save->m1y;
		save->m1x=m.x;
		save->m1y=m.y;
		getimage(&save->img3,save->nowlx,save->nowly,save->a,save->h);
		putimage(save->nowlx,save->nowly,&save->img2);

		EndBatchDraw();

		if(m.message==WM_LBUTTONUP) {
			save->putflag=0;
		}
//			一次绘图出来,没有屏闪了
	}

}


void buttonscheck(ExMessage m,struct pircle *save) {
	static int flag=0;
	if(flag==0) {
		rectangle(20,20,60,40);
		flowsave(m,save,w2,h2);
		flag=1;
	}
	movecheck(m,save);


	flowsave(m,save,w2,h2);
	

}

keycheck.h文件

这个是按键实现保存,清屏处理。

这也是软件快捷键的执行的代码。




extern IMAGE set;



//重置绘图版功能
void ori(struct drawdesksize ddm) {

	int i,j;
	int square=ddm.sizetile;
	setfillcolor(WHITE);
	setlinecolor(GREEN);
	for(i=ddm.x; i<=ddm.x+ddm.a-square; i+=square) {
		for(j=ddm.y; j<ddm.y+ddm.h; j+=square) {
			fillrectangle(i,j,i+square,j+square);
		}
	}
	for(i=ddm.smx; i<ddm.smx+ddm.a/ddm.sizetile; i++) {
		for(j=ddm.smy; j<ddm.smy+ddm.h/ddm.sizetile; j++) {
		putpixel(i,j,WHITE);
		}
	}
//	rectangle(ddm.smx-1,ddm.y-1,ddm.x,ddm.y);

}


void pixnf(int lenth,struct drawdesksize ddm) {
//		小地图打印
	int i=0;
	for(i=0; i<lenth; i++) {
		putpixel(ddm.smx+nf.a[i].x,ddm.smy+nf.a[i].y,WHITE);
		if(i%55==0)
			Sleep(1);
	}
	for(i=0; i<lenth; i++) {
		putpixel(ddm.smx+nf.a[i].x,ddm.smy+nf.a[i].y,BLACK);
		if(i%55==0)
			Sleep(1);
	}
}

void keycheck(ExMessage m,int *lenth) {
	switch(m.vkcode) {
		case VK_F1:
			ori(ddm);
			*lenth=0;
//				优化清屏后叠加在小地图bug'
			break;


		case VK_F2 :
			saveimage(_T("gamemap.png"),&set);

			break;

		case VK_F5 :
			static int limf5=0;
			if(limf5==0) {
				pixnf(*lenth,ddm);

				limf5=1;
				break;
			} else {
				limf5=0;
			}
//				限制一次按动,一次调用,因为获取getmessage函数有连续两次探测。

			break;
	}

}

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】进程控制深度了解

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握Linux下的进程控制 > 毒鸡汤&#xff…

Spring Boot快速搭建一个简易商城项目【四,优化购物车篇】

在之前的基础上继续将购物车进行完善&#xff1a;全选&#xff0c;删除&#xff0c;加减购物车数量 效果&#xff1a; 全选&#xff1a; 计算价格&#xff1a; //计算总价function jisuan(){let total 0;$(".th").each((i,el)>{//each遍历 i下标 el指的是当前的…

Goole上架年度总结(2023年)

今天来总结一下2023年关于谷歌商店上架的相关政策改动和对应的拒审解决方法。 目录 政策更新与改动2023 年 2 月 22 日2023 年 4 月5 日2023 年 7 月 12 日2023 年 10 月 25 日 开发者计划政策拒审邮件内容和解决办法 政策更新与改动 2023 年 2 月 22 日 生效日期&#xff1…

普中STM32-PZ6806L开发板(HAL库函数实现-TIM5捕获上升沿, 获取输入频率)

简介 通过TIM5_CH1捕获上升沿电平, 两个上升沿的计数值计算频率;电路原理图 连接图 将 PC7 与 PA0使用跳线进行连接 其他知识 APIs /* Blocking mode: Polling */ HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); // 堵塞捕获开启 HAL_St…

什么是高防 IP?哪些行业适合用高防 IP?

在数字化浪潮席卷全球的今天&#xff0c;网络安全问题日益凸显。有听说过“高防 IP”这个名词吗&#xff1f;它究竟是什么东西&#xff0c;又能在哪些领域大显身手呢&#xff1f; 一、什么是高防 IP&#xff1f; 高防 IP&#xff0c;顾名思义&#xff0c;就是具备高级防护能力…

深度生成模型之图像翻译GAN ->(个人学习记录笔记)

文章目录 深度生成模型之图像翻译GAN图像翻译的应用1. 风格迁移2. 数据增强3. 经典图像任务4. 内容创作5. 人脸图像编辑6. 人体图像编辑 图像翻译模型1. 有监督图像翻译模型2. 无监督图像翻译模型3. 多域图像翻译模型 深度生成模型之图像翻译GAN 图像翻译的应用 1. 风格迁移 …

Vue:使用IDEA开发Vue的相关配置

一、IDEA无法识别.vue文件 1、IDEA 添加Vue插件 2、添加Vue配置 File | Settings | Editor | File Types 找到 HTML 文件 在下面点号 输入*.vue 二、IDEA无法创建.vue文件 1、问题 在开发过程中&#xff0c;发现创建文件的界面&#xff0c;没有vue模板 2、相关配置 Fi…

MATLAB指令

01--根据数学公式进行绘制 1.绘制连续函数 ①一元函数 t0:0.1:10; y3*t2; plot(t,y) ②一元二次函数 t0:0.1:10; yt.*t; plot(t,y) 注意此处应为点乘 ③一元3次 t0:0.1:10; yt.*t.*t; plot(t,y) ④y1/t t0:0.1:10; y1./t; plot(t,y) ⑤yexp(t) t0:0.1:10; yexp(2*t); p…

BIO和NIO编程(待完善)

目录 IO模型 BIO NIO 常见问题 IO模型 Java共支持3种网络编程IO模式&#xff1a;BIO&#xff0c;NIO&#xff0c;AIO BIO 同步阻塞模型&#xff0c;一个客户端连接对应一个处理线程 代码示例&#xff1a; Server端&#xff1a; public class BioServer {private static …

ARM NEON 指令

NEON指令 按照操作数类型可以分为正常指令、宽指令、窄指令、饱和指令、长指令。 正常指令&#xff1a;生成大小相同且类型通常与操作数向量相同到结果向量。长指令&#xff1a;对双字向量操作数执行运算&#xff0c;生产四字向量到结果。所生成的元素一般是操作数元素宽度到…

PS插件一键生成超治愈向日葵花海

金黄色的向日葵总能给人带来治愈的感觉&#xff0c;仿佛在这里能够疗愈心灵所有的伤口。今天我们通过START AI来生成一片美丽的向日葵花海~ 这是小编使用的关键词&#xff0c;负面词需要填写你不想要拥有的&#xff0c;能够让生成的结果更贴合你的想法 最后的生成效果就如下图…

清风数学建模写作

Overview 标题 摘要&#xff01;&#xff01;&#xff01;&#xff08;1000字&#xff09; 开头 中间 解决的问题 应用的方法 得到的结果 结尾 应用价值、本文亮点 关键词&#xff08;3-6个&#xff09; 积累、二次拓展 目录 1.问题重述 拆分背景与问题&#xff0c;也可以结…

菜鸟之MATLAB学习——QPSK OQPSK信号生成及频谱分析

本人MATLAB学习小白&#xff0c;仅做笔记记录和分享~~ % qpsk && oqpsk clc; close all;Ts1; fc10;N_sample16; N_sum100; dt1/fc/N_sample; t0:dt:N_sum*Ts-dt; Tdt*length(t);d1sign(randn(1,N_sum)); d2sign(randn(1,N_sum));gtones(1,fc*N_sample); …

Java基础综合练习(飞机票,打印素数,验证码,复制数组,评委打分,数字加密,数字解密,抽奖,双色球)

练习一&#xff1a;飞机票 需求: ​ 机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。 ​ 按照如下规则计算机票价格&#xff1a;旺季&#xff08;5-10月&#xff09;头等舱9折&#xff0c;经济舱8.5折&#xff0c;淡季&#xff08;11月到来…

产品电子画册用什么工具可以轻松制作

​随着互联网的普及和移动设备的增多&#xff0c;电子画册已经成为了企业宣传和产品展示的重要工具。然而&#xff0c;制作电子画册并不是一件容易的事情&#xff0c;需要耗费大量的时间和精力。现在&#xff0c;我们可以通过使用一些专业的工具来轻松制作产品电子画册&#xf…

想升职or转岗,可以考一个PMP吗?

现在就业形式比较严峻&#xff0c;如果不想被淘汰&#xff0c;就得提升自己的能力&#xff0c;增加自己的职场竞争力&#xff0c;今天就来推荐一个能在工作中起到非常大重要的证书--pmp项目管理证书。 首先&#xff0c;pmp是什么呢&#xff1f; PMP是由美国项目管理协会&…

Windows搭建Emby媒体库服务器,无公网IP远程访问本地影音文件

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

UCOSIII移植

1、“sys.h” 头文件修改 //0,不支持ucos //1,支持ucos #define SYSTEM_SUPPORT_OS 1 //定义系统文件夹是否支持UCOS2、stm32f10x_it.c中断屏蔽 注释掉void PendSV_Handler(void) 和 void SysTick_Handler(void)中断 //void PendSV_Handler(void) //{ //} // //void Sys…

New!DevExpress WinForms v23.2系统环境配置要求

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…

创建x11vnc系统进程

为方便使用vnc&#xff0c;所以寻找到一个比较好用的vnc服务端那就是x11vnc&#xff0c;索性就创建了一个系统进程 一、环境 系统&#xff1a;银河麒麟v4-sp2-server 软件&#xff1a;x11vnc【linux下】、VNCviewer【win下】 二、安装x11vnc 1、挂载光盘源并修改apt源 mou…