⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 推箱子游戏]基于AT89S51+62256+12864LCD
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************
*名称:推箱子游戏测试版V0.1 
*编程:飞扬
*说明:采用YM12864R-3的液晶(ST7920)+62256的RAM+PT6122的遥控
*下一个版本增加音效,地图编辑功能,界面显示美化,撤销上一步!
*主要是学习外扩展RAM才搞这个东东!
**********************************************************/
#include <at89x52.h>
#include "MAIN.H"
/******    引脚定义   ******/
sbit Beep = P3^3; //音频输出脚

/****** 变量/数组定义 ******/
//定义数组,存放接收到的数据
uchar KeyCoding[4]={0,0,0,0};

//关卡设置
uchar guanka = 0;
 
//用1024个字节存放动态绘图数据,我叫它显存数据
uchar xdata GamePic[1024]; 
 
//十字形(箱子推到圆形位置后变为十字形)
uchar code shizi[8]={0x3c,0x3c,0xff,0xff,0xff,0xff,0x3c,0x3c};

//圆形(箱子要推到的地方)
uchar code yuan[8]={0x3c,0x66,0xc3,0x81,0x81,0xc3,0x66,0x3c};

//箱子(推动的就是他)
uchar code xiangzi[8]={0xff,0x81,0xbd,0xbd,0xbd,0xbd,0x81,0xff};

//娃娃脸(用于推动箱子)
uchar code lian[8]={0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0x7e};

//墙壁
uchar code qiang[8]={0x00,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x00};

//空(用于清空图形移动后的痕迹)
uchar code kong[8]={0,0,0,0,0,0,0,0};

//用于计算图形移动和放置的坐标
//实际存放的是GamePic数组的相应下标
uint code MoveData[64]={
0,1,2,3,4,5,6,7,
128,129,130,131,132,133,134,135,
256,257,258,259,260,261,262,263,
384,385,386,387,388,389,390,391,
512,513,514,515,516,517,518,519,
640,641,642,643,644,645,646,647,
768,769,770,771,772,773,774,775,
896,897,898,899,900,901,902,903
};
/*8X8的游戏地图数据,同时根据图形数据判断娃娃脸是否可以移动,
*箱子是否可以推动,箱子推动的方向是否是墙和箱子,是则不
*能推动!箱子推到的地方是圆形则用十字形替换(将该位置数据换成5),
*推动十字形,则再恢复到箱子的形状(在换成3).
*空(什么都不显示)=0,墙=1,圆=2,箱子=3,脸=4,十字=5 */
uchar code GameMap[10][64]={
//第一关
{1,1,1,1,1,1,1,1,
1,0,0,0,1,2,0,1,
1,2,0,0,3,0,0,1,
1,1,3,1,1,0,0,1,
1,0,0,1,1,3,1,1,
1,0,0,4,0,0,0,1,
1,0,2,1,0,0,0,1,
1,1,1,1,1,1,1,1},
//第二关
{1,1,1,1,1,1,1,1,
1,0,0,0,1,0,0,1,
1,0,2,0,3,2,0,1,
1,1,3,1,1,0,0,1,
1,0,0,1,1,3,1,1,
1,0,0,4,0,2,0,1,
1,0,0,1,0,0,0,1,
1,1,1,1,1,1,1,1},
//第三关
{1,1,1,1,1,1,1,1,
1,0,0,0,1,0,0,1,
1,0,0,0,3,0,0,1,
1,0,3,1,1,0,0,1,
1,0,2,1,1,3,1,1,
1,0,2,4,0,0,0,1,
1,0,2,1,0,0,0,1,
1,1,1,1,1,1,1,1},
//第四关
{1,1,1,1,1,1,1,1,
1,0,0,0,1,0,0,1,
1,0,2,0,3,2,0,1,
1,1,3,1,1,0,0,1,
1,0,0,1,1,3,1,1,
1,0,2,4,0,0,0,1,
1,0,0,1,0,0,0,1,
1,1,1,1,1,1,1,1},
//第五关
{1,1,1,1,1,1,1,1,
1,0,0,0,1,0,0,1,
1,0,0,2,3,0,0,1,
1,1,3,1,1,0,0,1,
1,0,2,1,1,3,1,1,
1,0,0,4,2,0,0,1,
1,0,0,1,0,0,0,1,
1,1,1,1,1,1,1,1},
//6
{1,1,1,1,1,1,1,1,
1,1,0,1,1,0,2,1,
1,0,0,3,0,0,0,1,
1,4,3,3,0,0,0,1,
1,0,1,0,0,1,0,1,
1,0,1,1,1,1,0,1,
1,2,0,0,0,0,2,1,
1,1,1,1,1,1,1,1},
//7
{1,1,1,1,1,1,1,1,
1,0,0,1,0,0,0,1,
1,0,0,1,0,5,0,1,
1,0,0,1,0,2,1,1,
1,1,0,3,0,0,0,1,
1,0,3,0,0,2,0,1,
1,4,0,1,1,0,0,1,
1,1,1,1,1,1,1,1},
//8
{1,1,1,1,1,1,1,1,
1,1,4,0,1,1,1,1,
1,0,0,0,3,2,0,1,
1,0,0,1,0,0,0,1,
1,0,0,0,1,5,0,1,
1,1,0,3,0,0,0,1,
1,1,1,1,0,2,0,1,
1,1,1,1,1,1,1,1},
//9
{1,1,1,1,1,1,1,1,
1,2,0,1,1,1,1,1,
1,2,0,0,0,1,1,1,
1,0,1,3,0,0,0,1,
1,2,0,3,3,1,0,1,
1,1,0,0,0,0,0,1,
1,1,1,1,1,0,4,1,
1,1,1,1,1,1,1,1},
//10
{1,1,1,1,1,1,1,1,
1,1,0,1,1,0,2,1,
1,0,3,0,3,3,0,1,
1,4,0,0,0,0,0,1,
1,0,1,0,0,1,0,1,
1,0,1,1,1,1,0,1,
1,2,0,0,0,0,2,1,
1,1,1,1,1,1,1,1}
};
//因为程序存储器中的的是只读的!
//用于复制程序存储器中的当前地图数据
uchar idata Map[64];
 
//用于存放圆形的坐标,最多5个圆
//yuanPos[6]存放本关有几个圆
uchar xdata yuanPos[6]=0;
 
/**********************************************************
*函数名:CopyMap() 
*功  能:用于复制程序存储器中的当前地图数据
*输  入:入口参数为当前地图编号
**********************************************************/
void CopyMap(uchar num)
{
  uchar i;
  for (i=0;i<64;i++)
  {
	 Map[i] = GameMap[num][i];
  }
}
/**********************************************************
*函数名:WriteMemorizer()
*功  能:将图形数据写入显存 
*pos:要显示图形的位置,*p:指针指向要显示的图形
**********************************************************/
void WriteMemorizer(uchar pos,uchar *p)
{
   uchar i;
   uint j;
   j = MoveData[pos]; //取显存地址(显示坐标)
   for (i=0;i<8;i++)
   {
		GamePic[j] = *p; //要显示的图形写入显存
		p++;  //下一个数据
		j+=16;//显存的下一个地址(每个地址之间的差是16)
   }		  //或者说是间隔是16.
}
/**********************************************************
*函数名:MapCreate() 
*功  能:地图生成程序
**********************************************************/
void MapCreate()
{
   uchar i;
   for (i=0;i<64;i++) //生成8X8的地图
   {
		switch (Map[i])//获得地图上的图形数据
	 	{
			case 0:
				WriteMemorizer(i,kong);//空
				break;
			case 1:
				WriteMemorizer(i,qiang);//墙
				break;
			case 2:
				WriteMemorizer(i,yuan);//圆
				break;
			case 3:
				WriteMemorizer(i,xiangzi);//箱子
				break;
			case 4:
				WriteMemorizer(i,lian);//脸
				break;
			case 5:
				WriteMemorizer(i,shizi);//十字
				break;
		}
   }
}
/**********************************************************
*函数名:GameDisplay() 
*功  能:游戏图形显示程序(从左到右,从上到下)
**********************************************************/
void GameDisplay()
{
  uchar i,j;
  uint  k=0; //对显存清计数器清0
  LCDWriteCommand(0x34);//扩充指令集
  LCDWriteCommand(0x36);//绘图显示开
  for (i=0;i<32;i++) //写上半屏(32行)
  {
    LCDWriteCommand(0x80+i);//Y地址寄存器
	LCDWriteCommand(0x80);  //X地址(LCM自动加1)
	for (j=0;j<16;j++)//16x8列
	{
		LCDWriteData(GamePic[k]);//写入一个字节图形数据
		k++; //指向下一个图形字节
	}
  }
  for (i=0;i<32;i++) //写下半屏
  {
    LCDWriteCommand(0x80+i);//Y地址寄存器
	LCDWriteCommand(0x88);  //X地址(LCM自动加1)
	for (j=0;j<16;j++)//
	{
	 	LCDWriteData(GamePic[k]);
		k++;
	}
  }
}
/**********************************************************
*函数名:ReadPosition()
*功  能:读得娃娃脸的当前坐标位置
*返  回:ReadPos
**********************************************************/
uchar ReadPosition()
{
	uchar i;
	uchar ReadPos; //定义变量存放娃娃脸的位置.
	for (i=0;i<64;i++)
	{
		if(Map[i]==4)
		{ 
			ReadPos = i; //记录娃娃脸的坐标
			break; //找到位置跳出循环
		}
	}
	return (ReadPos); //返回娃娃脸当前位置
}
/**********************************************************
*函数名:Readyuan()
*功  能:读得圆形的坐标位置(箱子移动目的地)
**********************************************************/
void Readyuan()
{
   uchar i,j=0;
   for (i=0;i<64;i++)
   {
	  if (Map[i]==2) //找出圆形的位置
	  {
	  	yuanPos[j] = i; //存放圆的位置
	  	j++;
		yuanPos[6] = j;//存放有几个圆
	  }
   }
}
/**********************************************************
*函数名:Refyuan()
*功  能:刷新显示圆形(箱子移动目的地)
**********************************************************/
void Refyuan()
{
   uchar i;
   for (i=0;i<yuanPos[6];i++)
   {
	   if(Map[yuanPos[i]]==0) Map[yuanPos[i]]=2;
   }
   if (Map[yuanPos[0]]==5&&Map[yuanPos[1]]==5&&Map[yuanPos[2]]==5)
   {//过关
	  		guanka++; //进入下一关
			if (guanka==10) guanka=0;
			CopyMap(guanka);  //复制地图数据
  			MapCreate(); //地图生成程序
  			GameDisplay();//游戏界面显示程序
			Readyuan();//
   }
}
/**********************************************************
*函数名:UpMove()
*功  能:娃娃脸向上移动
*说  明:向上移动是-8 (8X8的数据间隔是8)
*空(什么都不显示)=0,墙=1,圆=2,箱子=3,脸=4,十字=5
**********************************************************/
void UpMove()
{
   uchar pos;
   pos = ReadPosition(); //获得娃娃脸的位置
   if (Map[pos-8]!=1)//判断移动方向前面是否是墙
   {
	 switch (Map[pos-8]) 
	  {
		   case 0: //移动方向前面是空的执行这里
				Map[pos-8] = 4;//娃娃脸的新位置
				Map[pos] =0;   //清空娃娃脸位置
		   		break;
		   case 2: //是圆形执行这里
				Map[pos-8] = 4;//娃娃脸的新位置
				Map[pos] =0;   //清空娃娃脸位置
		   		break;
		   case 3: //移动方向前面是箱子执行这里
				//箱子的前面不是墙或箱子或十字就可以移动
				if (Map[pos-16]==0)
				{
					Map[pos-16]= 3;//显示箱子
				  	Map[pos-8] = 4;//娃娃脸的新位置
					Map[pos] = 0; //清空娃娃脸位置
				}
				else if (Map[pos-16]==2)
				{
					Map[pos-16]= 5;//显示十字形
				  	Map[pos-8] = 4;//娃娃脸的新位置
					Map[pos] = 0; //清空娃娃脸位置

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -