CodeBus投稿落选代码——瓦片地图粗糙版 记录

2024-01-06 02:12

本文主要是介绍CodeBus投稿落选代码——瓦片地图粗糙版 记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Easyx官网上有个分享代码的网站。

然后心血来潮,想起来之前的瓦片地图编辑器

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

就去试试投稿。然后收到回复说要改格式,写注释,按帖子要求排版。

然后排版完了,有好心人提示几个地方修改,比如说题目英文中文之间空格隔开。

然后继续改,巧的是改着改着就来消息说代码比较多,建议上传项目文件压缩包。

然后就到 visualstdio 上跑一遍,发现可以。

然后再提交,然后手机响了,审核同志来询问这个软件的“应用”。然后提出来软件的应用性不够。

比如说整个png图像当游戏背景显然是不可能的,像素绘制瓦片就不如到PS上绘制了。

虽然发了一个png当跳一跳游戏背景的截图,然后有人就指出来实际游戏里运行的情况不同,提示说去可以看看官网推荐参考案例——FC红白机坦克大战的代码。

然后就谢谢指点。

总之后续又有几句话,强调了应用性,随即提示说背景是个二维数组里了,坦克到哪个数组,数组序号是1,1是砖头,坦克就不能继续前进。说可以导出二维数组。再然后就没有然后了,理解了整个故事,也翻看了坦克大战的数组地图,打算这个寒假重整一下瓦片地图,导出瓦片地图背后的二维数组。和二维数组对应的数字,数字对应的像素贴图。这样应该就能过审了。也可以产生价值了。

但是旧的代码呢?估计是雪藏了,但是又再网上搜索关键字,发现旧文案被转载了,然后想起来按格式改写的代码,觉得还是先整一篇新的吧,原来的篇目当做历史,记录无中生有的变化。也算是还原一下一个普通程序的发展历程。

完整代码

虽然代码确实和DevC++ easyx实现视口编辑--像素绘图板与贴图系统-CSDN博客一样,

但是一想起来转载到DevC++ easyx实现视口编辑--像素绘图板与贴图系统 - 技术栈 (jishuzhan.net)

没有注释的代码多少确实有点不够意思,或者说现在巧了,有个详细注释版本,就更新一下

记录一下一些原来应被改写的代码的原样。

一键整合版


// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// main.cpp#include <stdio.h>
#include <graphics.h>// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// oripic.h
int w = 2600; 					// 大地图长
int h = 800;					// 大地图宽
IMAGE set(w, h);				// 大地图struct pixlocal
{short x;				// 记录鼠标绘制的坐标,是地图编辑器改线条生长动画时用到。这里只是用于测试鼠标像素short y;
};struct skline
{							// 另一个编辑器按绘制顺序打印线条生长动画,这里是 debug 用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;		// 像素大小为 8 正方形大小则是 8*8int 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;	// img3 左上角坐标bool putflag = 0;		// 拖动 flag , 用于悬浮窗拖动int drawflag = 0;		// 瓦片绘制 flag , 用于实现长按鼠标绘制像素struct skline b;		// 线条长度存储,当时用于开发技能动画,但是在这里只是用来测试功能,比如拖动技能图标,实现技能启用关闭,就是这个变量在控制
} save;						// 待保存的悬浮窗数据,所以只能有一个struct picsave
{							// 绿色网格插槽,暂存笔刷int lx;					// 左上角坐标int ly;int wide;				// 宽高int h;int useflag;			// 是否被使用struct skline b;		// 配套线条暂存
} a[28];					// 暂存上限 28 个瓦片// 初始化绘图窗口
void OriPicDesk(int a, int h)
{initgraph(a, h, EX_SHOWCONSOLE);setbkcolor(WHITE);cleardevice();				//	创制绘图界面,背景色设置,以背景色填充setlinecolor(BLACK);setlinestyle(PS_SOLID, 1);	//	不含实线,矩形的面积为 8*8,含实线 9*9rectangle(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;		// img2 的左上角坐标save->a = ddm->a / ddm->sizetile;save->h = ddm->h / ddm->sizetile;save->m1x = 0, save->m1y = 0;						// img3 的左上角坐标save->putflag = 0;save->drawflag = 0;
}// 初始化大地图
void OriSet(IMAGE* set, struct drawdesksize ddm)
{SetWorkingImage(set);setbkcolor(YELLOW);			// 背景黄色cleardevice();setlinecolor(BLACK);for (int i = 0; i < w; i += ddm.a / ddm.sizetile){for (int j = 0; j < h; 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++ easyx4mingw_20220901
// 编写日期:2024-1-2
// 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 = 0, puty = 0;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);				// 把 maptile 粘贴到大地图中SetWorkingImage();}else{if (putx == oldx && puty == oldy){											// 如果和上次的位置相同,则不贴图,避免了重复贴图}else{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);			// 把 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 bool drawflag, putflag, attachflag;static	IMAGE olds(show_wideth, show_height);static	IMAGE news(show_wideth, show_height);static int m2x, m2y;							// 加速移动设置参数 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);SetWorkingImage(set);getimage(&olds, nowlx, nowly, pic_wide, pic_heigh);SetWorkingImage();putimage(show_x, show_y, &olds);}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){// ctrl+左键视口,连续移动大地图SetWorkingImage(set);									// 获取视口里的图片getimage(&olds, nowlx, nowly, pic_wide, pic_heigh);m1x = m.x;												// 长按开始时的坐标m1y = m.y;m2x = m.x;m2y = m.y;SetWorkingImage();putflag = true;											// 启动地图移动}else if (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);	// 开始把瓦片贴入大地图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){// 持续拖动大地图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);SetWorkingImage();putimage(show_x, show_y, &olds);if (m.message == WM_LBUTTONUP || m.ctrl == 0){putflag = 0;											// 长按停止,视口采样停止}}}
}// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// draw.h
extern IMAGE maptile;// 像素绘图板的小矩形绘制,开发顺序是先有这个 draw.h 代码,然后有 show.h 代码。这两个头文件是继承关系
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){// 修正可涂色范围,防止溢出。y 不可等于 640+100,x 等于 640+600-1 是边界小方块的最右侧像素// 节约运算,不在相同位置重复绘制}else{int px = 0, py = 0, qx = 0, qy = 0;int mapqx = 0, mapqy = 0;px = m.x - ddm.x;												// 修正 600 的偏移,601=600+1;0==1%8,600=600+(601-600)%8py = m.y - ddm.y;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("draw function is running 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");}
}// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// 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;							// 读取数据,但是 ndnf 没有用到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){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);										// 在瓦片地图这里没有用,但是从这里衍生的其他编辑器用到了}
}// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// movecheck.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("movecheck is running 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("movecheck function is running11111\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;													// 停止移动悬浮窗}}
}// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// 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);									// 悬浮窗重置}}
}// 小地图轨迹打印,这个就是所谓的 skline 的作用。另一个编辑器实现了线条导出功能
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;break;case VK_F2:													// 导出为 gamemap0 的 png 图片saveimage(_T("gamemap.png"), &set);break;case VK_F5:													// 播放线条动画static int limf5 = 0;if (limf5 == 0){Pixnf(*lenth, ddm);limf5 = 1;}else{limf5 = 0;											// 处理掉的 bug:按 F5 一次,打印两次线条}break;}
}int x2 = 650, y2 = 100;									// 深绿色像素板的左上角坐标
int w2 = 3, h2 = 7;										// 绿色网格的列数、行数
int showx3 = 101, showy3 = 100;							// 黄色网格视口的左上角坐标int main()
{OriPicDesk(1800, 870);								// 初始化整个软件窗口大小OriDrawDeskSize(&ddm, 1000, 100);					// 初始化整个软件窗口大小OriPirCle(&save, &ddm);								// 初始化白色小图OriSet(&set, ddm);									// 初始化大地图OriFlowSave(x2, y2, w2, h2);						// 初始化暂存瓦片的绿色网格DrawDesk(ddm);										// 绘制出像素绘图板ExMessage m;int lenth = 0;										// 用于记录绘制长度,在 debug 时看控制台窗口数据while (1){m = getmessage(EX_MOUSE | EX_KEY);				// 获取鼠标、按键信息DrawMouseCheck(m, &lenth, &ddm);				// 像素绘制检测KeyCheck(m, &lenth);							// 按键检测MoveCheck(m, &save);							// 拖动检测FlowSave(m, &save, w2, h2);						// 暂存检测Show(&set, m, showx3, showy3, 600, 700);		// 大地图绘制}closegraph();return 0;
}

分部版本 

main.cpp


// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// main.cpp#include <stdio.h>
#include <graphics.h>#include"oripic.h"									// 初始化函数集中在这个头文件里了
#include"show.h"									// 视口、粘贴瓦片
#include"draw.h"									// 绘制瓦片
#include"flowsave.h"								// 瓦片暂存
#include"movecheck.h"								// 鼠标点击检测
#include"keycheck.h"								// 按键按动检测int x2 = 650, y2 = 100;									// 深绿色像素板的左上角坐标
int w2 = 3, h2 = 7;										// 绿色网格的列数、行数
int showx3 = 101, showy3 = 100;							// 黄色网格视口的左上角坐标int main()
{OriPicDesk(1800, 870);								// 初始化整个软件窗口大小OriDrawDeskSize(&ddm, 1000, 100);					// 初始化整个软件窗口大小OriPirCle(&save, &ddm);								// 初始化白色小图OriSet(&set, ddm);									// 初始化大地图OriFlowSave(x2, y2, w2, h2);						// 初始化暂存瓦片的绿色网格DrawDesk(ddm);										// 绘制出像素绘图板ExMessage m;int lenth = 0;										// 用于记录绘制长度,在 debug 时看控制台窗口数据while (1){m = getmessage(EX_MOUSE | EX_KEY);				// 获取鼠标、按键信息DrawMouseCheck(m, &lenth, &ddm);				// 像素绘制检测KeyCheck(m, &lenth);							// 按键检测MoveCheck(m, &save);							// 拖动检测FlowSave(m, &save, w2, h2);						// 暂存检测Show(&set, m, showx3, showy3, 600, 700);		// 大地图绘制}closegraph();return 0;
}

oripic.h 


// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// oripic.h
int w = 2600; 					// 大地图长
int h = 800;					// 大地图宽
IMAGE set(w, h);				// 大地图struct pixlocal
{short x;				// 记录鼠标绘制的坐标,是地图编辑器改线条生长动画时用到。这里只是用于测试鼠标像素short y;
};struct skline
{							// 另一个编辑器按绘制顺序打印线条生长动画,这里是 debug 用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;		// 像素大小为 8 正方形大小则是 8*8int 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;	// img3 左上角坐标bool putflag = 0;		// 拖动 flag , 用于悬浮窗拖动int drawflag = 0;		// 瓦片绘制 flag , 用于实现长按鼠标绘制像素struct skline b;		// 线条长度存储,当时用于开发技能动画,但是在这里只是用来测试功能,比如拖动技能图标,实现技能启用关闭,就是这个变量在控制
} save;						// 待保存的悬浮窗数据,所以只能有一个struct picsave
{							// 绿色网格插槽,暂存笔刷int lx;					// 左上角坐标int ly;int wide;				// 宽高int h;int useflag;			// 是否被使用struct skline b;		// 配套线条暂存
} a[28];					// 暂存上限 28 个瓦片// 初始化绘图窗口
void OriPicDesk(int a, int h)
{initgraph(a, h, EX_SHOWCONSOLE);setbkcolor(WHITE);cleardevice();				//	创制绘图界面,背景色设置,以背景色填充setlinecolor(BLACK);setlinestyle(PS_SOLID, 1);	//	不含实线,矩形的面积为 8*8,含实线 9*9rectangle(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;		// img2 的左上角坐标save->a = ddm->a / ddm->sizetile;save->h = ddm->h / ddm->sizetile;save->m1x = 0, save->m1y = 0;						// img3 的左上角坐标save->putflag = 0;save->drawflag = 0;
}// 初始化大地图
void OriSet(IMAGE* set, struct drawdesksize ddm)
{SetWorkingImage(set);setbkcolor(YELLOW);			// 背景黄色cleardevice();setlinecolor(BLACK);for (int i = 0; i < w; i += ddm.a / ddm.sizetile){for (int j = 0; j < h; 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();
}

 

 show.h


// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// 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 = 0, puty = 0;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);				// 把 maptile 粘贴到大地图中SetWorkingImage();}else{if (putx == oldx && puty == oldy){											// 如果和上次的位置相同,则不贴图,避免了重复贴图}else{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);			// 把 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 bool drawflag, putflag, attachflag;static	IMAGE olds(show_wideth, show_height);static	IMAGE news(show_wideth, show_height);static int m2x, m2y;							// 加速移动设置参数 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);SetWorkingImage(set);getimage(&olds, nowlx, nowly, pic_wide, pic_heigh);SetWorkingImage();putimage(show_x, show_y, &olds);}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){// ctrl+左键视口,连续移动大地图SetWorkingImage(set);									// 获取视口里的图片getimage(&olds, nowlx, nowly, pic_wide, pic_heigh);m1x = m.x;												// 长按开始时的坐标m1y = m.y;m2x = m.x;m2y = m.y;SetWorkingImage();putflag = true;											// 启动地图移动}else if (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);	// 开始把瓦片贴入大地图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){// 持续拖动大地图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);SetWorkingImage();putimage(show_x, show_y, &olds);if (m.message == WM_LBUTTONUP || m.ctrl == 0){putflag = 0;											// 长按停止,视口采样停止}}}
}

 

 draw.h


// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// draw.h
extern IMAGE maptile;// 像素绘图板的小矩形绘制,开发顺序是先有这个 draw.h 代码,然后有 show.h 代码。这两个头文件是继承关系
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){// 修正可涂色范围,防止溢出。y 不可等于 640+100,x 等于 640+600-1 是边界小方块的最右侧像素// 节约运算,不在相同位置重复绘制}else{int px = 0, py = 0, qx = 0, qy = 0;int mapqx = 0, mapqy = 0;px = m.x - ddm.x;												// 修正 600 的偏移,601=600+1;0==1%8,600=600+(601-600)%8py = m.y - ddm.y;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("draw function is running 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 


// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// 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;							// 读取数据,但是 ndnf 没有用到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){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++ easyx4mingw_20220901
// 编写日期:2024-1-2
// movecheck.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("movecheck is running 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("movecheck function is running11111\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;													// 停止移动悬浮窗}}
}

 

keycheck.h 


// 程序:瓦片地图绘图板
// 作者:无脑
// 编译环境:DevC++ easyx4mingw_20220901
// 编写日期:2024-1-2
// 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);									// 悬浮窗重置}}
}// 小地图轨迹打印,这个就是所谓的 skline 的作用。另一个编辑器实现了线条导出功能
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;break;case VK_F2:													// 导出为 gamemap0 的 png 图片saveimage(_T("gamemap.png"), &set);break;case VK_F5:													// 播放线条动画static int limf5 = 0;if (limf5 == 0){Pixnf(*lenth, ddm);limf5 = 1;}else{limf5 = 0;											// 处理掉的 bug:按 F5 一次,打印两次线条}break;}
}

这篇关于CodeBus投稿落选代码——瓦片地图粗糙版 记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/574903

相关文章

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

SpringBoot生成和操作PDF的代码详解

《SpringBoot生成和操作PDF的代码详解》本文主要介绍了在SpringBoot项目下,通过代码和操作步骤,详细的介绍了如何操作PDF,希望可以帮助到准备通过JAVA操作PDF的你,项目框架用的... 目录本文简介PDF文件简介代码实现PDF操作基于PDF模板生成,并下载完全基于代码生成,并保存合并P

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

SpringCloud集成AlloyDB的示例代码

《SpringCloud集成AlloyDB的示例代码》AlloyDB是GoogleCloud提供的一种高度可扩展、强性能的关系型数据库服务,它兼容PostgreSQL,并提供了更快的查询性能... 目录1.AlloyDBjavascript是什么?AlloyDB 的工作原理2.搭建测试环境3.代码工程1.

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python