贪吃蛇总结
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
百度资料:
代码:
(其中value_snake(tail,8,8)会熄灭尾灯,稍后会提及。)此处的蛇头移动方向无法被定时移动部分使用。(后来在周四解决掉了)
(3)
蛇身的显示:这里采取逐点显示的方式来显示蛇身每点。首先,据点阵工作原理,先将蛇身某点的坐标转换成字节的形式(如x=0为00000001,y=0为11111111),然后再赋给对应IO口(此处设置为P1与P2),短暂延时后再显示下一个点。具体代码如下:
void key_check()//调用了食物产生函数
{
// void rand_food();
if(up==0)
{
delay(10);
if(up==0)
{
while(!up);
delay(10);
dx=0;
dy=1;
key_flag=1;
}
}
else if(down==0)
{
delay(10);
if(down==0)
延时函数
*************************************************************************************************/
void delay(char MS)
{
char us,usn;
while(MS!=0)
{
usn = 0;
TMOD &= 0xF0;//设置定时器模式
TMOD |= 0x01;//设置定时器模式
TL0 = 0xB0;//设置定时初值
TH0 = 0x3C;//设置定时初值
TF0 = 0;//清除TF0标志
TR0 = 1;//定时器0开始计时
}
/************************************************************************************************
void value_snake(char i,unsigned char m,unsigned char n)
{
snake[i].x=m;
snake[i].y=n;
}
/************************************************************************************************
坐标转化成字节,以便显示
*************************************************************************************************/
unsigned char mux(unsigned char temp)
{
if(temp==8)return 0;
{
kflag=1;
goto loop;
}
}
}
loop:return(kflag);
}
}
/************************************************************************************************
按键检测函数
*************************************************************************************************/
{
kflag=1;
goto loop;
}
}
if(kflag!=1)//如果上面已确认蛇身重叠(即kflag被置1),则不进行第二部分检查
{
for(i=tail;i<max;i++)
{
if((snake[i].x==snake[head].x)&&(snake[i].y==snake[head].y))
代码:
蛇头移动:
定时移动:
8.19周五
解决了接触检测(食物检测部分)和蛇体增长的问题:
如何检测是否吃到食物:这里我采取了蛇头与食物坐标对比的方法,若x,y坐标完全相同,则证明蛇吃到了食物,则增长蛇体。
蛇体增长:如果吃到了食物,则在这一次检测中不熄灭尾灯,而蛇头依旧变化,蛇的长度就增加1了。
代码:
效果:
while(usn!=0)
{
us=0xff;
while (us!=0){us--;};
usn--;
}
MS--;
}
}
/************************************************************************************************
目前总程序代码如下:
#include<reg52.h>
#include<stdlib.h>
#define max 20
sbit t=P3^7;//测试行
sbit up=P3^0;
sbit down=P3^1;
sbit left=P3^2;
sbit right=P3^3;
char head,tail;
delay(100);
P1=0xff;
}
for(i=tail;i<max;i++)
{
P2=mux(snake[i].x);
P1=255-mux(snake[i].y);
delay(100);
P1=0xff;
}
}
P2=mux(food.x);
P0=255-mux(food.y);
delay(100);
*************************************************************************************************/
void display()
{
char i;
if(over)
{
P2=255;
P1=0;
}
else
{
if(head>tail)
{
for(i=0;i<=(head-tail);i++)
{
P2=mux(snake[tail+i].x);
P1=255-mux(snake[tail+i].y);
delay(100);
P1=0xff;
}
}
else
{
for(i=0;i<=head;i++)
{
P2=mux(snake[i].x);
P1=255-mux(snake[i].y);
8.15周一
上网搜集点阵贪吃蛇的参考资料并分析:
参考资料:
分析:
贪吃蛇游戏的要点:
(1)蛇身信息(用何种方式储存每个蛇身点的坐标,蛇身的移动及方向)
(2)食物的产生及位置
(3)食物与蛇身的显示
(4)接触检测(与自身是否碰撞,与墙是否碰撞,是否接触到食物等)
(5)蛇体增长
8.16周二
解决要点(1)(蛇身点部分及移动部分,方向部分后来周四时改进解决)及(3)的蛇身部分:
定时器初始化函数
*************************************************************************************************/
void TimerInit(void)//50毫秒@12.000MHz
{
EA=1;
ET0=1;
总效果如图:
(仍未实现定向移动与食物产生)
8.17周三
解决要点(2):此处使用rand()函数作为食物坐标的种子,经过与蛇身各点的对比,排除掉与蛇身重叠的点后,产生食物的坐标,并用一个结构体来保存。
ቤተ መጻሕፍቲ ባይዱ代码:
效果:
8.18周四
解决蛇头移动方向和定向移动问题
蛇头移动方向:一开始我采取的方案是直接在按键检测函数中使旧蛇头的x,y坐标加减一个数然后赋给新蛇头以完成向一个方向的移动,但这样的话,定向移动的时候没办法找到方向。所以我定义了全局变量char dx,dy;作为移动方向。例如,当dx=1时,snake[head].x+dx即为向右移动。这样以来,在定时中断也可以引用dx,dy作为方向了。
{
for(i=tail;i<(head-tail);i++)
{
if((snake[i].x==snake[head].x)&&(snake[i].y==snake[head].y))
{
kflag=1;
goto loop;
}
}
}
else
{
for(i=0;i<head;i++)
{
if((snake[i].x==snake[head].x)&&(snake[i].y==snake[head].y))
{
while(!down);
定义蛇身结构体
*************************************************************************************************/
typedef struct
{
char x;
char y;
} snakebody ;
snakebody snake[max];
(1)
蛇身信息:定义一个结构体数组,用来储存蛇身坐标。
代码:
蛇体移动:(此处应用队列数据结构的思想,附图为百度资料)
另声明一个char head;一个char tail;,则该数组snake[head]则代表蛇头,snake[tail]代表蛇尾,蛇体的移动方式是:点亮下一个点,并使其成为新的蛇头(head++),然后熄灭蛇尾,且使现时最后的点成为新的蛇尾(tail++)。(当head或tail超过数组元素最大值时,其值清0,以此构成队列数据结构。)
/************************************************************************************************
定义食物结构体
*************************************************************************************************/
else if(temp==7)return 128;
else if(temp==6)return 64;
else if(temp==5)return 32;
else if(temp==4)return 16;
else if(temp==3)return 8;
else if(temp==2)return 4;
自身碰撞函数
*************************************************************************************************/
bit knock()
{
char i;
bit kflag;
kflag=0;
if(head>tail)
else if(temp==1)return 2;
else if(temp==0)return 1;
}
/************************************************************************************************
点阵显示
P0=0xff;
}
}
/************************************************************************************************
蛇身赋值函数
*************************************************************************************************/
typedef struct
{
char x;
char y;
} snakefood;
snakefood food;
/************************************************************************************************
直至周日,这个贪吃蛇的小游戏已经算是实现了基本的功能,但仍有比较多的bug:
(1)食物有时出现在蛇身里
(2)无法检测是否撞墙
(3)开始时还没移动的时候按键会导致游戏直接结束
这两天我在调试程序,打算把这些bug清除后补充另外一些功能:
(1)计分,并用LCD显示
(2)在达到一定程度后加速
(3)游戏结束后用LCD显示总分
char dx=1,dy=0;
bit key_flag=0;
bit food_flag=1;
bit over=0;
//char a=0;
/************************************************************************************************
代码:
(其中value_snake(tail,8,8)会熄灭尾灯,稍后会提及。)此处的蛇头移动方向无法被定时移动部分使用。(后来在周四解决掉了)
(3)
蛇身的显示:这里采取逐点显示的方式来显示蛇身每点。首先,据点阵工作原理,先将蛇身某点的坐标转换成字节的形式(如x=0为00000001,y=0为11111111),然后再赋给对应IO口(此处设置为P1与P2),短暂延时后再显示下一个点。具体代码如下:
void key_check()//调用了食物产生函数
{
// void rand_food();
if(up==0)
{
delay(10);
if(up==0)
{
while(!up);
delay(10);
dx=0;
dy=1;
key_flag=1;
}
}
else if(down==0)
{
delay(10);
if(down==0)
延时函数
*************************************************************************************************/
void delay(char MS)
{
char us,usn;
while(MS!=0)
{
usn = 0;
TMOD &= 0xF0;//设置定时器模式
TMOD |= 0x01;//设置定时器模式
TL0 = 0xB0;//设置定时初值
TH0 = 0x3C;//设置定时初值
TF0 = 0;//清除TF0标志
TR0 = 1;//定时器0开始计时
}
/************************************************************************************************
void value_snake(char i,unsigned char m,unsigned char n)
{
snake[i].x=m;
snake[i].y=n;
}
/************************************************************************************************
坐标转化成字节,以便显示
*************************************************************************************************/
unsigned char mux(unsigned char temp)
{
if(temp==8)return 0;
{
kflag=1;
goto loop;
}
}
}
loop:return(kflag);
}
}
/************************************************************************************************
按键检测函数
*************************************************************************************************/
{
kflag=1;
goto loop;
}
}
if(kflag!=1)//如果上面已确认蛇身重叠(即kflag被置1),则不进行第二部分检查
{
for(i=tail;i<max;i++)
{
if((snake[i].x==snake[head].x)&&(snake[i].y==snake[head].y))
代码:
蛇头移动:
定时移动:
8.19周五
解决了接触检测(食物检测部分)和蛇体增长的问题:
如何检测是否吃到食物:这里我采取了蛇头与食物坐标对比的方法,若x,y坐标完全相同,则证明蛇吃到了食物,则增长蛇体。
蛇体增长:如果吃到了食物,则在这一次检测中不熄灭尾灯,而蛇头依旧变化,蛇的长度就增加1了。
代码:
效果:
while(usn!=0)
{
us=0xff;
while (us!=0){us--;};
usn--;
}
MS--;
}
}
/************************************************************************************************
目前总程序代码如下:
#include<reg52.h>
#include<stdlib.h>
#define max 20
sbit t=P3^7;//测试行
sbit up=P3^0;
sbit down=P3^1;
sbit left=P3^2;
sbit right=P3^3;
char head,tail;
delay(100);
P1=0xff;
}
for(i=tail;i<max;i++)
{
P2=mux(snake[i].x);
P1=255-mux(snake[i].y);
delay(100);
P1=0xff;
}
}
P2=mux(food.x);
P0=255-mux(food.y);
delay(100);
*************************************************************************************************/
void display()
{
char i;
if(over)
{
P2=255;
P1=0;
}
else
{
if(head>tail)
{
for(i=0;i<=(head-tail);i++)
{
P2=mux(snake[tail+i].x);
P1=255-mux(snake[tail+i].y);
delay(100);
P1=0xff;
}
}
else
{
for(i=0;i<=head;i++)
{
P2=mux(snake[i].x);
P1=255-mux(snake[i].y);
8.15周一
上网搜集点阵贪吃蛇的参考资料并分析:
参考资料:
分析:
贪吃蛇游戏的要点:
(1)蛇身信息(用何种方式储存每个蛇身点的坐标,蛇身的移动及方向)
(2)食物的产生及位置
(3)食物与蛇身的显示
(4)接触检测(与自身是否碰撞,与墙是否碰撞,是否接触到食物等)
(5)蛇体增长
8.16周二
解决要点(1)(蛇身点部分及移动部分,方向部分后来周四时改进解决)及(3)的蛇身部分:
定时器初始化函数
*************************************************************************************************/
void TimerInit(void)//50毫秒@12.000MHz
{
EA=1;
ET0=1;
总效果如图:
(仍未实现定向移动与食物产生)
8.17周三
解决要点(2):此处使用rand()函数作为食物坐标的种子,经过与蛇身各点的对比,排除掉与蛇身重叠的点后,产生食物的坐标,并用一个结构体来保存。
ቤተ መጻሕፍቲ ባይዱ代码:
效果:
8.18周四
解决蛇头移动方向和定向移动问题
蛇头移动方向:一开始我采取的方案是直接在按键检测函数中使旧蛇头的x,y坐标加减一个数然后赋给新蛇头以完成向一个方向的移动,但这样的话,定向移动的时候没办法找到方向。所以我定义了全局变量char dx,dy;作为移动方向。例如,当dx=1时,snake[head].x+dx即为向右移动。这样以来,在定时中断也可以引用dx,dy作为方向了。
{
for(i=tail;i<(head-tail);i++)
{
if((snake[i].x==snake[head].x)&&(snake[i].y==snake[head].y))
{
kflag=1;
goto loop;
}
}
}
else
{
for(i=0;i<head;i++)
{
if((snake[i].x==snake[head].x)&&(snake[i].y==snake[head].y))
{
while(!down);
定义蛇身结构体
*************************************************************************************************/
typedef struct
{
char x;
char y;
} snakebody ;
snakebody snake[max];
(1)
蛇身信息:定义一个结构体数组,用来储存蛇身坐标。
代码:
蛇体移动:(此处应用队列数据结构的思想,附图为百度资料)
另声明一个char head;一个char tail;,则该数组snake[head]则代表蛇头,snake[tail]代表蛇尾,蛇体的移动方式是:点亮下一个点,并使其成为新的蛇头(head++),然后熄灭蛇尾,且使现时最后的点成为新的蛇尾(tail++)。(当head或tail超过数组元素最大值时,其值清0,以此构成队列数据结构。)
/************************************************************************************************
定义食物结构体
*************************************************************************************************/
else if(temp==7)return 128;
else if(temp==6)return 64;
else if(temp==5)return 32;
else if(temp==4)return 16;
else if(temp==3)return 8;
else if(temp==2)return 4;
自身碰撞函数
*************************************************************************************************/
bit knock()
{
char i;
bit kflag;
kflag=0;
if(head>tail)
else if(temp==1)return 2;
else if(temp==0)return 1;
}
/************************************************************************************************
点阵显示
P0=0xff;
}
}
/************************************************************************************************
蛇身赋值函数
*************************************************************************************************/
typedef struct
{
char x;
char y;
} snakefood;
snakefood food;
/************************************************************************************************
直至周日,这个贪吃蛇的小游戏已经算是实现了基本的功能,但仍有比较多的bug:
(1)食物有时出现在蛇身里
(2)无法检测是否撞墙
(3)开始时还没移动的时候按键会导致游戏直接结束
这两天我在调试程序,打算把这些bug清除后补充另外一些功能:
(1)计分,并用LCD显示
(2)在达到一定程度后加速
(3)游戏结束后用LCD显示总分
char dx=1,dy=0;
bit key_flag=0;
bit food_flag=1;
bit over=0;
//char a=0;
/************************************************************************************************