Easyx库-2048小游戏

#include 
#include 
#include 
#include 
#pragma comment(lib,"Winmm.lib")

#define SQU_INTERVAL 12       //正方形的间隙
#define SQU_LONG 130          //正方形的边长

void map_welcome();          //欢迎
void map_start();            //开始设置初始值
int map_add(void);           //获取剩余空格随机值
int map_cutSqu(int num);     //剪切小方格背景
void map_drawSqu();          //数字添加图片上
int map_move(void);          //方格移动
int map_check(void);         //满格后方格检查邻近方格有相同的
void map_over();             //游戏结束

IMAGE background;
IMAGE squ;
IMAGE squAll;
IMAGE black;
int map[4][4];               //将游戏界面看作二维数组
int full_num=0;              //有数字方格的个数
int space_num;               //空方格的个数
int position;                //随机产生数字的位置(看作一维数组)

void main()
{
	srand((unsigned)time(NULL));
	initgraph(580,580);
	map_welcome();           //调用欢迎方法
	map_start();             //调用初始化方法,二维数组值全为0
	mciSendString("open audio/move.mp3 alias move",NULL,0,NULL);
	mciSendString("play move from 0",NULL,0,NULL);
	map_add();               //调用获取剩余空格随机值方法
	map_drawSqu();           //调用数字添加到图片方法
	BeginBatchDraw();        //开始批绘制
	while(1)
	{	
		if(map_move())       //调用移动方法
		{
			mciSendString("play move from 0",NULL,0,NULL);
			map_add();       //若移动发生改变,则再调用产生随机值方法
		}
		putimage(0,0,&background);
		map_drawSqu();
		FlushBatchDraw();               //批绘制
		if(!map_check()&&full_num==16)            
		{
			map_over();                 //如果满格并且检查函数返回值为0(邻近无相同数字),调用结束函数
		}
		Sleep(40);
	}
	
}

void map_welcome()//欢迎
{
	loadimage(NULL,"image/welcome.jpg");      //图片直接加载到屏幕
	MOUSEMSG m;
	while(1)
	{
		m=GetMouseMsg();
		if(m.uMsg==WM_LBUTTONDOWN&&m.x>=200&&m.x<=400&&m.y>=410&&m.y<=490)           //如果鼠标是左键点击并且点击某范围
		{
			break;
		}
	}
	loadimage(&background,"image/background.jpg");
	putimage(0,0,&background);
}

void map_start()//初始化
{
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			map[i][j]=0;
		}
	}
}

int map_add(void)//剩余空格产生随机值
{
	int i,j,count=0;                                               //count代表第几个剩余空格,count-1用于与position比较
	space_num=16-full_num;
	if(full_num==16)
	{
		return 1;
	}
	else
	{
		position=rand()%space_num;                                 //产生随机位置
	}
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(!map[i][j])
			{	
				count+=1;                                          //若非空,则加1
				if(count-1==position)
				{
					map[i][j]=rand()%50>5?2:4;                     //随机生成2和4,2比例大					
					full_num+=1;                                   //有数字方格个数加1
					break;
				}			
			}			
		}
	}
	return 0;
}

void map_drawSqu()//数字添加到图片上
{
	int i,j,textX,textY=52;//textX,textY分别是数字在小方格图片中的坐标
	char string[10];
	LOGFONT f;
	getfont(&f);
	f.lfHeight=42;
	strcpy(f.lfFaceName,"微软雅黑");
	settextcolor(BLACK);
	setfont(&f);
	loadimage(&black,"image/black.jpg");	
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(map[i][j]>0)
			{
				switch(map[i][j])
				{
					case 2:map_cutSqu(15);break;                 //调用截取方格函数,2对应右下角方格
					case 4:map_cutSqu(14);break;
					case 8:map_cutSqu(13);break;
					case 16:map_cutSqu(12);break;
					case 32:map_cutSqu(11);break;
					case 64:map_cutSqu(10);break;
					case 128:map_cutSqu(9);break;
					case 256:map_cutSqu(8);break;
					case 512:map_cutSqu(7);break;
					case 1024:map_cutSqu(6);break;
					case 2048:map_cutSqu(5);break;
					case 4096:map_cutSqu(4);break;
					case 8192:map_cutSqu(3);break;
					case 16384:map_cutSqu(2);break;
					case 32768:map_cutSqu(1);break;
					default:map_cutSqu(0);break;
				}
				if(map[i][j]<10)
				{
					textX=65;                                    //若是数字位数少,则x坐标要大
				}
				else if(map[i][j]>10&&map[i][j]<100)
				{
					textX=55;
				}
				else if(map[i][j]>100&&map[i][j]<1000)
				{
					textX=50;
				}
				else if(map[i][j]>1000&&map[i][j]<10000)
				{
					textX=40;
				}
				else
				{
					textX=30;
				}
				putimage(SQU_INTERVAL+(SQU_INTERVAL+SQU_LONG)*j,SQU_INTERVAL+(SQU_INTERVAL+SQU_LONG)*i,&black,SRCAND);    //三位光栈,贴白底黑字图片
				putimage(SQU_INTERVAL+(SQU_INTERVAL+SQU_LONG)*j,SQU_INTERVAL+(SQU_INTERVAL+SQU_LONG)*i,&squ,SRCPAINT);    //三位光栈,贴黑底彩字图片,白底与黑底会透明
				sprintf(string,"%d",map[i][j]);
				setbkmode(TRANSPARENT);                                                                                   //设置文字背景透明
				outtextxy((SQU_INTERVAL+SQU_LONG)*j+textX,(SQU_INTERVAL+SQU_LONG)*i+textY,string);
			}
		}
	}	
}

int map_cutSqu(int num)//截取方格
{
	loadimage(&squAll,"image/squAll.jpg");
	SetWorkingImage(&squAll);                                               //在某图片上绘制
	getimage(&squ,SQU_LONG*(num%4),SQU_LONG*(num/4),SQU_LONG,SQU_LONG);     //截取某个区域并保存到某个图片变量中
	SetWorkingImage();                                                      //无参数表示在屏幕上绘制,写过有参数的一定写无参的
	return 0;
}

int map_move(void)//方格移动
{	
	int x,x1,y,y1,move_num=0;
	if(GetAsyncKeyState(VK_LEFT)&0x8000)       //向左移动
	{
		for(x=0;x<4;x++)
		{
			for(y=0;y<3;y++)
			{
				for(y1=y+1;y1<4;y1++)
				{
					if(map[x][y1]>0)
					{
						if(map[x][y]==0)
						{
							map[x][y]=map[x][y1];
							map[x][y1]=0;							
							y--;              //--后再++让y重新指向该位置
							move_num=1;       //用来判断是否需要产生新数字,若是移动了则move_num=1,需要产生
						}
						else if(map[x][y]==map[x][y1])
						{
							map[x][y]*=2;
							map[x][y1]=0;
							full_num-=1;
							move_num=1;
						}
						break;
					}					
				}
			}
		}
	}
	else if(GetAsyncKeyState(VK_UP)&0x8000)        //向上移动
	{
		for(y=0;y<4;y++)
		{
			for(x=0;x<3;x++)
			{
				for(x1=x+1;x1<4;x1++)
				{
					if(map[x1][y]>0)
					{
						if(map[x][y]==0)
						{							
							map[x][y]=map[x1][y];
							map[x1][y]=0;							
							x--;
							move_num=1;
						}
						else if(map[x][y]==map[x1][y])
						{
							map[x][y]*=2;
							map[x1][y]=0;
							full_num-=1;
							move_num=1;
						}
						break;
					}					
				}
			}
		}
	}
	else if(GetAsyncKeyState(VK_RIGHT)&0x8000)    //向右移动
	{
		for(x=0;x<4;x++)
		{
			for(y=3;y>=0;y--)
			{
				for(y1=y-1;y1>=0;y1--)
				{
					if(map[x][y1]>0)
					{
						if(map[x][y]==0)
						{							
							map[x][y]=map[x][y1];
							map[x][y1]=0;							
							y++;
							move_num=1;
						}
						else if(map[x][y]==map[x][y1])
						{
							map[x][y]*=2;
							map[x][y1]=0;
							full_num-=1;
							move_num=1;
						}
						break;
					}					
				}
			}
		}
	}
	else if(GetAsyncKeyState(VK_DOWN)&0x8000)     //向下移动
	{
		for(y=0;y<4;y++)
		{
			for(x=3;x>=0;x--)
			{
				for(x1=x-1;x1>=0;x1--)
				{
					if(map[x1][y]>0)
					{
						if(map[x][y]==0)
						{							
							map[x][y]=map[x1][y];
							map[x1][y]=0;							
							x++;
							move_num=1;
						}
						else if(map[x][y]==map[x1][y])
						{
							map[x][y]*=2;
							map[x1][y]=0;
							full_num-=1;
							move_num=1;
						}
						break;
					}					
				}
			}
		}
	}
	return move_num;
}

int map_check(void)
{
	int i,j;
	for(i=0;i<3;i++)
	{
		for(j=0;j<3;j++)                            //因为判断的是右边和下边,坐标需要加1,所以小于3是防止下标越界
		{
			if(map[i][j]==map[i+1][j]||map[i][j]==map[i][j+1])
				return 1;
		}
	}
	for(i=1;i<4;i++)                                //判断的是左边和上边,坐标需要减1,所以从等于1开始
	{
		for(j=1;j<4;j++)
		{
			if(map[i][j]==map[i-1][j]||map[i][j]==map[i][j-1])
				return 1;
		}
	}
	return 0;
}

void map_over()
{
	EndBatchDraw();                     //关闭批绘制
	setcolor(RED);
	settextstyle(60,0,"微软雅黑");
	setbkmode(TRANSPARENT);   
	outtextxy(200,250,"闯关失败!");
	system("pause");
	exit(0);
}

源代码文件:点击打开链接

你可能感兴趣的:(Easyx)