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

📄 lcd_test2.c

📁 液晶1602的测试程序!很好用。1602可以显示英文
💻 C
字号:
/**************************************************************/
/*                  贪食蛇游戏  V1.0                          */
/*          硬件m64 + 128*64图形液晶(ks0108)8M RC           */
/*  环境:AVRSstudio4.12 SP4 + WINAVR20060421 -00优化         */
/*  作者:Bozai(章其波)                                       */
/*  日期: 2006-12-30                                          */
/**************************************************************/

#include<avr/io.h>
#include<avr/pgmspace.h>
#include"LCD/LCD.H"
#include<stdlib.h>
//按键
#define KEY_RIGHT  PF1
#define KEY_LEFT   PF0
#define KEY_UP     PF2
#define KEY_DOWN   PF3

//全局速度
#define SPEED 20000

//记录蛇状态的结构体
struct SNAKE
{
	unsigned char Head_X;//蛇头的坐标
	unsigned char Head_Y;
	unsigned char Tail_X;//蛇尾的坐标
	unsigned char Tail_Y;
	unsigned char Direction;//移动方向
#define TO_RIGHT 0x01
#define TO_LEFT  0x02
#define TO_UP    0x03
#define TO_DOWN  0x04
	unsigned char Level;//游戏级别
#define L0 0x00
#define L1 0x01
#define L2 0x02
#define L3 0x03
#define L4 0x04
#define L5 0x05
#define L6 0x06
#define L7 0x07
	unsigned int  Dot_Cnt;//蛇身长度
	unsigned char Next_X;//目标点
	unsigned char Next_Y;
} Snake_Data;//声明结构体变量

unsigned char Hit_Self(unsigned char x,unsigned char y);//原形

//定时器1初始化
void Timer1_Initial()
{
 TCNT1H=0x00;
 TCNT1L=0x00;
 TCCR1A=0x03;//ctc mode  use icr1
 TCCR1B=0x01;//system clock;
 ICR1H=0xff;
 ICR1L=0xff;
}

/*********** 以四个像素作为一个点 *************/
//总共尺寸 为 64 * 32
// x范围0~63 y范围0~31 val为填充值 1或0
void OneDot(unsigned char x,unsigned char y,unsigned char val)
{
	OnePixel(x<<1,y<<1,val);
	OnePixel(x<<1,(y<<1)+1,val);
	OnePixel((x<<1)+1,y<<1,val);
	OnePixel((x<<1)+1,(y<<1)+1,val);
}

//蛇身初始化,x y 为起始坐标,length为长度,level为游戏级别
void Snake_Ini(unsigned char x,unsigned char y,unsigned char length,unsigned char level)
{
	unsigned char i;
	unsigned int position;
	Snake_Data.Head_X = x + length - 1;//蛇头
	Snake_Data.Head_Y = y;
	Snake_Data.Tail_X = x;//蛇尾
	Snake_Data.Tail_Y = y;
	Snake_Data.Direction = TO_RIGHT;//默认方向
	Snake_Data.Level = level;//游戏级别
	Snake_Data.Dot_Cnt = length;//蛇身长度
	ClearDisBuf(0x00);//清屏
	for(i = 0;i<length;i++)OneDot(x+i,y,1);//填充
	while(1)//确定目标点
	{
		srand(TCNT1);
		position = rand()>>4;//产生随机数
		if(Hit_Self(position%64,position/64))continue;//如果落在有点处则重新产生
		OneDot(position%64,position/64,1);//填充
		Snake_Data.Next_X = position%64;//设置目标点
		Snake_Data.Next_Y = position/64;
		break;
	}
	UpdateDis();//刷新
}

//检测是否碰到自己
unsigned char Hit_Self(unsigned char x,unsigned char y)
{
	return ReadPixel(x<<1,y<<1);
}

//键盘初始化
void Key_Ini()
{
	DDRF |= 0x00;
	PORTF |= 0xff;
}

//键盘扫描
unsigned char Key_Scan(unsigned int n)
{
	unsigned char i = 0;
	while(n--)
	{
		if((PINF & (1<<KEY_RIGHT))==0)i = TO_RIGHT;
		else if((PINF & (1<<KEY_LEFT))==0)i = TO_LEFT;
		else if((PINF & (1<<KEY_UP))==0)i = TO_UP;
		else if((PINF & (1<<KEY_DOWN))==0)i = TO_DOWN;
	}
	return i;
}

//移动蛇身
unsigned char Move()
{
	unsigned int position;
	unsigned char x,y;

	//判断是否撞到四周的墙 //gameover
	if(Snake_Data.Direction == TO_RIGHT && Snake_Data.Head_X == 63)return 1;
	else if(Snake_Data.Direction == TO_LEFT && Snake_Data.Head_X == 0)return 1;
	else if(Snake_Data.Direction == TO_UP && Snake_Data.Head_Y == 0)return 1;
	else if(Snake_Data.Direction == TO_DOWN && Snake_Data.Head_Y == 31)return 1;

	//根据方向置x y的值
	x = Snake_Data.Head_X;
	y = Snake_Data.Head_Y;
	if(Snake_Data.Direction == TO_RIGHT)x++;
	else if(Snake_Data.Direction == TO_LEFT)x--;
	else if(Snake_Data.Direction == TO_UP)y--;
	else if(Snake_Data.Direction == TO_DOWN)y++;


	//如果碰到目标点,即吃子
	if(x == Snake_Data.Next_X && y == Snake_Data.Next_Y)
	{
		//OneDot(x,y,1);
		Snake_Data.Dot_Cnt += 1;//点加1
		Snake_Data.Head_X = x;//置新头
		Snake_Data.Head_Y = y;

		while(1)//重新计算新目标点
		{
			srand(TCNT1);
			position = rand()>>4;
			if(Hit_Self(position%64,position/64))continue;
			OneDot(position%64,position/64,1);
			Snake_Data.Next_X = position%64;
			Snake_Data.Next_Y = position/64;
			break;
		}
		UpdateDis();//刷新
		return 0;//正常返回0
	}
	//如果碰到自己
	else if(Hit_Self(x,y))return 1;//gameover
	//正常移动
	else
	{
		OneDot(x,y,1);//向前移动
		Snake_Data.Head_X = x;//置新首
		Snake_Data.Head_Y = y;
		OneDot(Snake_Data.Tail_X,Snake_Data.Tail_Y,0);//清最后一点
		UpdateDis();//刷新

		//一下程序判断蛇尾应是哪一点 原尾四周的四点之一
		//需要判断当目标点也在原蛇尾的四周的情况
		if(Snake_Data.Tail_X == 0 )
		{
			if(Snake_Data.Tail_Y == 0)
			{
				if(Hit_Self(Snake_Data.Tail_X + 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X + 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y))Snake_Data.Tail_X += 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y + 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y + 1)==Snake_Data.Next_Y))Snake_Data.Tail_Y += 1;
			}
			else if(Snake_Data.Tail_Y == 31)
			{
				if(Hit_Self(Snake_Data.Tail_X + 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X + 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y))Snake_Data.Tail_X += 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y - 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y - 1)==Snake_Data.Next_Y))Snake_Data.Tail_Y -= 1;
			}
			else
			{
				if(Hit_Self(Snake_Data.Tail_X + 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X + 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y))Snake_Data.Tail_X += 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y + 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y + 1)==Snake_Data.Next_Y))Snake_Data.Tail_Y += 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y - 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y + 1)==Snake_Data.Next_Y))Snake_Data.Tail_Y -= 1;
			}
		}
		else if(Snake_Data.Tail_X == 63)
		{
			if(Snake_Data.Tail_Y == 0)
			{
				if(Hit_Self(Snake_Data.Tail_X - 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X - 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y)) Snake_Data.Tail_X -= 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y + 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y + 1)==Snake_Data.Next_Y))Snake_Data.Tail_Y += 1;
			}
			else if(Snake_Data.Tail_Y == 31)
			{
				if(Hit_Self(Snake_Data.Tail_X - 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X - 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y))Snake_Data.Tail_X -= 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y - 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y - 1)==Snake_Data.Next_Y)) Snake_Data.Tail_Y -= 1;
	
			}
			else
			{
				if(Hit_Self(Snake_Data.Tail_X - 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X - 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y)) Snake_Data.Tail_X -= 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y + 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y + 1)==Snake_Data.Next_Y)) Snake_Data.Tail_Y += 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y - 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y - 1)==Snake_Data.Next_Y)) Snake_Data.Tail_Y -= 1;
			}

		}
		else
		{
			if(Snake_Data.Tail_Y == 0)
			{
				if(Hit_Self(Snake_Data.Tail_X + 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X + 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y)) Snake_Data.Tail_X += 1;
				else if(Hit_Self(Snake_Data.Tail_X - 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X - 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y)) Snake_Data.Tail_X -= 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y + 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y + 1)==Snake_Data.Next_Y)) Snake_Data.Tail_Y += 1;
			}
			else if(Snake_Data.Tail_Y == 31)
			{
				if(Hit_Self(Snake_Data.Tail_X + 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X + 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y)) Snake_Data.Tail_X += 1;
				else if(Hit_Self(Snake_Data.Tail_X - 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X - 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y)) Snake_Data.Tail_X -= 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y - 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y - 1)==Snake_Data.Next_Y)) Snake_Data.Tail_Y -= 1;
	
			}
			else
			{
				if(Hit_Self(Snake_Data.Tail_X + 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X + 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y)) Snake_Data.Tail_X += 1;
				else if(Hit_Self(Snake_Data.Tail_X - 1 ,Snake_Data.Tail_Y) && !((Snake_Data.Tail_X - 1)==Snake_Data.Next_X && (Snake_Data.Tail_Y)==Snake_Data.Next_Y)) Snake_Data.Tail_X -= 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y + 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y + 1)==Snake_Data.Next_Y)) Snake_Data.Tail_Y += 1;
				else if(Hit_Self(Snake_Data.Tail_X,Snake_Data.Tail_Y - 1) && !((Snake_Data.Tail_X)==Snake_Data.Next_X && (Snake_Data.Tail_Y - 1)==Snake_Data.Next_Y)) Snake_Data.Tail_Y -= 1;
			}
		}
	}
	return 0;//正常返回0
}

//进行游戏
void Play_Game()
{
	unsigned int cnt;
	switch(Snake_Data.Level)//根据游戏级别设置延时
	{
		case L0: cnt = SPEED/(L0+1);break;
		case L1: cnt = SPEED/(L1+1);break;
		case L2: cnt = SPEED/(L2+1);break;
		case L3: cnt = SPEED/(L3+1);break;
		case L4: cnt = SPEED/(L4+1);break;
		case L5: cnt = SPEED/(L5+1);break;
		case L6: cnt = SPEED/(L6+1);break;
		case L7: cnt = SPEED/(L7+1);break;
		default: cnt = SPEED/(L0+1);break;
	}
	while(1)
	{
		switch(Key_Scan(cnt))//根据按键方向确定移动方向 不可向相反方向移动
		{
			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;
			default:break;
		}
		if(Move())return;//如果撞倒四周和自己就gameover了
	}	
}

int main()
{
	Timer1_Initial();//定时器1初始化
	Key_Ini();//初始化按键
	InitialLcd();//液晶屏初始化
	while(1)
	{
		Snake_Ini(5,5,8,0);//游戏初始化 尾在(5,5)处 长度8 级别0
		Play_Game();//开始游戏
	}
}

⌨️ 快捷键说明

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