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

📄 snake.h

📁 诺基亚5110 LCD资料
💻 H
字号:
/*------------------------------  
SNAKE.H
-------------------------------*/ 
#ifndef _SNAKE_INCLUDED_
#define _SNAKE_INCLUDED_    

#include<stdlib.h>    //包含srand函数
#include <delay.h>    
#include <string.h>  //包含memset函数
#include  "5110.h"
            
#define GAME_FIELD_HEIGHT 10     
#define GAME_FIELD_WIDTH 21
#define SNAKE_GROUND	0
#define SNAKE_UP		1	
#define SNAKE_RIGHT		2	
#define SNAKE_DOWN		3
#define SNAKE_LEFT		4
#define SNAKE_FOOD		255	 

#define KEY_UP PIND.6
#define KEY_DOWN PIND.5
#define KEY_LEFT PINB.0
#define KEY_RIGHT PIND.7 
#define KEY_QUIT PIND.0

#define TIMER 2

typedef struct SnakeBody //蛇身结构体
{
	unsigned int x;
	unsigned int y;
}SNAKE_BODY;

SNAKE_BODY SnakeHead = {0}; //蛇头
SNAKE_BODY SnakeTail = {0}; //蛇尾
unsigned char cDisplayRam[504] = {0};    //显示缓存6*84
unsigned char cGameField[GAME_FIELD_HEIGHT*GAME_FIELD_WIDTH] = {0}; //游戏地图 
unsigned char keyCode = 0;   //键值
unsigned char snakeHeadDir;  //蛇头运动方向
unsigned char timerCnt = 0;   //定时器累加变量
unsigned char snakeMoveFlag = 0;  //蛇运动标志位
eeprom unsigned char  topMark = 0;
flash unsigned char cBmpCode[160] =   //snake图形
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xB8,0xB8,0xF8,
0xF0,0xE0,0x80,0x80,0x80,0x80,0x00,0xE0,0xF0,0x98,0x08,0x08,0xB8,0xB0,0x80,0x80,
0x80,0x00,0xF8,0xF8,0xF8,0xC0,0x00,0xF8,0xF8,0x00,0x80,0x80,0x00,0x00,0xE0,0xF8,
0xF8,0xF8,0x00,0x80,0x80,0x80,0x00,0xF8,0xF8,0x80,0xC0,0xF0,0x38,0x88,0x80,0x80,
0x00,0xF8,0xF8,0x08,0x08,0x08,0x08,0x00,0x80,0x00,0x00,0x00,0x80,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0F,0x1F,0x3F,
0x7F,0x77,0x77,0x7F,0x3F,0x1F,0x07,0x07,0x07,0x07,0x17,0x76,0x65,0x45,0x43,0x7E,
0x3E,0x01,0x0F,0x0F,0x07,0x78,0x7F,0x07,0x03,0x1F,0x7C,0x7F,0x07,0x08,0x0F,0x67,
0x78,0x1F,0x07,0x04,0x07,0x7F,0x7C,0x03,0x0F,0x07,0x78,0x7F,0x07,0x03,0x0F,0x7F,
0x70,0x0F,0x0F,0x07,0x78,0x7F,0x47,0x41,0x41,0x41,0x01,0x00,0x0F,0x07,0x03,0x03
};
void Timer0Initial(void);  
void SnakeInitial(void);
unsigned int SnakeRand(unsigned int dRange);  
void SnakePutFood(void);
void RefreshRam(unsigned char *pcBuff);
void DrawBox(unsigned int x, unsigned int y);
void ClearBox(unsigned int x, unsigned int y);
void SnakeOption(void);
unsigned char KeyScan(void);
void SnakeGame(void);

/*
*函数介绍:刷新显示缓存
*输入参数:缓存数组
*输出参数:无
*返回值:  无
*/
void RefreshRam(unsigned char *pcBuff) 
{
    unsigned int i;
    WriteByte(0x80, 0);
	WriteByte(0x40, 0);
	WriteByte(0x80, 0);				
    for (i = 0; i < 504; i++)
    {
        WriteByte(*pcBuff++, 1);
    }    
}

/*
*函数介绍:画点块函数
*输入参数:画点块坐标
*输出参数:无
*返回值:  无
*/
void DrawBox(unsigned int x, unsigned int y)
{
	unsigned char Temp = 0x0F;     //方块为4*4点块
	unsigned char offset;
	offset = y * 4 % 8;
	x = x * 4;
	y = y * 4 / 8;
	Temp <<= offset;
	cDisplayRam[y*84+x] |= Temp;
	cDisplayRam[y*84+x + 1] |= Temp;
	cDisplayRam[y*84+x + 2] |= Temp;
	cDisplayRam[y*84+x + 3] |= Temp;
	RefreshRam(cDisplayRam);
}

/*
*函数介绍:清点块函数
*输入参数:清除点块坐标
*输出参数:无
*返回值:  无
*/
void ClearBox(unsigned int x, unsigned int y)
{
	unsigned char Temp = 0x0F;
	unsigned char offset;
	offset = y * 4 % 8;
	x = x * 4;
	y = y * 4 / 8;
	Temp <<= offset;
	cDisplayRam[y*84+x] &= ~Temp;         //取反清除
	cDisplayRam[y*84+x + 1] &= ~Temp;
	cDisplayRam[y*84+x + 2] &= ~Temp;
	cDisplayRam[y*84+x + 3] &= ~Temp;
	RefreshRam(cDisplayRam);
}

/*
*函数介绍:按键扫描函数
*输入参数:无
*输出参数:无
*返回值:  键值或255
*/
unsigned char KeyScan(void)
{
	if(!KEY_UP)
	{
		delay_ms(TIMER);
		if(!KEY_UP)
		{
			return SNAKE_UP;
		}
	}
	else if(!KEY_DOWN)
	{
		delay_ms(TIMER);
		if(!KEY_DOWN)
		{
			return SNAKE_DOWN;
		}
	}
	else if(!KEY_LEFT)
	{
		delay_ms(TIMER);
		if(!KEY_LEFT)
		{
			return SNAKE_LEFT;
		}
	}
	else if(!KEY_RIGHT)
	{
		delay_ms(TIMER);
		if(!KEY_RIGHT)
		{
			return SNAKE_RIGHT;
		}
	}
	else 
	{
		return 255;
	}
}

/*
*函数介绍:food随即分布函数
*输入参数:dRange
*输出参数:unsigned int
*返回值:  无
*/
unsigned int SnakeRand(unsigned int dRange)
{
	srand(TCNT0);
	return (rand()%dRange) ;
} 

/*
*函数介绍:放置food函数
*输入参数:无
*输出参数:无
*返回值:  无
*/ 
void SnakePutFood(void)
{
	unsigned int x;
	unsigned int y;
	do
	{
		x = SnakeRand(GAME_FIELD_WIDTH);
		y = SnakeRand(GAME_FIELD_HEIGHT);
	}while( cGameField[y*GAME_FIELD_WIDTH+x] != SNAKE_GROUND);
	cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_FOOD;
	DrawBox(x, y);
}

/*
*函数介绍:贪吃蛇初始化函数
*输入参数:无
*输出参数:无
*返回值:  无
*/
void SnakeInitial(void)
{
	unsigned int i;
	unsigned int j;
	for(i = 0; i < GAME_FIELD_HEIGHT; i ++) //打扫游戏场地
	{
		for(j = 0; j < GAME_FIELD_WIDTH; j ++)
		{
			cGameField[i*GAME_FIELD_WIDTH+j] = SNAKE_GROUND;
		}
	}

	memset(cDisplayRam,0, 504);//清空显示缓存
	SnakeHead.x = 11;//设置蛇头位置
	SnakeHead.y = 3; 
	SnakeTail.x = 8;//设置蛇尾位置
	SnakeTail.y = 3;
	DrawBox(11, 3); //画出蛇头
	snakeHeadDir = SNAKE_RIGHT;
	DrawBox(10, 3); //画蛇身
	cGameField[3*GAME_FIELD_WIDTH+10] = SNAKE_RIGHT; //移动方向右
	DrawBox(9, 3); //画蛇身
	cGameField[3*GAME_FIELD_WIDTH+9] = SNAKE_RIGHT; //移动方向右
	DrawBox(8, 3); //画蛇尾
	cGameField[3*GAME_FIELD_WIDTH+8] = SNAKE_RIGHT; //移动方向右
	SnakePutFood();
}

/*
*函数介绍:贪吃蛇游戏函数
*输入参数:无
*输出参数:无
*返回值:  无
*/
void SnakeGame(void)
{
	unsigned int x = 0;
	unsigned int y = 0;
	unsigned int foodCnt = 0; //食物计数器
	unsigned char markTab[] = {"Mark:"};
    unsigned char overTab[] = {"Game over"}; 
    unsigned char coolTab[] = {"You are Cool!"}; 
    unsigned char scoreTab[] = {"Score:"};
	while(1)
	{
		keyCode = KeyScan(); //获取用户按键
		PrintString(10, 5, scoreTab);
		PrintChar(numberTab[foodCnt/100]);
		PrintChar(numberTab[foodCnt%100/10]);
		PrintChar(numberTab[foodCnt%10]);
		if (KEY_QUIT == 0)      //退出游戏           
		{
		    topMark = foodCnt;
		    Clean();
		    break;
		}
		if(keyCode != 255)
		{	
			if(keyCode != ((snakeHeadDir - 1 + 2) % 4) + 1) //如果不是后退									
			{
				snakeHeadDir = keyCode;
			}
		}
		if(snakeMoveFlag == 1)     //运动延时时间到
		{
			#asm("cli")            //关闭中断
			snakeMoveFlag = 0;	
			if(cGameField[y*GAME_FIELD_WIDTH+x] != SNAKE_FOOD) //如果没有吃到食物
			{
				x = SnakeTail.x; //获取当前蛇尾位置
				y = SnakeTail.y;
				switch(cGameField[y*GAME_FIELD_WIDTH+x]) //判断蛇尾的移动方向
				{
					case SNAKE_UP:
					{
						if(y == 0)
						{
							y = GAME_FIELD_HEIGHT;
						}
						y--;
						break;	
					}	
					case SNAKE_DOWN:
					{
						y++;
						if(y == GAME_FIELD_HEIGHT)
						{
							y = 0;
						}
						break;	
					}		
					case SNAKE_LEFT:
					{
						if(x == 0) 
						{
							x = GAME_FIELD_WIDTH; 
						}
						x--;
						break;
					}
					case SNAKE_RIGHT:
					{
						x++;
						if(x == GAME_FIELD_WIDTH) //如果移动到场地宽度
						{
							x = 0; //水平位置清零
						}
						break;
					}
					default:
						break;
				}
				cGameField[SnakeTail.y*GAME_FIELD_WIDTH+SnakeTail.x] = SNAKE_GROUND;
				ClearBox(SnakeTail.x , SnakeTail.y); //清除尾巴
				SnakeTail.x = x; //重新定位蛇尾
				SnakeTail.y = y;
			}
			else //吃到食物  
			{
				SnakePutFood();
				foodCnt++;
				if(foodCnt >= 284) //满分
				{
					PrintString(15, 2, coolTab);
					PrintString(20, 4, markTab);
					PrintChar(numberTab[foodCnt/100]);
				    PrintChar(numberTab[foodCnt%100/10]);
				    PrintChar(numberTab[foodCnt%10]);
				}
			}
			x = SnakeHead.x; //获取当前蛇头位置
			y = SnakeHead.y;			
			switch(snakeHeadDir) //判断蛇头的移动方向
			{
				case SNAKE_UP:
				{	
					cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_UP;
					if(y == 0)
					{	
						y = GAME_FIELD_HEIGHT;
					}
					y--;
					break;
				}
				case SNAKE_DOWN:
				{	
					cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_DOWN;
					y++;
					if(y == GAME_FIELD_HEIGHT) 
					{
						y = 0; 
					}
					break;		
				}
				case SNAKE_LEFT:
				{
					cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_LEFT;
					if(x == 0)
					{	
						x = GAME_FIELD_WIDTH;
					}
					x--;
					break;
				}			
				case SNAKE_RIGHT:
				{
					cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_RIGHT;
					x++;
					if(x == GAME_FIELD_WIDTH)
					{
						x = 0;
					}
					break;
				}
				default:
				{
					break;
				}
			}
			DrawBox(x, y);
			SnakeHead.x = x; //重新定位蛇头
			SnakeHead.y = y;  
			if(cGameField[y*GAME_FIELD_WIDTH+x] != SNAKE_GROUND && cGameField[y*GAME_FIELD_WIDTH+x] 
								!= SNAKE_FOOD)
			{
				PrintString(20, 2, overTab);
				PrintString(20, 4, markTab);
				topMark = foodCnt; 
				SetAddress(50, 4);
				PrintChar(numberTab[foodCnt/100]);
				PrintChar(numberTab[foodCnt%100/10]);
				PrintChar(numberTab[foodCnt%10]);
				memset(cDisplayRam,0, 504); 
				delay_ms(200);  
				Clean();
				#asm("sei")                                     
				return;
			}			
			TCNT0 = 150;
			#asm("sei") 
		}

	}	
}

/*
*函数介绍:界面选择函数
*输入参数:无
*输出参数:无
*返回值:  无
*/
void SnakeOption(void)
{
	unsigned char i = 3;
	unsigned char menuTab0[] = {"New Game"};   
    unsigned char menuTab1[] = {"Top Mark"};
    unsigned char menuTab2[] = {"Help"};
    unsigned char pointTab[] = {">"};
    unsigned char speaceTab[] = {" "};
    unsigned char helpTab[] = {"Mark the snakegrow longer by directing it to the food."};
	PrintBmp(0, 0);
	PrintString(25, 3, menuTab0);
	PrintString(25, 4, menuTab1);
	PrintString(25, 5, menuTab2);
	PrintString(14, 3, pointTab); 
	while(1)
	{
		keyCode = KeyScan(); //获取用户按键
		switch(keyCode)
		{
			case SNAKE_UP:
			{
				if(i > 3)
				{
					PrintString(15, i, speaceTab);
					i--;
				}
				
				PrintString(15, i, pointTab);
				while(keyCode == KeyScan());
				break;
			}
			case SNAKE_DOWN:
			{
				if(i < 5)
				{
					PrintString(15, i, speaceTab);
					i++;
				}
				
				PrintString(15, i, pointTab);  
				while(keyCode == KeyScan());
				break;
			}
			case SNAKE_RIGHT:
			{
				if(i == 3)
				{
					SnakeInitial();
					SnakeGame();
					PrintBmp(0, 0);
	                PrintString(25, 3, menuTab0);
	                PrintString(25, 4, menuTab1);
	                PrintString(25, 5, menuTab2);
					PrintString(15, i,pointTab);	
				} 
				
			    if(i == 4)
				{
                    Clean(); 
                    SetAddress(10, 3);
                    PrintChar(numberTab[topMark/100]);
		            PrintChar(numberTab[topMark%100/10]);
		            PrintChar(numberTab[topMark%10]);	        	
				}
				if(i == 5)
				{
                    Clean();
                    PrintString(0, 0, helpTab);	
				}  
				while(keyCode == KeyScan());
				break;
			}
			case SNAKE_LEFT:
			{
			        Clean(); 
			        i = 3;      
			        PrintBmp(0, 0);
	                PrintString(25, 3, menuTab0);
	                PrintString(25, 4, menuTab1);
	                PrintString(25, 5, menuTab2);
	                PrintString(14, 3, pointTab); 
	                while(keyCode == KeyScan());   
			} 
			
		}
	}
}


#endif

⌨️ 快捷键说明

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