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

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd