栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

游戏制作(2048)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

游戏制作(2048)

提示:C语言、2048

目录

一、设定内容

二、概要设计

三、实验流程

四、源程序

五、运行结果

总结反思

一、设定内容

        2048游戏,用户控制上下左右键,控制格子内数字移动,相同数字碰撞升级为下一级,直至方格内所有数字无法移动且升级,游戏结束。

二、概要设计

        1. 功能模块:if—else 语句实现功能选择

        2. 各个模块详细的功能描述:根据用户的选择调用不同的函数实现对应功能。

三、实验流程

        把游戏画面想象成4*4的数组,其中数值为0的位置表示空的格子,有数值的位置代表对应的格子。然后对于每一行按列来遍历,或者每一列按行来遍历,实现每一行每一列的对应数字合并,直到出现2048的格子就胜利,否则就失败。

四、源程序
#include
#include
#include  
#include

int data[4][4];
int data_old[4][4];//数据的备份,用于比较data[][]是否变化
int steps=0;//记录操作的步数
void copyData()
{
	int i,j;
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			data_old[i][j]=data[i][j];

}
int compareData()
{
	int i,j;
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			if(data_old[i][j] != data[i][j])return 0; 
	return 1; 
}
int getEmptyNum()
{
	int i,j,n=0;
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			if(data[i][j]==0)
				n++;
	return n;
}void putNewNum()
{
	int i,j,c=0;
	c=1+rand()%getEmptyNum();//生成随机数,范围:[1,空白单元格数)
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			if(data[i][j]==0)
			{
				c--;
				if(c==0)
					data[i][j]=2;//把2放入某空白单元格内
			}	
}
int getMaxScore()
{
	int max=0;
	int i,j;
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
		{
			if(data[i][j]>max)max=data[i][j];
		}
	return max;
}
void printLine(int L)//打印某一行
{
	int i=0;

	for(i=0;i<4;i++)
	{
		printf("│");
		if(data[L][i]==0)printf("t");
		else printf("%dt",data[L][i]);
	}
	printf("│n");
}
void printMap()//打印整个二维数组和分数信息
{
	printf("┌-------┬-------┬-------┬-------┐n");
	printLine(0);
	printf("├-------┼-------┼-------┼-------┤n");
	printLine(1);
	printf("├-------┼-------┼-------┼-------┤n");
	printLine(2);
	printf("├-------┼-------┼-------┼-------┤n");
	printLine(3);
	printf("└-------┴-------┴-------┴-------┘n");
	printf("分数:%dn",getMaxScore());
	printf("操作次数:%dn",steps);
	printf("剩余空间:%dn",getEmptyNum());
}
void moveUP()
{
	int i,j;
	int m=0,n=0;
	for(i=0;i<4;i++)//列
	{
		//移动操作
		j=0;n=0;		 //j为当前判定的所在行
		while(n<3 && j<3)//n为移动的次数
		{
			if(data[j][i]==0)   //若发现空白格
			{
				for(m=j;m<3;m++)//下方数据向上平移1格,覆盖空白格
					data[m][i]=data[m+1][i];	
				data[3][i]=0;	//最后一行置0
				n++;			//移动的次数+1
				
			}else j++; //否则:让当前判定的所在行+1
		}

		//合并操作
		for(j=0;j<3;j++)//行
			if(data[j][i]==data[j+1][i] && data[j][i]!=0)//相同(且不是0)则合并
			{											 // 0和0不需要合并
				data[j][i]=data[j][i]*2;//上面的保存合并后的数字
				data[j+1][i]=0;			//下面的清零
			}
		//移动操作
		j=0;n=0;
		while(n<3 && j<3)
		{
			if(data[j][i]==0)
			{
				for(m=j;m<3;m++)
					data[m][i]=data[m+1][i];	
				data[3][i]=0;
				n++;	
			}else j++;
		}
	}
}

void moveDOWN()
{
	int i,j;
	int m=0,n=0;
	for(i=0;i<4;i++)//列
	{
		//移动操作
		j=3;n=0;
		while(n<3 && j>0)
		{
			if(data[j][i]==0)
			{
				for(m=j;m>0;m--)data[m][i]=data[m-1][i];	
				data[0][i]=0;
				n++;	
			}else j--;
		}

		//合并操作
		for(j=3;j>0;j--)//行
			if(data[j][i]==data[j-1][i] && data[j][i]!=0)//相同(且不是0)则合并
			{
				data[j][i]=data[j][i]*2;//下面的保存合并后的数字
				data[j-1][i]=0;			//上面的清零
			}
		//移动操作
		j=3;n=0;
		while(n<3 && j>0)
		{
			if(data[j][i]==0)
			{
				for(m=j;m>0;m--)data[m][i]=data[m-1][i];	
				data[0][i]=0;
				n++;	
			}else j--;
		}
	}
}

void moveLEFt()
{
	int i,j;
	int m=0,n=0;
	for(i=0;i<4;i++)
	{
		//移动操作
		j=0;n=0;
		while(n<3 && j<3)
		{
			if(data[i][j]==0)
			{
				for(m=j;m<3;m++)data[i][m]=data[i][m+1];	
				data[i][3]=0;
				n++;	
			}else j++;
		}
		//合并操作
		for(j=0;j<3;j++)
			if(data[i][j]==data[i][j+1] && data[i][j]!=0)
			{
				data[i][j]=data[i][j]*2;
				data[i][j+1]=0;		
			}
		//移动操作
		j=0;n=0;
		while(n<3 && j<3)
		{
			if(data[i][j]==0)
			{
				for(m=j;m<3;m++)data[i][m]=data[i][m+1];	
				data[i][3]=0;
				n++;	
			}else j++;
		}
	}
}

void moveRIGHt()
{
	int i,j;
	int m=0,n=0;
	for(i=0;i<4;i++)
	{
		//移动操作
		j=3;n=0;
		while(n<3 && j>0)
		{
			if(data[i][j]==0)
			{
				for(m=j;m>0;m--)data[i][m]=data[i][m-1];	
				data[i][0]=0;
				n++;	
			}else j--;
		}
		//合并操作
		for(j=3;j>0;j--)
			if(data[i][j]==data[i][j-1] && data[i][j]!=0)
			{
				data[i][j]=data[i][j]*2;
				data[i][j-1]=0;			
			}
		//移动操作
		j=3;n=0;
		while(n<3 && j>0)
		{
			if(data[i][j]==0)
			{
				for(m=j;m>0;m--)data[i][m]=data[i][m-1];	
				data[i][0]=0;
				n++;	
			}else j--;
		}
	}
}
int isGameover()
{
	int i,j;
    for(i=0;i<4;++i)
	{
        for(j=0;j<4;++j)
		{
            if(data[i][j]==0)//任意一点为空,游戏继续
                return 0;
            if(i>0)
			{
                if(data[i-1][j]==data[i][j])//任意两个相邻的单元值相同,游戏继续
                    return 0;
            }
            if(j>0)
                if(data[i][j-1]==data[i][j])
                    return 0;
        }
    }
    return 1;
}
int main()
{
	int ch;
	srand(time(NULL));//用系统当前时间设置rand()随机序列种子,保证每次运行随机序列不一样
    putNewNum();//先生成两个2
	putNewNum();
	copyData(); //备份数组
	printMap(); //显示
	while( (ch=getch())!=0x1B )
    { 
		
		  switch(ch)
		  {
		  case 0xE0:
			 switch(ch=getch())
			 {//识别按下键
				case 72:  moveUP(); break;
				case 80:  moveDOWN(); break;
				case 75:  moveLEFt(); break;
				case 77:  moveRIGHt(); break;
				default:
				   break;
			 }
			 if(compareData()==0)//数据不一样说明格子中的数字能且被移动了
			 {
				putNewNum();  //放置新的数字‘2’
				copyData();   //备份数组的数据
				steps++;	  //操作的次数+1
				
			 }
			 system("cls");  //清屏
			 printMap();	 //显示	
			 if(isGameover())printf("游戏结束,按Q键退出n");
			 //if(getMaxScore()>=2048){}//这里也可以判断分数>=2048,提示通关
			 break;
		  default:break;
		  }	
	 }
}

五、运行结果

总结反思

1.注意要分成多个函数来实现,如游戏初始化,界面展示,游戏控制等功能函数。

2.对于格子中数字位置的掌控不是很到位,有待改进。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/921045.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号