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资源分类与访问
资源分类与访问 应用开发过程中,经常需要用到颜色、字体、间距、图片等资源,在不同的设备或配置中,这些资源的值可能不同。 应用资源:借助资源文件能力,开发者在应用中自定义资源,自行管理这些资源在不同…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...
Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...
负载均衡器》》LVS、Nginx、HAproxy 区别
虚拟主机 先4,后7...
