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

📄 main.c

📁 用C编写的贪吃蛇程序
💻 C
📖 第 1 页 / 共 2 页
字号:
*功能: 显示12*12汉字字符串
*参数: x 列地址(0-7), y行地址(0-3),pcBuff要显示的汉字串
*返回: 无
************************************************************************/
void LCD_PutHanziString(uint8_t x, uint8_t y, uint8_t *pcBuff)
{
    while(*pcBuff)
    {
        LCD_PutHanzi(x, y, pcBuff);
        pcBuff += 2;
        x += 1;
    }
}
/*************************************************************************
*名称: LCD_DrawBmp
*功能: LCD显示位图
*参数: pcBuff位图数据
*返回: 无		                           								
*************************************************************************/
void LCD_DrawBmp(uint8_t *pcBuff)
{
    uint16_t i;
    LCD_WriteByte(0x80, 0);
	LCD_WriteByte(0x40, 0);
	LCD_WriteByte(0x80, 0);				
    for (i = 0; i < 504; i++)
    {
        LCD_WriteByte(pgm_read_byte(pcBuff++), 1);
    }    
}
void LCD_RefreshRam(uint8_t *pcBuff)
{
    uint16_t i;
    LCD_WriteByte(0x80, 0);
	LCD_WriteByte(0x40, 0);
	LCD_WriteByte(0x80, 0);				
    for (i = 0; i < 504; i++)
    {
        LCD_WriteByte(*pcBuff++, 1);
    }    
}
void LCD_DrawBox(uint8_t x, uint8_t y)
{
	uint8_t Temp = 0x0F;
	uint8_t cOffset;
	cOffset = y * 4 % 8;
	x = x * 4;
	y = y * 4 / 8;
	Temp <<= cOffset;
	cDisplayRam[y][x] |= Temp;
	cDisplayRam[y][x + 1] |= Temp;
	cDisplayRam[y][x + 2] |= Temp;
	cDisplayRam[y][x + 3] |= Temp;
	LCD_RefreshRam(cDisplayRam);
}
void LCD_ClearBox(uint8_t x, uint8_t y)
{
	uint8_t Temp = 0x0F;
	uint8_t cOffset;
	cOffset = y * 4 % 8;
	x = x * 4;
	y = y * 4 / 8;
	Temp <<= cOffset;
	cDisplayRam[y][x] &= ~Temp;
	cDisplayRam[y][x + 1] &= ~Temp;
	cDisplayRam[y][x + 2] &= ~Temp;
	cDisplayRam[y][x + 3] &= ~Temp;
	LCD_RefreshRam(cDisplayRam);
}
uint8_t Key_Scan(void)
{
	if(!KEY_UP)
	{
		Delay_MS(10);
		if(!KEY_UP)
		{
			return SNAKE_UP;
		}
	}
	else if(!KEY_DOWN)
	{
		Delay_MS(10);
		if(!KEY_DOWN)
		{
			return SNAKE_DOWN;
		}
	}
	else if(!KEY_LEFT)
	{
		Delay_MS(10);
		if(!KEY_LEFT)
		{
			return SNAKE_LEFT;
		}
	}
	else if(!KEY_RIGHT)
	{
		Delay_MS(10);
		if(!KEY_RIGHT)
		{
			return SNAKE_RIGHT;
		}
	}
	else 
	{
		return 255;
	}	
}

uint16_t Snake_Rand(uint16_t dRange)
{
	srand(TCNT0);
	return (rand() % dRange) ;
} 
void Snake_PutFood(void)
{
	uint8_t x;
	uint8_t y;
	do
	{
		x = Snake_Rand(GAME_FIELD_WIDTH);
		y = Snake_Rand(GAME_FIELD_HEIGHT);
	}while( cGameField[y][x] != SNAKE_GROUND);
	cGameField[y][x] = SNAKE_FOOD;
	LCD_DrawBox(x, y);
}
void Snake_Init(void)
{
	uint8_t i;
	uint8_t j;
	for(i = 0; i < GAME_FIELD_HEIGHT; i ++) //打扫游戏场地
	{
		for(j = 0; j < GAME_FIELD_WIDTH; j ++)
		{
			cGameField[i][j] = SNAKE_GROUND;
		}
	}
/*	for(i = 0; i < 6; i ++) //清空显示缓存
	{
		for(j = 0; j < 84; j ++)
		{
			cDisplayRam[i][j] = 0;
		}
	}*/
	memset(cDisplayRam,0, 504);
	//cDisplayRam[6][84] = 0; //清空显示缓存
	SnakeHead.x = 11;//设置蛇头位置
	SnakeHead.y = 3; 
	
	SnakeTail.x = 8;//设置蛇尾位置
	SnakeTail.y = 3;
 	
	LCD_DrawBox(11, 3); //画出蛇头
	//cGameField[3][11] = SNAKE_RIGHT; //移动方向右
	cSnakeHeadDir = SNAKE_RIGHT;
	LCD_DrawBox(10, 3); //画蛇身
	cGameField[3][10] = SNAKE_RIGHT; //移动方向右
	
	LCD_DrawBox(9, 3); //画蛇身
	cGameField[3][9] = SNAKE_RIGHT; //移动方向右
	
	LCD_DrawBox(8, 3); //画蛇尾
	cGameField[3][8] = SNAKE_RIGHT; //移动方向右
	Snake_PutFood();
}

void Snake_Game(void)
{
	uint8_t x = 0;
	uint8_t y = 0;
	
	while(1)
	{
		cKeyCode = Key_Scan(); //获取用户按键
		if(cKeyCode != 255)
		{	
			if(cKeyCode != ((cSnakeHeadDir - 1 + 2) % 4) + 1) 
												//如果不是后退
			{
				cSnakeHeadDir = cKeyCode;
			}
		}
		if(cSnakeMoveFlag == 1)
		{
			cli();
			cSnakeMoveFlag = 0;
			//x = SnakeHead.x; //获取当前蛇头位置
			//y = SnakeHead.y;	
			if(cGameField[y][x] != SNAKE_FOOD) //如果没有吃到食物
			{
				x = SnakeTail.x; //获取当前蛇尾位置
				y = SnakeTail.y;
				switch(cGameField[y][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][SnakeTail.x] = SNAKE_GROUND;
				LCD_ClearBox(SnakeTail.x , SnakeTail.y); //清除尾巴
				SnakeTail.x = x; //重新定位蛇尾
				SnakeTail.y = y;
			}
			else //吃到食物
			{
				Snake_PutFood();
				cFoodCnt++;
				if(cFoodCnt >= 284) //满分
				{
					LCD_PutString(15, 2, "You are Cool!");
					LCD_PutString(20, 4, "Mark: ");
					LCD_PutChar(50, 4, cFoodCnt / 100 + 0x30);
					LCD_PutChar(55, 4, cFoodCnt % 100 / 10 + 0x30);
					LCD_PutChar(60, 4, cFoodCnt % 10 + 0x30);
				}
			}
			x = SnakeHead.x; //获取当前蛇头位置
			y = SnakeHead.y;			
			switch(cSnakeHeadDir) //判断蛇头的移动方向
			{
				case SNAKE_UP:
				{	
					//LCD_DrawBox(x, y);
					cGameField[y][x] = SNAKE_UP;
					if(y == 0)
					{	
						y = GAME_FIELD_HEIGHT;
					}
					y--;
					//cGameField[y][x] = SNAKE_UP;
					//cSnakeHeadDir = SNAKE_UP;
					break;
				}
				case SNAKE_DOWN:
				{	
					//LCD_DrawBox(x, y);
					cGameField[y][x] = SNAKE_DOWN;
					y++;
					if(y == GAME_FIELD_HEIGHT) 
					{
						y = 0; 
					}
					//cSnakeHeadDir = SNAKE_DOWN;
					//cGameField[y][x] = SNAKE_DOWN;
					break;		
				}
				case SNAKE_LEFT:
				{
					//LCD_DrawBox(x, y);
					cGameField[y][x] = SNAKE_LEFT;
					if(x == 0)
					{	
						x = GAME_FIELD_WIDTH;
					}
					x--;
					//cSnakeHeadDir = SNAKE_LEFT;
					
					break;
				}			
				case SNAKE_RIGHT:
				{
					//LCD_DrawBox(x, y);
					cGameField[y][x] = SNAKE_RIGHT;
					x++;
					if(x == GAME_FIELD_WIDTH)
					{
						x = 0;
					}
					//cSnakeHeadDir = SNAKE_RIGHT;
					
					break;
				}
				default:
				{
					break;
				}
			}
			LCD_DrawBox(x, y);
			SnakeHead.x = x; //重新定位蛇头
			SnakeHead.y = y;  
			if(cGameField[y][x] != SNAKE_GROUND && cGameField[y][x] 
								!= SNAKE_FOOD)
			{
				LCD_PutString(20, 2, "Game Over");
				LCD_PutString(20, 4, "Mark: ");
				LCD_PutChar(50, 4, cFoodCnt / 100 + 0x30);
				LCD_PutChar(55, 4, cFoodCnt % 100 / 10 + 0x30);
				LCD_PutChar(60, 4, cFoodCnt % 10 + 0x30);
				Delay_MS(5000);
				sei();                                     
				return;
			}			
			TCNT0 = 256 - 78;
			sei();
		}

	}	
}
void Snake_Option(void)
{
	uint8_t i = 3;
	//LCD_PutString(20, 0,"S N A K E");
	//LCD_PutString(20, 1,"<<=======");
	LCD_DrawBmp(cBmpCode);
	LCD_PutString(25, 3,"New Game");
	LCD_PutString(25, 4,"Top Mark");
	LCD_PutString(25, 5,"  Help  ");
	LCD_PutString(15, i,"} ");
	while(1)
	{
		cKeyCode = Key_Scan(); //获取用户按键
		switch(cKeyCode)
		{
			case SNAKE_UP:
			{
				if(i > 3)
				{
					LCD_PutString(15, i,"  ");
					i--;
				}
				
				LCD_PutString(15, i,"} ");
				while(cKeyCode == Key_Scan());
				break;
			}
			case SNAKE_DOWN:
			{
				if(i < 5)
				{
					LCD_PutString(15, i,"  ");
					i++;
				}
				
				LCD_PutString(15, i,"} ");
				while(cKeyCode == Key_Scan());
				break;
			}
			case SNAKE_RIGHT:
			{
				if(i == 3)
				{
					Snake_Init();
					Snake_Game();
					LCD_DrawBmp(cBmpCode);
					LCD_PutString(25, 3,"New Game");
					LCD_PutString(25, 4,"Top Mark");
					LCD_PutString(25, 5,"  Help  ");
					LCD_PutString(15, i,"} ");
					
				}
			}
		}
	}
}
void Timer0_Init(void)
{
	TCNT0 = 256 - 78;
	TCCR0 |= (1 << CS02) | (1 << CS00); //1024分频
	TIMSK |= (1 << TOIE0);
	
}
ISR(TIMER0_OVF_vect)
{
	TCNT0 = 256 - 78;
	cTimerCnt++;
	if(cTimerCnt >= 20)
	{
		cSnakeMoveFlag = 1;
		cTimerCnt = 0;
	}
}
int main(void)
{	
	uint8_t i;
    Port_Init();
    SPI_MasterInit();
	Timer0_Init();
    LCD_Init();

	sei();
	Snake_Option();
    while(1)
    {
	/*	LCD_DrawBmp(cBmpCode);
		Delay_MS(2000);
		LCD_Clear();
		LCD_PutString(15, 0,"LCD");
		LCD_PutHanziString(1, 1, "液晶驱动");
		LCD_PutString(20, 4,"worm chen");
		LCD_PutString(25, 5,"2008.11");
		Delay_MS(2000);*/
		//LCD_Clear();
		//Snake_Init();
		//Snake_Game();
    }
}

⌨️ 快捷键说明

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