瓦片地图游戏代码开发——实现二维数组记录贴图序号,卡马克卷轴实现原理

 核心在于 changewait()函数对采样区越界检测,以及对采样区的刷新,就是九宫格绘制到采样区域里。

 

#include 
#include 

// 默认游戏地图
int map[20][20]= {
	{0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
	{0,0,0,0,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
	{0,0,0,0,0, 0,0,1,0,0, 0,0,2,0,2, 0,0,0,0,0},
	{0,0,0,0,0, 0,0,0,0,2, 0,0,0,2,0, 0,0,0,0,0},
	{0,0,0,0,1, 0,0,0,0,0, 0,0,1,0,0, 1,0,0,0,0},

	{0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
	{0,0,0,0,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
	{0,0,0,0,0, 0,0,1,0,0, 0,0,2,0,2, 0,0,0,0,0},
	{0,0,0,0,0, 0,0,0,0,2, 0,0,0,2,0, 0,0,0,0,0},
	{0,0,0,0,1, 0,0,0,0,0, 0,0,1,0,0, 1,0,0,0,0},

	{0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
	{0,0,0,0,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
	{0,0,0,0,0, 0,0,1,0,0, 0,0,2,0,2, 0,0,0,0,0},
	{0,0,0,0,0, 0,0,0,0,2, 0,0,0,2,0, 0,0,0,0,0},
	{0,0,0,0,1, 0,0,0,0,0, 0,0,1,0,0, 1,0,0,0,0},

	{0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
	{0,0,0,0,0, 0,1,0,0,0, 0,0,0,0,0, 0,0,0,0,0},
	{0,0,0,0,0, 0,0,1,0,0, 0,0,2,0,2, 0,0,0,0,0},
	{0,0,0,0,0, 0,0,0,0,2, 0,0,0,2,0, 0,0,0,0,0},
	{0,0,0,0,1, 0,0,0,0,0, 0,0,1,0,0, 1,0,0,0,0},
};

int a=30;								// 瓦片的大小正方形像素瓦片的边长
int xc=3*a;								// 采样区左上角坐标
int yc=3*a;								// 采样区左上角坐标
IMAGE c(3*a,3*a);						// 采样图片,就是屏幕上看到的游戏的大小
int see = 9;							// 缓冲区的大小
int seex =0;							// 缓冲区对应的数组左上角坐标
int seey=0;								// 缓冲区对应的数组左上角坐标
IMAGE n(see*a,see*a);					// 缓冲区,长宽各为 see*a 个像素

void loadmap();

void changewait() {
	int changeflag=0;
	if(xc>2*(3*a)) {					// 如果采样区移动超过自身一倍
		xc=xc-(3*a);					// 采样区减少一份长度,
		seex+=3;						// 缓冲区增加一份长度
		changeflag=1;					// 如果有重置,就更新缓冲区,重新采样打印
	}
	if(xc<0) {
		xc=xc+3*a;
		seex-=3;						// 采样区增减和屏幕移动增减同号
		changeflag=1;
	}
	if(yc>2*(3*a)) {
		yc=yc-(3*a);
		seey+=3;
		changeflag=1;
	}
	if(yc<0) {
		yc=yc+(3*a);
		seey-=3;
		changeflag=1;
	}

	if(changeflag) {
		SetWorkingImage(&n);								// 选择缓冲区为更新对象
		for(int i=0; i<9; i++) {
			for(int j=0; j<9; j++) {
				switch (map[i+seey][j+seex]) {				// 解决x坐标与数组的对应关系 第二个方括号【】是列数,是横坐标x,控制第几列
					case 0:
						setfillcolor(BLACK);				// 二维数组瓦片是 0,则选择黑色瓦片
						break;
					case 1:
						setfillcolor(WHITE);				// 二维数组瓦片是 1,则选择白色瓦片
						break;
					case 2:
						setfillcolor(GREEN);				// 二维数组瓦片是 2,则选择绿色瓦片
						break;
					case 3:
						setfillcolor(BLUE);					// 二维数组瓦片是 3,则选择蓝色瓦片
						break;
				}
				fillrectangle(j*a,i*a,(j+1)*a,(i+1)*a);		// 贴图瓦片
			}
		}
		changeflag=0;
	}
	SetWorkingImage(&n);									// 从缓冲区采样
	getimage(&c,xc,yc,3*a,3*a);
	SetWorkingImage();
	putimage(800,a,&n);										// 打印缓冲区,理解间断更新
	putimage(1300,a,&c);									// 打印缓冲区,理解连续更新
	printf("cx = %d, yc = %d\n",xc,yc);
	printf("seex = %d, seey = %d\n",seex,seey);
}


void changev2(ExMessage msg) {
	static int flag=0;
	static int oldx;
	static int oldy;
	static int orx=xc;
	static int ory=xc;
	if(msg.message == WM_RBUTTONDOWN) {
		flag=1;												// 长按flag
		oldx=msg.x;											// 记录拖动的起点 
		oldy=msg.y;
		printf("msg.x = %d,msg.y = %d\n",msg.x,msg.y);
	} else if(flag==1) {									// 长按时不变参考点 
		xc = orx-(msg.x-oldx);								// 图片移动的距离等于鼠标移动的距离
		yc= ory-(msg.y-oldy);								// 移动方向和鼠标移动方向相反
		changewait();
	}
	if(msg.message == WM_RBUTTONUP) {
		flag=0;
		orx=xc;
		ory=yc;
	}
}


void change(ExMessage msg) {
	if(msg.message==WM_KEYDOWN) {		// 游戏移动
		switch(msg.vkcode) {
			case 0x41:					// A
				xc--;					// 左移采样区
				break;
			case 0x44:					// D
				xc++;					// 右移采样区
				break;
			case 0x57:					// W
				yc--;					// 上移采样区
				break;
			case 0x53:					// S
				yc++;					// 下移采样区
				break;
		}
	}
	changewait();
}


int main() {
	loadmap();												// 加载地图
	getimage(&n,1*a,1*a,see*a,see*a);						// 加载缓冲区
	putimage(800,a,&n);										// 显示缓冲区
	ExMessage msg;
	while(1) {
		peekmessage(&msg,EX_KEY|EX_MOUSE,true);
		change(msg);
		changev2(msg);
		Sleep(1);
	}
	closegraph();
	return 0;
}



void loadmap() {
//	FILE* fp;
//	fp=fopen("map.txt","r");
//	for(int i=0; i<20; i++) {
//		for(int j=0; j<20; j++) {
//			fscanf(fp," %d",&map[i][j]);
//		}
//		fscanf(fp,"\n");
//	}
//
//	printf("gammap\n");
//	for(int i=0; i<20; i++) {
//		for(int j=0; j<20; j++) {
//			printf(" %d",map[i][j]);
//		}
//		printf("\n");
//	}
//	fclose(fp);

	initgraph(1800,800,1);
	setbkcolor(GREEN);
	cleardevice();

	for(int i=0; i<20; i++) {
		for(int j=0; j<20; j++) {
			rectangle(i*a,j*a,(i+1)*a,(j+1)*a);
		}
	}

	setfillcolor(WHITE);
	for(int i=0; i<20; i++) {
		for(int j=0; j<20; j++) {
			switch (map[i][j]) {
				case 0:
					setfillcolor(BLACK);
					break;
				case 1:
					setfillcolor(WHITE);
					break;
				case 2:
					setfillcolor(GREEN);
					break;
				case 3:
					setfillcolor(BLUE);
					break;
			}
			fillrectangle(j*a,i*a,(j+1)*a,(i+1)*a);
		}
	}
}

你可能感兴趣的:(算法)