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

📄 main.c

📁 一个推箱子的游戏,编程思想很值得借鉴,对大家会很有帮助
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************
*名称:推箱子游戏V0.1 Beta 1 (以占用3515字节 EPROM空间)
*编程:飞扬
*说明:采用YM12864R液晶(ST7920)+62256+PT6122遥控+AT89S51
*下一个版本增加音效,地图编辑功能,界面显示美化,撤销上一步!
*主要是学习外扩展RAM才搞这个东东! 我使用的是24MHz晶振
*关卡增加到20关
**********************************************************/
#include <at89x52.h>
#include "MAIN.H"
/******    引脚定义   ******/
sbit Beep = P3^3; //音频输出脚

/****** 变量/数组定义 ******/
uchar code logotab[4][17]={
{"                "},
{"  V0.1 Beta 1   "},
{"  推箱子游戏    "},
{"  编程  飞扬    "}};
//存放遥控接收数据
uchar xdata KeyCoding[4]={0,0,0,0};
//关卡设置
uchar guanka = 0;
//用1024个字节存放动态绘图数据,我叫它显存数据
uchar xdata GamePic[1024] _at_ 0x0100; //这里使用了绝对地址
//空(用于清空图形移动后的痕迹)编号0
uchar code kong[8]={0,0,0,0,0,0,0,0};
//墙壁(用来标识移动的范围)编号1
uchar code qiang[8]={0x00,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x00};
//圆形(箱子要推到的地方)编号2
uchar code yuan[8]={0x3c,0x66,0xc3,0x81,0x81,0xc3,0x66,0x3c};
//箱子(推动的就是他)编号3
uchar code xiangzi[8]={0xff,0x81,0xbd,0xbd,0xbd,0xbd,0x81,0xff};
//娃娃脸(用于推动箱子)编号4
uchar code lian[8]={0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0x7e};
//十字形(箱子推到圆形位置后变为十字形)编号5
uchar code shizi[8]={0x3c,0x3c,0xff,0xff,0xff,0xff,0x3c,0x3c};
//用于计算图形移动和放置的坐标
//实际存放的是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[20][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,0,0,0,1,0,0,1,
1,0,0,0,3,0,0,1,
1,1,5,1,1,0,0,1,
1,0,2,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},
//7
{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},
//8
{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},
//9
{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},
//10
{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},
//11
{1,1,1,1,1,1,1,1,
1,1,0,0,0,1,1,1,
1,0,1,2,3,0,1,1,
1,0,2,4,0,0,1,1,
1,0,3,0,3,0,1,1,
1,1,0,0,0,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1},
//12
{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},
//13
{1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,0,0,0,0,1,1,
1,1,2,1,1,3,0,1,
1,0,2,2,3,0,0,1,
1,0,0,1,3,0,0,1,
1,0,0,4,0,1,1,1,
1,1,1,1,1,1,1,1},
//14
{1,1,1,1,1,1,1,1,
1,1,1,0,0,1,1,1,
1,1,0,0,0,0,1,1,
1,0,2,0,2,3,1,1,
1,0,0,3,4,0,0,1,
1,1,1,1,5,1,0,1,
1,1,1,1,0,0,0,1,
1,1,1,1,1,1,1,1},
//15
{1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,0,2,0,5,0,1,
1,1,0,0,1,0,0,1,
1,1,4,3,5,0,0,1,
1,1,1,0,0,0,1,1,
1,1,1,0,0,0,1,1,
1,1,1,1,1,1,1,1},
//16
{1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,0,2,2,1,1,1,1,
1,0,3,0,0,0,0,1,
1,0,0,1,3,1,0,1,
1,0,4,0,2,3,0,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1},
//17
{1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,2,0,0,4,2,1,1,
1,0,0,3,1,0,1,1,
1,0,1,0,3,2,0,1,
1,0,0,0,3,1,0,1,
1,1,1,1,0,0,0,1,
1,1,1,1,1,1,1,1},
//18
{1,1,1,1,1,1,1,1,
1,2,0,2,1,1,1,1,
1,2,1,3,3,0,1,1,
1,0,0,0,4,0,1,1,
1,0,3,1,0,0,1,1,
1,1,0,0,0,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1},
//19
{1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,2,0,0,0,2,0,1,
1,0,1,0,1,0,0,1,
1,4,3,0,0,3,2,1,
1,1,1,1,1,0,3,1,
1,1,1,1,1,0,0,1,
1,1,1,1,1,1,1,1},
//20
{1,1,1,1,1,1,1,1,
1,0,0,1,1,1,1,1,
1,0,0,1,1,1,1,1,
1,0,2,5,0,0,0,1,
1,1,3,0,0,0,0,1,
1,1,0,1,3,1,1,1,
1,1,2,0,4,1,1,1,
1,1,1,1,1,1,1,1}
};
/*程序存储器中的数据是只读的!根据这个地图刷新显示.
 用于复制程序存储器中的当前地图数据*/
uchar xdata 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 zb;
   zb = MoveData[pos]; //取显存地址(显示坐标)
   for (i=0;i<8;i++)
   {
	GamePic[zb] = *p; //要显示的图形写入显存
	p++;   //下一个数据
	zb+=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() 
*功  能:游戏图形显示程序(从左到右,从上到下)
*  *point指向外部RAM存储的128X64的图片数据
**********************************************************/
void GameDisplay(uchar xdata *point)
{
  uchar i,j;
  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列
	{						  //获得GamePic的首地址
		LCDWriteData(*point);//写入一个字节图形数据
		point++; //指向下一个图形字节
	}
  }
  for (i=0;i<32;i++) //写下半屏
  {
    LCDWriteCommand(0x80+i);//Y地址寄存器
	LCDWriteCommand(0x88);  //X地址(LCM自动加1)
	for (j=0;j<16;j++)//
	{
	 	LCDWriteData(*point);//写入一个字节图形数据
		point++;
	}
  }
}
/**********************************************************
*函数名:ReadPosition()
*功  能:读得娃娃脸的当前坐标位置
*返  回:ReadPos
**********************************************************/
uchar ReadPosition()
{
	uchar i;
	uchar ReadPos;    //定义变量存放娃娃脸的位置.
	for (i=0;i<64;i++)//地图数据是64个字节
	{				  //逐个比较找出娃娃脸
		if(Map[i]==4) //娃娃脸的编号是4
		{ 
			ReadPos = i;//记录娃娃脸的坐标
			break;      //找到娃娃脸就跳出循环
		}
	}
	return (ReadPos); //返回娃娃脸当前位置
}
/**********************************************************
*函数名:Readyuan()
*功  能:读得圆形的坐标位置(箱子移动目的地)
*在初次读入当前地图数据是,5(十字)也认为是圆,不然就出错,
*推动十字形后就少一个圆了.
**********************************************************/
void Readyuan()
{
   uchar i,j=0;
   for (i=0;i<64;i++)//地图数据是64个字节
   {				 //圆形的编号是2
	  if (Map[i]==2||Map[i]==5) //找出圆形的位置
	  {//在编地图的时候也用十字形.
	  	yuanPos[j] = i;//存放圆形的位置
	  	j++;           //计数圆形的个数
		yuanPos[6] = j;//存放圆形的个数
	  }
   }
}
/**********************************************************
*函数名:Refyuan()
*功  能:刷新显示圆形(箱子移动目的地)
**********************************************************/
void Refyuan()
{
   uchar i;	 //yuanPos[6] 存放着圆形的个数(3--5个)
   for (i=0;i<yuanPos[6];i++)//根据圆的个数来判断
   {   //判断圆形的坐标位置是否为0(空),是就显示圆形
	   if(Map[yuanPos[i]]==0) Map[yuanPos[i]]=2;
   }
}
/**********************************************************
*函数名:Next()
*功  能:进入下一关
**********************************************************/
void Next()
{  //圆形位置全变为十字形(5),说明推完了,过关
   if (Map[yuanPos[0]]==5&&Map[yuanPos[1]]==5&&Map[yuanPos[2]]==5)
   {//过关
	  		guanka++; //进入下一关
			if (guanka==20) guanka=0;//这里设置为20关
			CopyMap(guanka);//复制地图数据
  			MapCreate();    //地图生成程序
  			GameDisplay(GamePic);  //游戏界面显示程序
			Readyuan();     //复制当前关卡圆形坐标和个数
   }
}
/**********************************************************
*函数名:UpMove()
*功  能:娃娃脸向上移动
*说  明:向上移动是-8 (8X8的数据间隔是8)
*空(什么都不显示)=0,墙=1,圆=2,箱子=3,脸=4,十字=5

⌨️ 快捷键说明

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