1. 程式人生 > >(微控制器原理與應用)大液晶屏的遊戲設計(推箱子)

(微控制器原理與應用)大液晶屏的遊戲設計(推箱子)

圖十二 遊戲程式介面

系統的優點與不足

優點:遊戲容易上手,而且可以鍛鍊大腦思維

不足:有些關卡設計簡單

參考文獻

[1] 陳海宴. 51微控制器原理及應用--基於Keil C與Proteus. 北京航空航天大學出版,2010-07-01,第1版.

[2] 彭偉. 微控制器C語言程式設計實訓100例——基於8051+PROTEUS模擬. 電子工業出版社,2009-06-01 .

[3] 浦濱. C遊戲程式設計從入門到精通. 北京希望電子出版社,2002-5-1

[4] 李巨集 張家田,等. 液晶顯示器件應用技術  機械工業出版社, 2004-7-1

[5]AT89c52資料手冊

附錄程式碼

Variable.h
#define uchar unsigned char
#define uint unsigned int
//**********T6963c命令巨集定義*********************//
//地址指標設定
#define cur_pos 0x21 //游標位置設定
#define CGR_pos 0x22 //CGRAM偏置地址設定
#define add_pos 0x24 //地址指標位置

//顯示區域設定
#define txt_stp 0x40 //文字區首地址
#define txt_wid 0x41 //文字區寬度
#define grh_stp 0x42 //圖形區首地址
#define grh_wid 0x43 //圖形區寬度

//顯示方式設定
#define mod_or  0x80 //顯示方式:邏輯或
#define mod_xor 0x81 //顯示方式:邏輯異或
#define mod_and 0x82 //顯示方式:邏輯與
#define mod_tch 0x83 //顯示方式:文字特徵

//顯示狀態設定
#define dis_sw 0x90 //顯示開關
                    //D0=1/0:游標閃爍啟用/禁用
					//D1=1/0:游標顯示啟用/禁用
					//D2=1/0:文字顯示啟用/禁用
					//D3=1/0:圖形顯示啟用/禁用

//游標形狀設定
#define cur_shp 0xa0 //游標形狀選擇:0xa0~0xa7光標占的行數:1行~8行

//資料自動讀寫設定
#define aut_wr  0xb0 //自動寫
#define aut_rd  0xb1 //自動讀
#define aut_ovr 0xb2 //自動讀寫結束

//資料一次讀寫設定
#define inc_wr 0xc0 //資料寫,地址+1
#define inc_rd 0xc1 //資料讀,地址+1
#define dec_wr 0xc2 //資料寫,地址-1
#define dec_rd 0xc3 //資料讀,地址-1
#define noc_wr 0xc4 //資料寫,地址不變
#define noc_rd 0xc5 //資料讀,地址不變

uchar tcount;  			//中斷計數
uint Timtcount;			//計時變數(秒)
uchar playing,startflag;//遊戲標誌,開始標誌
uchar levelg; 			//記錄當前關卡
uchar man_x,man_y;		//紀錄當前小人所在位置
//**********lcd12864引腳位定義*********************//
sbit wr =P2^0;
sbit rd =P2^1; 
sbit cd =P2^2;
sbit rst=P2^3; 

uchar code Number[][16]= //數字0-9
{
	0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,	    //0
	0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,		//1
	0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,		//2
	0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,		//3
	0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,	    //4
	0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,		//5
	0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,		//6
	0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,		//7
	0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,		//8
	0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,		//9
};
//開機畫面
uchar code start_box[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFC,0x7C,0xC0,0x06,0x30,0xC6,0x00,0x1F,0xFF,0xFF,0x00,0x00,0x00,
0x00,0x00,0x01,0x86,0xC7,0xF0,0x06,0x1F,0xC7,0xF8,0x30,0x00,0x01,0xC0,0x00,0x00,
0x00,0x00,0x01,0x87,0x86,0x18,0x0C,0x01,0x80,0x0C,0x30,0x00,0x00,0xC0,0x00,0x00,
0x00,0x00,0x01,0x87,0x82,0x18,0x1C,0x01,0x80,0x0E,0x30,0x00,0x00,0x40,0x00,0x00,
0x00,0x00,0x01,0x87,0x06,0x0C,0x18,0x01,0x00,0x06,0x30,0x00,0x00,0x40,0x00,0x00,
0x00,0x00,0x0F,0x87,0x07,0x0F,0x10,0x03,0x00,0x0C,0x30,0x00,0x00,0xC0,0x00,0x00,
0x00,0x00,0x0C,0x06,0x00,0x01,0x90,0x43,0x00,0x0C,0x1F,0xFF,0x01,0x80,0x00,0x00,
0x00,0x00,0x0C,0x06,0x00,0x01,0x98,0xC3,0x08,0x38,0x00,0x3E,0x03,0x00,0x00,0x00,
0x00,0x00,0x0C,0x0C,0x00,0x01,0x8F,0xC3,0x1C,0x38,0x00,0x3C,0x06,0x00,0x00,0x00,
0x00,0x00,0x0C,0x0C,0x00,0x03,0x1F,0xC7,0xFC,0x7C,0x7F,0xF6,0x0F,0xE0,0x00,0x00,
0x00,0x00,0x0F,0x88,0x1E,0x1F,0x1C,0x7F,0x67,0xDC,0xC0,0x03,0x18,0x30,0x00,0x00,
0x00,0x00,0x01,0x8C,0x00,0x03,0x18,0x01,0x80,0x0C,0xC0,0x01,0xF0,0x30,0x00,0x00,
0x00,0x00,0x03,0x87,0x80,0x03,0x10,0x00,0x80,0x0C,0xC0,0x00,0x00,0x30,0x00,0x00,
0x00,0x00,0x0E,0x01,0x80,0x03,0x10,0x00,0x9F,0x0C,0xC0,0x00,0x00,0x30,0x00,0x00,
0x00,0x00,0x0C,0x01,0x80,0x03,0x18,0x0F,0x80,0x0C,0xC0,0x00,0x00,0x30,0x00,0x00,
0x00,0x00,0x0C,0x01,0x9E,0x1F,0x0E,0x1B,0x80,0x0C,0xC0,0x00,0x00,0x30,0x00,0x00,
0x00,0x00,0x0C,0x03,0x00,0x03,0x0E,0x31,0x00,0x0C,0x7F,0xF0,0x7F,0xE0,0x00,0x00,
0x00,0x00,0x0C,0x06,0x00,0x03,0x1C,0x30,0x9F,0x0C,0x00,0x30,0x60,0x00,0x00,0x00,
0x00,0x00,0x07,0x86,0x00,0x03,0x38,0x30,0xC0,0x0C,0x00,0x30,0x60,0x00,0x00,0x00,
0x00,0x00,0x01,0x86,0x1E,0x1F,0x30,0x18,0xC0,0x0C,0x01,0xF0,0x60,0x00,0x00,0x00,
0x00,0x00,0x07,0x86,0x00,0x01,0xB0,0x0F,0x80,0x0C,0x03,0x00,0x60,0x00,0x00,0x00,
0x00,0x00,0x0C,0x06,0x00,0x01,0x98,0x07,0x1F,0x0C,0x03,0x00,0x60,0x00,0x00,0x00,
0x00,0x00,0x0C,0x06,0x00,0x01,0x8C,0x06,0x00,0x0C,0x03,0x00,0x60,0x00,0x00,0x00,
0x00,0x00,0x0C,0x06,0x00,0x03,0x07,0x06,0x00,0x0C,0x03,0x00,0x60,0x00,0x00,0x00,
0x00,0x00,0x0C,0x06,0x0F,0xFF,0x03,0x06,0x00,0x0C,0x03,0x00,0x60,0x00,0x00,0x00,
0x00,0x00,0x0C,0x0F,0x18,0x00,0x03,0x07,0x00,0x18,0x03,0x00,0xC0,0x00,0x00,0x00,
0x00,0x00,0x07,0xF9,0xF0,0x00,0x01,0xFD,0xFF,0xF0,0x01,0xFF,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFD,0xFE,0x18,0x7F,0x3F,0xC0,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x8D,0xB6,0x18,0x31,0xB6,0xC0,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x8C,0x30,0x1C,0x31,0x86,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x30,0x3C,0x31,0x86,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x3C,0x3F,0x06,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x30,0x36,0x36,0x06,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x30,0x3E,0x36,0x06,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x30,0x66,0x33,0x06,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x8C,0x30,0x63,0x33,0x06,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x8C,0x30,0x63,0x31,0x86,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF8,0x78,0xF7,0xF9,0xCF,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
/*********************************************
遊戲關卡 一共9關
數字符號表示:人物1 磚頭2 箱子3 目的4 成功5
**********************************************/
uchar code level[][8][8]={
	/*第1關*/
	0,0,2,2,2,2,2,0,
	2,2,2,0,0,0,2,0,
	2,0,3,0,2,0,2,2,
	2,0,2,0,0,4,0,2,
	2,0,0,0,0,2,0,2,
	2,2,0,2,0,0,0,2,
	0,2,1,0,0,2,2,2,
	0,2,2,2,2,2,0,0,
	
	/*第2關*/
	2,2,2,2,2,2,2,2,
	2,0,0,0,0,0,1,2,
	2,0,0,0,5,0,0,2,
	2,0,0,2,2,2,2,2,
	2,2,0,0,2,0,0,0,
	2,0,3,0,2,0,0,0,
	2,0,0,4,2,0,0,0,
	2,2,2,2,2,0,0,0,

	/*第3關*/
	0,0,2,2,2,2,0,0,
	0,0,2,4,4,2,0,0,
	0,2,2,0,4,2,2,0,
	0,2,0,0,3,4,2,0,
	2,2,0,3,0,0,2,2,
	2,0,0,2,3,3,0,2,
	2,0,0,1,0,0,0,2,
	2,2,2,2,2,2,2,2,

	/*第4關*/
	0,0,0,2,2,2,2,0,
	0,2,2,2,0,1,2,0,
	0,2,0,0,3,0,2,0,
	2,2,0,2,0,2,2,2,
	2,0,0,2,0,2,4,2,
	2,0,2,0,0,3,4,2,
	2,0,0,0,0,0,0,2,
	2,2,2,2,2,2,2,2,

	/*第5關*/
	0,0,0,2,2,2,2,0,
	0,2,2,2,0,1,2,0,
	0,2,0,0,3,0,2,0,
	2,2,0,2,0,2,2,2,
	2,0,0,2,0,2,4,2,
	2,0,2,0,0,0,0,2,
	2,0,0,0,0,0,0,2,
	2,2,2,2,2,2,2,2,

	/*第6關*/
	0,0,0,2,2,2,2,0,
	0,2,2,2,0,1,2,0,
	0,2,0,0,3,0,2,0,
	2,2,0,2,0,2,2,2,
	2,0,0,2,0,2,4,2,
	2,0,2,0,0,3,4,2,
	2,0,3,0,0,0,4,2,
	2,2,2,2,2,2,2,2,
	
	/*第7關*/
	0,0,2,2,2,2,2,0,
	2,2,2,0,0,0,2,0,
	2,0,3,0,2,0,2,2,
	2,0,2,0,0,4,0,2,
	2,0,0,0,0,2,0,2,
	2,2,3,2,4,0,0,2,
	0,2,1,0,0,2,2,2,
	0,2,2,2,2,2,0,0, 	
	
	/*第8關*/
	0,2,2,2,2,0,0,0,
	2,2,0,0,2,0,0,0,
	2,1,3,0,2,0,0,0,
	2,2,3,0,2,2,0,0,
	2,2,0,3,0,2,0,0,
	2,4,3,0,0,2,0,0,
	2,4,4,5,4,2,0,0,
	2,2,2,2,2,2,0,0,

	/*第9關*/
	0,0,0,2,2,2,2,0,
	0,2,2,2,0,0,2,0,
	2,2,0,1,3,0,2,0,
	2,0,4,3,0,0,2,0,
	2,0,4,5,0,2,2,0,
	2,0,4,3,0,2,0,0,
	2,2,0,0,2,2,0,0,
	0,2,2,2,2,0,0,0,
	
};
uchar level_temp[8][8]=				//記錄當前的遊戲介面的變化
{
	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,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,0,0,0,0,
};
uchar code elements[][8]=
{
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  //0空白
	0x3C,0x7E,0x66,0x3C,0x7E,0x99,0x3C,0x66,  //1人物
	0x7F,0x7F,0x7F,0x00,0xEF,0xEF,0xEF,0x00,  //2磚頭
	0xFF,0xC3,0xA5,0x99,0x99,0xA5,0xC3,0xFF,  //3箱子
	0x00,0x18,0x24,0x4A,0x52,0x24,0x18,0x00,  //4目標
	0xFF,0xBD,0xDB,0xE7,0xE7,0xDB,0xBD,0xFF,  //5箱子到達目標	 	
};	
unsigned char code Di[]=	//"第"字														  //第
{
	0x20,0x40,0x3F,0x7E,0x48,0x90,0x85,0x08,0x3F,0xF8,0x01,0x08,0x01,0x08,0x3F,0xF8,
	0x21,0x00,0x21,0x00,0x3F,0xFC,0x03,0x04,0x05,0x04,0x19,0x28,0xE1,0x10,0x01,0x00,
};
unsigned char code Guan[]=	//“關”字													   //關
{
	0x10,0x10,0x08,0x10,0x08,0x20,0x00,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,0x01,0x00,
	0xFF,0xFE,0x01,0x00,0x02,0x80,0x02,0x80,0x04,0x40,0x08,0x20,0x30,0x18,0xC0,0x06,
};

unsigned char code Yong[]=	//“用”字														//用
{
	0x00,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,0x21,0x08,
	0x21,0x08,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x41,0x08,0x41,0x28,0x80,0x10,
}; 

unsigned char code Shi[]=	//“時”字															//時
{
	0x00,0x08,0x00,0x08,0x7C,0x08,0x44,0x08,0x45,0xFE,0x44,0x08,0x44,0x08,0x7C,0x08,
	0x44,0x88,0x44,0x48,0x44,0x48,0x44,0x08,0x7C,0x08,0x44,0x08,0x00,0x28,0x00,0x10,
};

unsigned char code Miao[]=	//“秒”字														//秒
{
	0x08,0x20,0x1C,0x20,0xF0,0x20,0x10,0xA8,0x10,0xA4,0xFC,0xA2,0x11,0x22,0x31,0x20,
	0x3A,0x24,0x54,0x24,0x54,0x28,0x90,0x08,0x10,0x10,0x10,0x20,0x10,0xC0,0x00,0x00,
};



main.c
#include<reg51.h>
#include"Variable.h"
/**************************************************
函式名:status_bit_01()
功能:狀態位sta1(讀/寫指令),sta0(讀/寫資料)判斷
入口引數:
返回值:狀態值i	
***************************************************/ 
uchar status_bit_01()     
{
	uchar i;  	
	P0=0xff;
	cd=1;
	rd=0;
	for(i=10;i>0;i--)
	{
		if((P1&0x03)==0x03)
		break;
	}
	rd=1;
	return i;                 
}

/*********************************************
函式名:write_data(uchar dat)
功能:寫資料
入口引數:8位資料dat
返回值:
*********************************************/
void write_data(uchar dat)
{
	while(status_bit_01()==0); 
	rd=1;cd=0;wr=0;
	P0=dat;
	wr=1;cd=1;	  //一定要有這一句,補完後面的時序!
} 
/*********************************************
函式名:write_cmd1(uchar cmd)
功能:寫命令,無引數
入口引數:8位命令cmd
返回值:
*********************************************/
void write_cmd1(uchar cmd)
{
	while(status_bit_01()==0);
	rd=1;cd=1;wr=0;
	P0=cmd;
	wr=1;cd=0;	 //一定要有這一句,補完後面的時序!
}
 
/************************************************
函式名:write_cmd3(uchar cmd)
功能:寫雙引數命令
入口引數:8位資料data1,8位資料data2,8位命令cmd
返回值:
*************************************************/
void write_cmd3(uchar data1,uchar data2,uchar cmd)
{
   	write_data(data1); 	
	write_data(data2); 
	write_cmd1(cmd);
}

/************************************************
函式名:setc_xy()
功能:定位
入口引數:列字元地址x,行位地址y
返回值:
*************************************************/
void setc_xy(uchar x, uchar y)
{
	int temp;
	temp = y * 0x10 + x;
	write_cmd3(temp&0xff,temp/0xff,add_pos);		
}
/*********************************************
函式名:write_cmd2(uchar cmd)
功能:寫單引數命令
入口引數:8位資料dat,8位命令cmd
返回值:
*********************************************/
void write_cmd2(uchar dat,uchar cmd)
{
	write_data(dat);
	write_cmd1(cmd);
}

/*********************************
功能:分解計時值的各位,並顯示在響應的位置上
函式名:	time_change(unsigned int ttime)
入口引數:計時值
返回值:

***********************************/

void time_change(uint ttime)
{
	uchar a1,a2,a3,a4,a5;
	uchar i,j;
	a1=ttime/10000;	  
	a2=ttime/1000%10;
	a3=ttime/100%10;
	a4=ttime/10%10;
	a5=ttime%10;


	for(j=0;j<16;j++)	//a1
	{
		for(i=0;i<1;i++)
		{
			setc_xy(9+i,32+j); 
			write_cmd2(Number[a1][j],inc_wr);			 
		}
	}

	for(j=0;j<16;j++)	//a2
	{
		for(i=0;i<1;i++)
		{
			setc_xy(10+i,32+j);
			write_cmd2(Number[a2][j],inc_wr);			 
		}
	}

	for(j=0;j<16;j++)	 //a3
	{
		for(i=0;i<1;i++)
		{
			setc_xy(11+i,32+j);
			write_cmd2(Number[a3][j],inc_wr); 
		}
	}

	for(j=0;j<16;j++)	//a4
	{
		for(i=0;i<1;i++)
		{
			setc_xy(12+i,32+j);
			write_cmd2(Number[a4][j],inc_wr);			 
		}
	}

	for(j=0;j<16;j++)	 //a5
	{
		for(i=0;i<1;i++)
		{
			setc_xy(13+i,32+j);
			write_cmd2(Number[a5][j],inc_wr);		
		}
	} 		
}
/*********************************
功能:初始化51
函式名:	int51_timec()
入口引數:
返回值:

***********************************/
void int51_timec()
{
	EA=1;
	TMOD=0x11;
	ET0=1;
	TR0=0;
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;

}
/*********************************
功能:定時器0中斷
函式名:	t0_tt()
入口引數:
返回值:

***********************************/
void t0_tt() interrupt 1
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	tcount++;
	if(tcount==20)
	{
		tcount=0;
		Timtcount++;
		time_change(Timtcount);	
	}			
}
/************************************************
函式名:init_12864()
功能:初始化lcd12864
入口引數:
返回值:
*************************************************/	
void init_12864()
{
	wr=1;rd=1;cd=1;rst=1;//初始化
	write_cmd3(0x01,0x00,0x21);//游標指標設定
	write_cmd3(0x00,0x00,0x42);//圖形區首地址
	write_cmd3(16,0x00,0x43);//圖形區寬度 
	write_cmd1(0x88);//顯示方式設定,正常顯示
	write_cmd1(0x98);//圖形方式顯示,不顯示字母,只打點
	write_cmd1(0xa0);//游標形狀設定1 0 1 0 0 N2 N1 N0
}
/************************************************
函式名:start_ui()
功能:開機畫面
入口引數:
返回值:
*************************************************/
void start_ui()
{
	uint i;
	setc_xy(0,0);
	for(i=0;i<1024;i++)
	{
		write_cmd2(start_box[i],inc_wr);
	}
} 
/********************************
函式名:delayms(x)
功能:按鍵掃描延時
入口引數:x=延遲時間
返回值:
*********************************/
void delayms(uint x)
{
	uchar i;
	while(x--); 
	for(i=0;i<100;i++);
}  

/********************************
函式名:keys_scan()
功能:按鍵掃描
入口引數:
返回值:按鍵號keyno 
*********************************/
uchar  keys_scan()	   
{	
	uchar tmp; //高4位置1,放入4行
	uchar keyno=16;
	if(P1 != 0x0f)
	{
		P1 = 0x0f; 	
		delayms(1); 
		//按鍵後00001111將程式設計0000××××,×中有一個為0.其餘為1
		//下面的異或操作會把3個1變成0,唯一的0變成1
		tmp = P1 ^ 0x0f;
		//判斷按鍵發生於0-3列中哪一列
		switch(tmp)
		{
			case 1: keyno = 0;break;
			case 2: keyno = 1;break;
			case 4: keyno = 2;break;
			case 8: keyno = 3;break;
			default:keyno = 16;//無鍵按下	
		}	
		//低4位置0,放入4列
		P1 = 0xf0;
		delayms(1);
		//按鍵後11110000將變成××××0000,×中有1個為0,3個仍為1
		tmp = (P1 >> 4)^ 0x0f;
		//對0-3行分別附加起始值0,4,8,12
		switch(tmp)
		{
			case 1:keyno += 0;break;
			case 2:keyno += 4;break;
			case 4:keyno += 8;break;
			case 8:keyno += 12;break;	
		}
		P1=0x0f;	
		return keyno;
	}	
	return keyno; 	
}
/************************************************
函式名:clc()
功能:清屏
入口引數:
返回值:
*************************************************/
void clc()
{			  
	int i;
	write_cmd3(0,0,add_pos);
	for(i = 0; i < 1024; i++)
		write_cmd2(0x00,inc_wr);
}
/************************************************
函式名:printelement()
功能:指定字元位置,顯示元素
入口引數:列字元地址xh,行字元地址yh,元素程式碼elnum
返回值:
*************************************************/
void printelement(uchar xh, uchar yh,uchar elnum)	 
{
	uchar i;
	int temp; 	
	for(i=0;i<8;i++)  //行地址加+1
	{
		temp = yh* 0x80+i*0x10 + xh;
		write_cmd3(temp&0xff,temp/0xff,add_pos);
		write_cmd2(elements[elnum][i],noc_wr); 
	} 	
}
void display_time()
{
	unsigned i,j;	
	for(j=0;j<16;j++)//顯示“第”字
	{
		for(i=0;i<2;i++)
		{
			setc_xy(9+i,j);
			write_cmd2(Di[j*2+i],inc_wr);//陣列的地址不要亂!
		}
	}

	for(j=0;j<16;j++)//關數
	{
		for(i=0;i<1;i++)
		{
			setc_xy(11+i,j);
			write_cmd2(Number[levelg+1][j],inc_wr);	//陣列的地址不要亂!
		}
	}

	for(j=0;j<16;j++)
	{
		for(i=0;i<2;i++)
		{
			setc_xy(12+i,j);
			write_cmd2(Guan[j*2+i],inc_wr);//“關”字	 
		}
	}

	for(j=0;j<16;j++)
	{
		for(i=0;i<2;i++)												//列式按字元定址的,行是按位定址的
		{
			setc_xy(9+i,16+j);
			write_cmd2(Yong[j*2+i],inc_wr);		//“用”字	 
		}
	}

	for(j=0;j<16;j++)
	{
		for(i=0;i<2;i++)
		{
			setc_xy(12+i,16+j);
			write_cmd2(Shi[j*2+i],inc_wr);		//“時”字	 
		}
	}

	for(j=0;j<16;j++)
	{
		for(i=0;i<2;i++)
		{				 
			setc_xy(14+i,32+j);
			write_cmd2(Miao[j*2+i],inc_wr);		//“秒”字	 
		}
	}  
}

/************************************************
函式名:gamebg()
功能:顯示遊戲本關卡遊戲介面
入口引數:關卡代號g
返回值:
*************************************************/
void gamebg(uchar g)
{
	unsigned i,j;
	for(i=0;i<8;i++)                                      //行
	{
		for(j=0;j<8;j++)                                  //列
		{
			if(level[g][i][j]==1) 
			{
				man_x=j;
				man_y=i;
			}
			level_temp[i][j]=level[g][i][j];              //當前關卡存入遊戲緩衝
			printelement(j,i,level_temp[i][j]);          //顯示當前關卡	
		}
	}

	display_time();
	time_change(Timtcount);	
		
}
/************************************************
函式名:level_suc()
功能:判斷是否通過本關卡
入口引數:
返回值:
*************************************************/
void level_suc()
{
	uchar i,j,k=1;
	for(i = 0; i < 8; i++)	                                    //行
	{
		if(k==0) break;
		for(j = 0; j < 8; j++)									//列
		{	                                                     
			if(level[levelg][i][j]==4||level[levelg][i][j]==5)	//迴圈掃描目標位置都有箱子在,此關卡就通過
			{
				if(level_temp[i][j]==5)
					k=1;										//此位置箱子在目標位置上
				else
				{
					k=0;										//有目標位置沒有箱子
					break;
				}
			}
		}
	}
	if(k==1)													 //所有目標位置都有箱子
	{
		if(levelg<8)
			levelg+=1;
		else 
			levelg=0;			 //通關後重新從第一關開始
		Timtcount=0;			 //計時清零
		TH0=(65536-50000)/256;
		TL0=(65536-50000)%256;
		tcount=0;
		gamebg(levelg);			
	}
}

/************************************************
函式名:key_up()
功能:按向上鍵的操作
入口引數:
返回值:
註釋含義:
          ?=:是否等與
		  上:本位置的上一個位置
		  目: 箱子的目標位置
		  成:箱子在目標位置上
		  源:位置最開始的元素
		  本:本位置
		  空:空白位置
		  再上:本位置的再上一個位置
		  箱:箱子
*************************************************/
void key_up()
{
	if(level_temp[man_y-1][man_x]==0||level_temp[man_y-1][man_x]==4)	             //上?=目/成   
	{		 
		if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)           //本,源?=目/成
		{
			level_temp[man_y][man_x]=4;										         //本=目
			printelement(man_x,man_y,4);	   
		}
		else
		{
			level_temp[man_y][man_x]=0;										         //本=空
			printelement(man_x,man_y,0);
		}
		man_y=man_y-1;													             //上=人//完成一次移動
		level_temp[man_y][man_x]=1;
		printelement(man_x,man_y,1);
	} 
	else if(level_temp[man_y-1][man_x]==3)								             //上?=箱
	{				  
		if(level_temp[man_y-2][man_x]==0)									         //再上?=空白
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)	     //本,源?=目/成
			{
				level_temp[man_y][man_x]=4;										     //本=目
				printelement(man_x,man_y,4);
			}
			else																	 //本=空
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}
			man_y=man_y-1;														     //上=人
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y-1][man_x]=3;										     //再上=箱//完成一次移動
			printelement(man_x,man_y-1,3);
		}
		else if(level_temp[man_y-2][man_x]==4)									     //再上?=目
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)		 //本,源?=目/成
			{
				level_temp[man_y][man_x]=4;											 //本=目
				printelement(man_x,man_y,4);
			}
			else																	 //本=空
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}
			man_y=man_y-1;					   
			level_temp[man_y][man_x]=1;												 //上=人
			printelement(man_x,man_y,1);
			level_temp[man_y-1][man_x]=5;											 //再上=成
			printelement(man_x,man_y-1,5); 			
		} 
	}
	else if(level_temp[man_y-1][man_x]==5)	                                          //上?=成
	{		   
		if(level_temp[man_y-2][man_x]==0)											  //再上?=空
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)		  //本,源?=目/成
			{
				level_temp[man_y][man_x]=4;											  //本=目
				printelement(man_x,man_y,4);
			}
			else
			{																		  //本=空
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}
			man_y=man_y-1;															  //上=人
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y-1][man_x]=3;										      //再上=箱
			printelement(man_x,man_y-1,3);
		}
		else if(level_temp[man_y-2][man_x]==4)										  //再上?=目
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)		  //本,源?=目/成
			{
				level_temp[man_y][man_x]=4;											  //本=目
				printelement(man_x,man_y,4);
			}
			else																	  //本=空
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}
			man_y=man_y-1;															  //上=人
		    level_temp[man_y][man_x]=1;
		    printelement(man_x,man_y,1);
		    level_temp[man_y-1][man_x]=5;											  //再上=成
		    printelement(man_x,man_y-1,5);	 		    
		}  			
	}
	level_suc();                                                                    //判斷是否完成本關				 
}

/************************************************
函式名:key_down()
功能:按向下鍵的操作
入口引數:
返回值:
*************************************************/
void key_down()
{
	if(level_temp[man_y+1][man_x]==0||level_temp[man_y+1][man_x]==4)				   
	{
		if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)			   
		{
			level_temp[man_y][man_x]=4;												   
			printelement(man_x,man_y,4);
		}
		else
		{																			   
			level_temp[man_y][man_x]=0;
			printelement(man_x,man_y,0);
		} 																			   
	    man_y=man_y+1;
		level_temp[man_y][man_x]=1;
		printelement(man_x,man_y,1);
	}
	else if(level_temp[man_y+1][man_x]==3)											   
	{
		if(level_temp[man_y+2][man_x]==0)											  
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)		   
			{
				level_temp[man_y][man_x]=4;											   
			    printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;											  
			    printelement(man_x,man_y,0);
			} 
			man_y=man_y+1;															   
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y+1][man_x]=3;											   
			printelement(man_x,man_y+1,3);
		}
		else if(level_temp[man_y+2][man_x]==4)											
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
				printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}
			man_y=man_y+1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y+1][man_x]=5;
			printelement(man_x,man_y+1,5);			
		}
	}
	else if(level_temp[man_y+1][man_x]==5)
	{
		if(level_temp[man_y+2][man_x]==0)
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
			    printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
			    printelement(man_x,man_y,0);
			}
				man_y=man_y+1;
				level_temp[man_y][man_x]=1;
				printelement(man_x,man_y,1);
				level_temp[man_y+1][man_x]=3;
				printelement(man_x,man_y+1,3);
		}
		else if(level_temp[man_y+2][man_x]==4)
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
			    printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
			    printelement(man_x,man_y,0);
			}					      
			man_y=man_y+1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y+1][man_x]=5;
			printelement(man_x,man_y+1,5); 						  
		} 				  
	}				  				  
	level_suc();
}
/************************************************
函式名:key_left()
功能:按向左鍵的操作
入口引數:
返回值:
*************************************************/
void key_left()
{
	if(level_temp[man_y][man_x-1]==0||level_temp[man_y][man_x-1]==4)
	{
		if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
		{
			level_temp[man_y][man_x]=4;
			printelement(man_x,man_y,4);
		}
		else
		{
			level_temp[man_y][man_x]=0;
			printelement(man_x,man_y,0);
		}
		man_x=man_x-1;
		level_temp[man_y][man_x]=1;
		printelement(man_x,man_y,1);
	}
	else if(level_temp[man_y][man_x-1]==3)
	{
		if(level_temp[man_y][man_x-2]==0)
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
				printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			} 
			man_x=man_x-1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y][man_x-1]=3;
			printelement(man_x-1,man_y,3);
		} 
		else if(level_temp[man_y][man_x-2]==4)
		{ 
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
				printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}
			man_x=man_x-1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y][man_x-1]=5;
			printelement(man_x-1,man_y,5);
		}
	}  
	else if(level_temp[man_y][man_x-1]==5)
	{
		if(level_temp[man_y][man_x-2]==0)
		{	
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
				printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}
			man_x=man_x-1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y][man_x-1]=3;
			printelement(man_x-1,man_y,3); 						      
		}
		else if(level_temp[man_y][man_x-2]==4)
		{	  
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
				printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}	  					      
			man_x=man_x-1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y][man_x-1]=5;
			printelement(man_x-1,man_y,5);
		}						 
	}			
	level_suc();			
}
/************************************************
函式名:key_right()
功能:按向右鍵的操作
入口引數:
返回值:
*************************************************/
void key_right()
{
	if(level_temp[man_y][man_x+1]==0||level_temp[man_y][man_x+1]==4)
	{
		if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
		{
			level_temp[man_y][man_x]=4;
			printelement(man_x,man_y,4);
		}
		else
		{
			level_temp[man_y][man_x]=0;
			printelement(man_x,man_y,0);
		}
			man_x=man_x+1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
	}	
	else if(level_temp[man_y][man_x+1]==3)
	{	 
		if(level_temp[man_y][man_x+2]==0)
		{	  
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
				printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}
			man_x=man_x+1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y][man_x+1]=3;
			printelement(man_x+1,man_y,3);
		}
		else if(level_temp[man_y][man_x+2]==4)
		{	  
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
				printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}	
			man_x=man_x+1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y][man_x+1]=5;
			printelement(man_x+1,man_y,5);						  
		}	
	}	 
	else if(level_temp[man_y][man_x+1]==5)
	{	  
		if(level_temp[man_y][man_x+2]==0)
		{
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
				printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}	
			man_x=man_x+1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y][man_x+1]=3;
			printelement(man_x+1,man_y,3); 						      
		}
		else if(level_temp[man_y][man_x+2]==4)
		{	  
			if(level[levelg][man_y][man_x]==4||level[levelg][man_y][man_x]==5)
			{
				level_temp[man_y][man_x]=4;
				printelement(man_x,man_y,4);
			}
			else
			{
				level_temp[man_y][man_x]=0;
				printelement(man_x,man_y,0);
			}					      
			man_x=man_x+1;
			level_temp[man_y][man_x]=1;
			printelement(man_x,man_y,1);
			level_temp[man_y][man_x+1]=5;
			printelement(man_x+1,man_y,5); 						  
		}						 
	}					 
	level_suc();	
}
/************************************************
函式名:void put_box()
功能:推箱子游戲規則
入口引數:
返回值:
*************************************************/
void put_box()
{
	uint keyupdate;
	keyupdate=16;	
	if(P1!=0x0f)//若沒有這句,有可能在按鍵掃描後執行while(P1!=0x0f),就得不到按鍵值,使按鍵失效
	{
		keyupdate=keys_scan();
		while(P1!=0x0f);	  
	}		
	switch(keyupdate)
	{
		case 0:  key_up();break;				                                 
		case 1:key_down();break;	
		case 2:key_left();break;
		case 3:key_right();break;		
		case 4:
				playing=0;
				startflag=1;
				Timtcount=0;
				TR0=0;
				clc();					
				start_ui();			
				break;	//退出遊戲
		case 5:
				
				if(levelg!=8)
					levelg++;
				gamebg(levelg);		  //顯示第一關
				Timtcount=0;
				TH0=(65536-50000)/256;
				TL0=(65536-50000)%256;
				tcount=0;
				break;				  //下一關
		case 6:
				
				if(levelg!=0)
				levelg--; 				
				gamebg(levelg);		  //顯示第一關
				Timtcount=0;
				TH0=(65536-50000)/256;
				TL0=(65536-50000)%256;
				tcount=0;
				break;                     //上一關

	}
}

void main()
{
	uchar kupdate;
	uchar startflag; 
	int51_timec();               //初始化51
	init_12864();               //初始化12864
	startflag=1;
	playing=0;
	start_ui();

	while(1)
	{
		while(startflag)			 //等待確定鍵按下
		{
		  	kupdate=16;	
			if(P1!=0x0f)				//若沒有這句,有可能在按鍵掃描後執行while(P1!=0x0f),就得不到按鍵值,使按鍵失效
			{
				kupdate=keys_scan();
				while(P1!=0x0f);	  
			}
			switch(kupdate)
			{
				case 4:
						startflag=0;
						playing=1;
						break;
			} 
		}
		
		clc();//清屏 
		levelg=0; 		
		gamebg(levelg);		  //顯示第一關 
		Timtcount=0;
		TR0=1;
		while(playing)		  //遊戲中...
		{
		 	put_box();	 
		}
		startflag=1;
	}			
}