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)%8qx=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)%8qx=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;}}
相关文章:

DevC++ easyx实现视口编辑--像素绘图板与贴图系统
到了最终成果阶段了,虽然中间有一些代码讲起来没有意思,纯靠debug,1-1解决贴图网格不重合问题,这次是一个分支结束。 想着就是把瓦片贴进大地图里。 延续这几篇帖子,开发时间也从2023年的4月16到了6月2号,80小时基本…...

Visual studio 2010的安装与使用
一、下载及安装 1、下载软件。 百度网盘: 链接:https://pan.baidu.com/s/115RibV7dOI_y8LUGW-94cA?pwd4hrs 提取码:4hrs 2、右键解压下载好的文件。 3、找到cn_visual_2010_……/Setup.hta,双击运行。 4、选择第三个“ Visual…...

Download Monitor Email Lock下载监控器邮件锁插件
打开Download Monitor Email Lock下载监控器邮件锁插件 Download Monitor Email Lock下载监控器邮件锁插件下载监视器的电子邮件锁定扩展允许您要求用户在获得下载访问权限之前填写他们的电子邮件地址。 Download Monitor Email Lock下载监控器邮件锁插件用法 安装扩展程序后…...

在vscode中创建任务编译module源文件
接昨天的文章 [创建并使用自己的C模块(Windows10MSVC)-CSDN博客],觉得每次编译转到命令行下paste命令过于麻烦,于是研究了一下在vscode中创建自动编译任务。 经过尝试,在task.json中增加如下代码: {"…...
element ui级连选择,lazyLoad选择地区
ui文档上直接给了一函数 先试试看效果是什么,加上let id0;不然会报错 props: {lazy: true,lazyLoad (node, resolve) {let id 0;const { level } node;setTimeout(() > {const nodes Array.from({ length: level 1 })//创建一个新数组,数组长度l…...

软件测试基础知识详解
1、黑盒测试、白盒测试、灰盒测试 1.1 黑盒测试 黑盒测试 又叫 功能测试、数据驱动测试 或 基于需求规格说明书的功能测试。该类测试注重于测试软件的功能性需求。 采用这种测试方法,测试工程师把测试对象看作一个黑盒子,完全不考虑程序内部的逻辑结构…...

Linux之进程管理
什么是进程 在linux中每个执行的程序都称为一个进程,每个进程都分配一个ID号(pid进程号)。每个进程都可能以两种方式存在,即前台和后天。前台进程就是用户目前的屏幕上可以进行操作的。后台进程则是实际在操作,但屏幕…...

动画墙纸:将视频、网页、游戏、模拟器变成windows墙纸——Lively Wallpaper
文章目录 前言下载github地址:网盘 关于VideoWebpagesYoutube和流媒体ShadersGIFs游戏和应用程序& more:Performance:多监视器支持:完结 前言 Lively Wallpaper是一款开源的视频壁纸桌面软件,类似 Wallpaper Engine,兼容 Wal…...
187.【2023年华为OD机试真题(C卷)】阿里巴巴找黄金宝箱(I)(贪心算法-JavaPythonC++JS实现)
请到本专栏顶置查阅最新的华为OD机试宝典 点击跳转到本专栏-算法之翼:华为OD机试 🚀你的旅程将在这里启航!本专栏所有题目均包含优质解题思路,高质量解题代码,详细代码讲解,助你深入学习,深度掌握! 文章目录 【2023年华为OD机试真题(C卷)】阿里巴巴找黄金宝箱(…...

Ubuntu22.04系统安装软件、显卡驱动、cuda、cudnn、pytorch
Ubuntu22.04系统安装软件、显卡驱动、cuda、cudnn、pytorch 安装 Nvidia 显卡驱动安装 CUDA安装 cuDNN安装 VSCode安装 Anaconda 并更换源在虚拟环境中安装 GPU 版本的 PyTorchReference 这篇博文主要介绍的是 Ubuntu22.04 系统中软件、显卡驱动、cuda、cudnn、pytorch 等软件和…...

基于矩阵乘的CUDA编程优化过程
背景:网上很多关于矩阵乘的编程优化思路,本着看理论分析万遍,不如实际代码写一遍的想法,大概过一下优化思路。 矩阵乘的定义如下,约定矩阵的形状及存储方式为: A[M, K], B[K, N], C[M, N]。 CPU篇 朴素实现方法 按照…...

layuiadmin新建tabs标签页,点击保存,打开新的标签页并刷新
用的layuiamin前端框架 需求:新增的页面为一个标签页,保存后,需要刷新列表 1、新建customMethod.js文件,自定义自己的方法 layui.define(function (exports) {var $ layui.$var customMethod {// 表单点击保存后,…...
Rxjs概念 学习
RxJS 是一个流式编程库,用于处理异步数据流和事件流。它基于观察者模式和迭代器模式,提供了丰富的操作符和工具,用于处理和操作数据流。RxJS 的核心概念包括可观察对象(Observable)、观察者(Observer&#…...
pillow像型学操作(转载笔记) --- 西北乱跑娃
Opencv、Matplotlib(plt)、Pillow(PIL)、Pytorch读取数据的通道顺序 需注意:Pillow加载图像后的尺寸是二维,图形化是三维,但无法打印三维尺寸。 详细区别: Opencv:uint8的ndarray数据,通道顺序[h, w, c],颜色通道BGR。 导入模块:import cv2 (1)cv2.imread() (2)cv…...

JS作用域链和闭包
JS作用域链和闭包 引题作用域链词法作用域闭包思考题 闭包如何回收 引题 有没有人跟我一样,面试中要是问基础,最怕遇到的就是闭包问题,闭包在 JavaScript 中几乎无处不在,理解作用域链是理解闭包的基础,同时作用域链和…...

【Spring实战】15 Logback
文章目录 1. 依赖2. 配置3. 打印日志4. 启动程序5. 验证6. 调整日志级别7. 代码详细总结 Spring 作为一个现代化的 Java 开发框架,提供了很多便利的功能,其中包括灵活而强大的日志记录。本文将介绍如何结合 Spring 和 Logback 配置和使用日志,…...

Stable Diffusion WebUI安装合成面部说话插件SadTalker
SadTalker可以根据一张图片、一段音频,合成面部说这段语音的视频。图片需要真人或者接近真人。 安装ffmpeg 下载地址: https://www.gyan.dev/ffmpeg/builds/ 下载ffmpeg-git-full.7z 后解压,将解压后的目录\bin添加到环境变量的Path中。 在…...

CSS 纵向顶部往下动画
<template><div class"container" mouseenter"startAnimation" mouseleave"stopAnimation"><!-- 旋方块 --><div class"box" :class"{ scale-up-ver-top: isAnimating }"><!-- 元素内容 -->&…...
科普:敏捷估算为什么用斐波那契数列
被一个同学问:敏捷估算为什么用斐波那契数列?有什么意义? 简单说说我自己的简介: 敏捷开发中使用斐波那契数列来估算的原因是,斐波那契数列可以用于估算任务的难度级别,并帮助团队预测完成任务所需的时间…...

HarmonyOS资源分类与访问
资源分类与访问 应用开发过程中,经常需要用到颜色、字体、间距、图片等资源,在不同的设备或配置中,这些资源的值可能不同。 应用资源:借助资源文件能力,开发者在应用中自定义资源,自行管理这些资源在不同…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...

云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...