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

📄 snake.h~

📁 用Mega32+VS1003做的MP3(FAT32文件系统浏览)——源代码
💻 H~
字号:
/**************************************************************/
/*                  贪食蛇游戏  V1.0                          */ 
//参考:无名网友和波仔的代码
//波仔的源代码有误,不能使用
//正点原子@scut  08/09/11
/**************************************************************/
#ifndef _SNAKE_INCLUDED_
#define _SNAKE_INCLUDED_   
#include "lcd13164.h"   
#include "stdlib.h"   
#include "red.h"  

//范围限定
#define MAX_GAME_X 23
#define MAX_GAME_Y 15  
//最大长度
#define MAX_LENTH 13 //蛇的最大长度 理论上允许到126个点
#define MAX_LEVEL_Snake 18 //最高速度等级
//游戏结束标志
bit GAME_OVER=0;  //游戏结束标志
bit PASS=0;       //过通关的标志
bit pauseen=0;    //暂停 
uchar GAME_PLAY=0;//游戏模式    

//级别       
eeprom uchar LEVELEPM_Snake; //保存级别 
eeprom uchar LEVELEPM_Russia;
eeprom uint MAXSCORE_Snake;  //最高分记录
eeprom uint MAXSCORE_Russia;

uchar LEVEL=0;         //等级暂存器   
uint score=0;          //分数暂存器
          
void Snake_msg(void);

//记录蛇状态的结构体
struct SNAKE
{ 
	unsigned char Direction;//移动方向
#define TO_RIGHT 0x01
#define TO_LEFT  0x02
#define TO_UP    0x03
#define TO_DOWN  0x04 
#define PAUSE    0x05  
#define LEVAND   0X06
#define LEVSUB   0X07 
#define SAVELEV  0x08  
#define BACK     0X09
	unsigned int  Dot_Cnt;//蛇身长度
	unsigned char Next_X;//目标点
	unsigned char Next_Y;
} Snake_Data;//声明结构体变量  

//判断是否碰到了蛇自己的身体了
unsigned char Hit_Self(unsigned char x,unsigned char y){return ReadPixel(x,y);}//原形    

//蛇身初始化,x y 为起始坐标,length为长度
void Snake_Ini(unsigned char x,unsigned char y,unsigned char length)
{
	unsigned char i;
	unsigned int position;   
	GAME_OVER=0;//清结束标记 
	Snake_Data.Direction = TO_RIGHT;//默认方向 
	Snake_Data.Dot_Cnt=length;//蛇身长度  
	clearlcdram();//清屏            
	for(i=0;i<length;i++)Big_pinxl(x+i,y,1);//填充length 点个数据  
	while(1)//确定目标点
	{
		srand(TCNT1);
		position = rand()>>4;//产生随机数     
		if(Hit_Self(position%24,position/128))continue;//如果落在有点处则重新产生 
		Big_pinxl(position%24,position/128,1);//填充
		Snake_Data.Next_X = position%24;//设置目标点
		Snake_Data.Next_Y = position/128;
		break;
	}
	lcd_refresh();//刷新
}  
//键盘扫描
unsigned char Key_Scan()
{ 
    uchar t;
    if(READY)
    {
        t=key_process();
        switch(t)
        {
            case 184:return TO_UP;
            case 168:return TO_DOWN;
            case 234:return TO_LEFT;
            case 232:return TO_RIGHT; 
            case 248:return PAUSE;//暂停 
            case 114:return LEVAND;
            case 176:return LEVSUB;
            case 250:return SAVELEV;//保存级别
            case 56: return BACK;
        } 
    }
    return 0;
}      
         
//产生新的种子,即下一个点
//同时对蛇身的身体长度加一
uchar seedget(void)
{    
    uint position; 
    Snake_Data.Dot_Cnt+=1;//点加1 
    score+=10; 
    if(Snake_Data.Dot_Cnt>MAX_LENTH)
    {
        if(LEVEL<MAX_LEVEL_Snake)
        {
            LEVEL++;//级别增加
        }
        else PASS=1; //过通关  
        Snake_msg();    
        Snake_Ini(0,0,2); 
        delay_ms(2000); 
        READY=0;//清除按键标志 
        return 0;
    }
    Snake_msg();   
    while(1)//重新计算新目标点
    {
        srand(TCNT1);
        position = rand()>>4;
		if(Hit_Self(position%24,position/128))continue;//直到得合适的坐标 24*16以内
		Big_pinxl(position%24,position/128,1);
		Snake_Data.Next_X = position%24;
		Snake_Data.Next_Y = position/128;
		break;
    }    
    Big_pinxl(Snake_Data.Next_X,Snake_Data.Next_Y,1);//显示新的食物 
    delay_ms(100);//延时,避免死  
    return 1;
}
//蛇身数据保存曲,因为pbuffer有512个字节
//所以snake_body可以指向的数据有512-260个这么多
uchar *snake_body=pbuffer+260;//指向地址pbuffer[260]

//函数名:snake_run
//功能:蛇运行函数
//输入参数:一个全局变量flag_snake,蛇根据这个变量判断运动方向
//注意事项:蛇跑动函数,用于判断路径,食物,长大,死亡
//使用情况:内部调用
void snake_run(void)
{
	uchar tmp_head_x,tmp_head_y;
	uchar i; 
	tmp_head_x=snake_body[0];//取得蛇头X坐标
	tmp_head_y=snake_body[1];//取得蛇头Y坐标  
	switch(Snake_Data.Direction) //取蛇头方向
	{
		case TO_DOWN://向下走 y++ 
			if(tmp_head_y==0)
				GAME_OVER=1;//这个代表撞墙了,就置GAMEOVER标志,下同
			else tmp_head_y--;
			break;
		case TO_UP://向上走 y-- 
			if(tmp_head_y==MAX_GAME_Y)
				GAME_OVER=1;
			else tmp_head_y++; 
			break;
		case TO_LEFT://向左走 x-- 
			if(tmp_head_x==0)
				GAME_OVER=1;
			else tmp_head_x--;
			break;
		case TO_RIGHT://向右走 x++   
			if(tmp_head_x==MAX_GAME_X)
				GAME_OVER=1;
			else tmp_head_x++;
			break;
		default:break;
	}
	if(!GAME_OVER) //如果在之前没有撞墙,就可以进行下一步判断
	{ //以下是得到食物的判断。 
	    //蛇头和食物坐标没重叠就代表没有吃到食物
		if(Snake_Data.Next_X==tmp_head_x&&Snake_Data.Next_Y==tmp_head_y) 
		{ //得不到食物的处理  
			snake_body[2*(Snake_Data.Dot_Cnt+1)]=snake_body[2*Snake_Data.Dot_Cnt]; //保留蛇尾巴(这是增长型柔体传动)
			snake_body[2*(Snake_Data.Dot_Cnt+1)+1]=snake_body[2*Snake_Data.Dot_Cnt+1];
			for(i=Snake_Data.Dot_Cnt;i>0;i--) //柔体传动  
			{
			    snake_body[2*i]=snake_body[2*(i-1)];
			    snake_body[2*i+1]=snake_body[2*i-1];
			}
			snake_body[0]=tmp_head_x;
		    snake_body[1]=tmp_head_y;//snake_flag&=~0x02;//清食物标志
			if(!seedget())return;//得到新种子,如果换级别了,就直接返回 
		}  
		else//得到食物的处理 
 		{ 
			Big_pinxl(snake_body[2*Snake_Data.Dot_Cnt],snake_body[2*Snake_Data.Dot_Cnt+1],0);//灭蛇尾巴 
			for(i=Snake_Data.Dot_Cnt;i>0;i--) //柔体传动  
			{
			    snake_body[2*i]=snake_body[2*(i-1)];
			    snake_body[2*i+1]=snake_body[2*i-1];
			}
			snake_body[0]=tmp_head_x;
		    snake_body[1]=tmp_head_y;
		}
		Big_pinxl(tmp_head_x,tmp_head_y,1);//显示新蛇头
	}
	for(i=1;i<Snake_Data.Dot_Cnt+1;i++) //判断是否撞中自己 
	{
		if(snake_body[0]==snake_body[2*i]&&snake_body[1]==snake_body[2*i+1]) //撞中了就置GAMEOVER标志 
		{
			GAME_OVER=1;  
			break;
		}
	}
	lcd_refresh();//显示  
}    
//显示游戏时的分数和等级信息 
void Snake_msg(void)
{                 
    Show_num(1,109,LEVEL);  
    Show_num(3,103,score/100);
    Show_num(3,115,score%100); 
}
//显示游戏时的界面 
void Snake_GUI(void)
{    
    uchar i=0;     
	for(i=0;i<8;i++)
	{
	    Set_page(i);Set_column(96);//显示边界线
	    Write_data(0xff);
	}
    LCD_write_cstr(0,99,"LEVEL");
    if(pauseen)LCD_write_cstr(2,99,"PAUSE");
    else LCD_write_cstr(2,99,"SCORE");    
}                                 
//游戏结束时的界面
void Game_Over_Show(uchar gametype)
{ 
	Cleardisplay(4);//清屏
	LCD_write_cstr(0,24,"Max Score:"); //显示最高分  
    if(gametype==0)//snake game
    {    
        if(MAXSCORE_Snake<score)MAXSCORE_Snake=score;//修改最高分值
        Show_num(0,84,MAXSCORE_Snake/100);//snake game max score
        Show_num(0,96,MAXSCORE_Snake%100);  
        if(score==MAXSCORE_Snake)LCD_write_cstr(1,36,"Well Done!");//玩家创造了最高分 
	    else LCD_write_cstr(1,36,"Game Over!");  //游戏结束
	}else //russia game
    {    
        if(MAXSCORE_Russia<score)MAXSCORE_Russia=score;
        Show_num(0,84,MAXSCORE_Russia/100);//russia game max score
        Show_num(0,96,MAXSCORE_Russia%100);  
        if(score==MAXSCORE_Russia)LCD_write_cstr(1,36,"Well Done!");//玩家创造了最高分 
	    else LCD_write_cstr(1,36,"Game Over!");  //游戏结束
	}          
	delay_ms(1000);
	LCD_write_cstr(2,20,"Your Score:"); //显示玩者分数
	Show_num(2,86,score/100);
    Show_num(2,98,score%100); 
	delay_ms(3000);	
	GAME_PLAY=0;//关闭游戏模式
}                 

//进行游戏,主循环.
void Play_Snake(void)
{       
    uint lev;
    if(LEVELEPM_Snake>MAX_LEVEL_Snake)LEVELEPM_Snake=8;//初始化等级 
    else LEVEL=LEVELEPM_Snake;
    if(MAXSCORE_Snake>9999)MAXSCORE_Snake=0;//初始化分数   
    
    Snake_GUI(); 
    score=0;  //分数清空
    pauseen=0;//关闭暂停 
    GAME_PLAY=1;//游戏模式
    PASS=0;//通关标志清空
    Snake_msg(); 
	while(!GAME_OVER)
	{
		switch(Key_Scan())//根据按键方向确定移动方向 不可向相反方向移动
		{
			case TO_RIGHT :if(Snake_Data.Direction!=TO_LEFT)Snake_Data.Direction = TO_RIGHT;break;
			case TO_LEFT  :if(Snake_Data.Direction!=TO_RIGHT)Snake_Data.Direction = TO_LEFT;break;
			case TO_UP    :if(Snake_Data.Direction!=TO_DOWN)Snake_Data.Direction = TO_UP;break;
			case TO_DOWN  :if(Snake_Data.Direction!=TO_UP)Snake_Data.Direction = TO_DOWN;break;
			case PAUSE://暂停
			{
			    pauseen=!pauseen;  
			    Snake_GUI();
			    break;
			}
			case LEVSUB://水平增加
			{
			    if(LEVEL)LEVEL--;
			    else LEVEL=0;
			    Snake_msg();//更新显示 
			    break;
			}
			case LEVAND://水平减少
			{
			    if(LEVEL<MAX_LEVEL_Snake)LEVEL++;
			    else LEVEL=MAX_LEVEL_Snake; 
			    Snake_msg();//更新显示
			    break;
			}  
			case SAVELEV://保存LEVEL信息
			{               
			    Cleardisplay(4);//清屏
			    LEVELEPM_Snake=LEVEL;//保存等级信息
			    save_show();//显示保存时的界面
			    Snake_GUI();   
			    Snake_msg(); //恢复显示
			    lcd_refresh();//刷新 
			    READY=0;//清除按键标志 
			    break; 
			}
			case BACK:{GAME_PLAY=0;return ;}//无条件退出
			default:break;
		} 
		if(PASS)//过通关了!!!
		{
		    Cleardisplay(4);//清屏 
		    if(MAXSCORE_Snake<score)MAXSCORE_Snake=score;//修改最高分值
	        LCD_write_cstr(0,24,"Max Score:"); //显示最高分
	        Show_num(0,84,MAXSCORE_Snake/100);
            Show_num(0,96,MAXSCORE_Snake%100); 
            
		    LCD_write_cstr(1,18,"Well Done! Dude.");
		    delay_ms(2000);
		    LCD_write_cstr(2,5,"Congratulations!!!"); 
		    delay_ms(2000);
		    LCD_write_cstr(3,20,"Your Score:"); 
		    Show_num(3,86,score/100);
            Show_num(3,98,score%100); 
		    delay_ms(4000);
		    GAME_PLAY=0;//游戏玩结束
		    return ;
		}
		if(!pauseen)snake_run();//如果撞倒四周和自己就gameover了
		else Snake_GUI();//更新信息 
		lev=LEVEL;
		lev=(MAX_LEVEL_Snake-lev)*20+40; 
		delay_ms(lev);//级别延时控制
	}
	Game_Over_Show(0);//snake game  
} 
#endif

⌨️ 快捷键说明

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