51单片机实现贪食蛇的子程序

发布者:HarmoniousPeace最新更新时间:2015-06-25 来源: 51hei关键字:51单片机  贪食蛇 手机看文章 扫描二维码
随时随地手机看文章

这是从http://www.51hei.com/bbs/dpj-20623-1.html 这个制作里面截取的一段子程序,调用函数请下载里面的附件.

下面是mysanke.h文件:

#ifndef _MYSNAKE_H_
#define _MYSNAKE_H_

/*---------------------------------------------------------
函数功能:检测随机落食是否压在已存在的亮点上
调用形式:Check_Food(*node);
参数:结构体指针
返回值:返回食物是否可以放置1->可以 0->不可以
备注:食物产生函数调用此函数用于检测
---------------------------------------------------------*/
bit Check_Food(node *r)
{
 if(GetStatusXY((*r).X,(*r).Y)) 
 (*r).S=0;//不可以放置
 
 else (*r).S=1;//S=1表示可以点亮
 return (*r).S;//返回状态
}

/*---------------------------------------------------------
函数功能:产生随机食物
调用形式:Creat_Food();
参数:无
返回值:无
备注:此函数未刷屏仅设置状态
---------------------------------------------------------*/
void Creat_Food(void)
{
 while(!Check_Food(&food))//
 {
 food.X=TL0&0x1f; //X的范围0->31
 food.Y=seed&0x0f; //Y的范围0->15
 }
 //Check_Food(&food);检测食物可以放置后执行下面
 SetStatusXY(food.X,food.Y,food.S);//食物点亮起
 

         //此函数未刷屏,仅设置状态
}

/*---------------------------------------------------------
函数功能:产生初始化的蛇并设置其运动状态
调用形式:Snake_Init();
参数:无
返回值:无
备注:无刷新屏幕,只在缓存写入数据
---------------------------------------------------------*/
void Snake_Init(void)
{
ClearBuf(); //清屏

snake[0].X=3;  //蛇头
snake[0].Y=1;
snake[0].S=1;

snake[1].X=2;
snake[1].Y=1;
snake[1].S=1;

snake[2].X=1;  //此时蛇尾
snake[2].Y=1;
snake[2].S=1;

SetStatusXY(snake[0].X,snake[0].Y,snake[0].S);
SetStatusXY(snake[1].X,snake[1].Y,snake[1].S);
SetStatusXY(snake[2].X,snake[2].Y,snake[2].S);

//while(!food.S)
//Creat_Food();
food.X=19;food.Y=13;food.S=1;
SetStatusXY(food.X,food.Y,food.S);
snake_status=1;
snake_size=2;
snake_score=0;
snake_speed=60;
snake_direct=RIGHT;//首先向右走。
}

/*---------------------------------------------------------
函数功能:蛇的单步移动刷新
调用形式:
参数:入口参数->移动方向(direct)
返回值:无
备注:仅更新显示缓存
---------------------------------------------------------*/
void Snake_Step(uint8 dir)
{
int8 dx,dy;   //-128->127.蛇头的位移量
uint8 i;//循环计数器变量
 switch(dir)
 {
 case UP: dx=0;dy=-1;break;
 case DOWN:dx=0;dy=1;break;
 case LEFT:dx=-1;dy=0;break;
 case RIGHT:dx=1;dy=0;break;
 default:return ;
 }

SetStatusXY(snake[snake_size].X,snake[snake_size].Y,0);//蛇尾消隐 
 
for(i=snake_size;i>0;i--) //0是蛇尾,到1为止
{       //蛇身的坐标跟随前一位
snake[i].X=snake[i-1].X;
snake[i].Y=snake[i-1].Y;
snake[i].S=snake[i-1].S;
}

snake[0].X+=dx;//蛇头坐标更新,具有方向性
snake[0].Y+=dy;

//更新*超过显示范围处理(蛇可穿过边界)
if(snake[0].X>31) snake[0].X=0;//横坐标越界处理
if(snake[0].X<0) snake[0].X=31;

if(snake[0].Y>15) snake[0].Y=0;//纵坐标越界处理
if(snake[0].Y<0) snake[0].Y=15;

for(i=0;i<=snake_size;i++)
{
SetStatusXY(snake[i].X,snake[i].Y,1);
}
}

/*---------------------------------------------------------
函数功能:游戏按键处理
调用形式:Snake_Key();
参数:
返回值:
备注:轮询
---------------------------------------------------------*/
void Snake_Key(void)
{
P2|=0XF8;
 if(!KEY_UP||ir_value==0x18)
 {
  //蛇游戏方向键无需去抖。避免影响刷新
   if(snake_direct==UP||snake_direct==DOWN)
   ;
   else
   {
   snake_direct=UP;
   //Snake_Step(UP);
   }
 }
  else
  {
   if(!KEY_DOWN||ir_value==0x52)
   {
   if(snake_direct==DOWN||snake_direct==UP)
   ;
   else
   {
   //Snake_Step(DOWN);
   snake_direct=DOWN;
   }
   }
   
    else
    {
     if(!KEY_LEFT||ir_value==0x08)
     {
      if(snake_direct==LEFT||snake_direct==RIGHT)
      ;
      else
      snake_direct=LEFT;
     }
      
     else
     {
      if(!KEY_RIGHT||ir_value==0x5a)
      {
       if(snake_direct==LEFT||snake_direct==RIGHT)
       ;
       else 
       snake_direct=RIGHT;
      }
      else 
      {
       if(!KEY_ENTER||ir_value==0x43)
       {
       DelayMs(SCAN_DELAY);
        if(!KEY_ENTER||ir_value==0x43)
        {
        while(!KEY_ENTER)
        ;
        snake_status=0;//游戏结束了
        matrix.S=FIRST;
        }
       }
       else if(ir_value==0x46)
        {
        food.X=0;
        TR0=0;
        DelayMs(10);
        TR0=1;
        }
      }
     }
    }
  }
 
}[page]

/*---------------------------------------------------------
函数功能:蛇吃到食物处理
调用形式:Snake_Feed();
参数:
返回值:迟到食物返回1 没吃到返回0->判断是否死亡
备注:
---------------------------------------------------------*/
void Snake_Feed(void)
{
uint8 i;
 if(snake[snake_size].X==food.X&&snake[snake_size].Y==food.Y)
 {
 //while(food.S==0)
 Creat_Food();//重新产生食物
 //snake_foodflag=1;
 snake_size++;//蛇身加1
 snake_score+=BASIC_SCORE;//游戏得分加上加分基数
 snake_speed-=BASIC_SPEED;//游戏速度加上加速基数
  if(snake_speed<=0)
  snake_speed=1;
 
 
   if(snake_size==SNAKE_SIZE)//此刻蛇长等于最长时候,通关条件
   {
    for(i=0;i<=SNAKE_SIZE;i++)
    {
    SetStatusXY(snake[i].X,snake[i].Y,0);//蛇消隐
    }
    //清屏幕缓存并显示得分
    ClearBuf();
    {
    Display_5x8(0,0,S_);
    Display_5x8(6,0,C_);
    Display_5x8(12,0,O_);
    Display_5x8(18,0,R_);
    Display_5x8(24,0,E_);
    }
    //下32x8像素显示分数(最长52节,吃50个食物通关,50*10=500分最高)
    {
    Display_5x8(31-6,8,snake_score%10);
    Display_5x8(31-12,8,snake_score%100/10);
    Display_5x8(31-18,8,snake_score/100);
    }
    while(1)
    {
     for(i=0;i<5;i++)
     Display();
     DelayMs(255);
     if(snake_status==0)
     break;
    }
   }
 //return 1;
 }
 //else return 0;
}

/*---------------------------------------------------------
函数功能:处理蛇的死亡
调用形式:Snake_Die();
参数:
返回值:
备注:
---------------------------------------------------------*/
void Snake_Die(void)
{
uint16 i;

 for(i=1;i  {
 if(snake[0].X==snake[i].X)
 {
  if(snake[i].Y==snake[0].Y) //死亡
  {
  ClearBuf();
   Display_5x8(0,0,G_); 
   Display_5x8(6,0,A_);
   Display_5x8(12,0,M_);
   Display_5x8(18,0,E_);
   Display_5x8(0,8,O_);
   Display_5x8(6,8,V_);
   Display_5x8(12,8,E_);
   Display_5x8(18,8,R_);
   for(i=0;i<800;i++)
   Display();
   
  ClearBuf();
  Display_5x8(31-6,8,snake_score%10);
  Display_5x8(31-12,8,snake_score%100/10);
  Display_5x8(31-18,8,snake_score/100);
  Display_5x8(0,0,S_);
  Display_5x8(6,0,C_);
  Display_5x8(12,0,O_);
  Display_5x8(18,0,R_);
  Display_5x8(24,0,E_); 
    while(1)
    {
     if(!snake_status)
     break;
     for(i=0;i<100;i++)
     Display();
     DelayMs(255);
    }
  break;  //连跳
  }
 }
 }
}

/*---------------------------------------------------------
函数功能:游戏进行时
调用形式:Snake_Ing();
参数:
返回值:
备注:
---------------------------------------------------------*/
void Snake_Ing(void)
{
uint8 i;
if(!snake_status)
Snake_Init();
 Snake_Step(snake_direct);
 Snake_Feed();
 Snake_Die();
 for(i=0;i  Display();
}

#endif

关键字:51单片机  贪食蛇 引用地址:51单片机实现贪食蛇的子程序

上一篇:51单片机驱动16*16点阵程序带原理图
下一篇:基于stc51单片机的光立方c语言源代码

推荐阅读最新更新时间:2024-03-16 14:05

51单片机与计算机通讯,51单片机与PC通信方法总结
51单片机的串口,是个全双工的串口,发送数据的同时,还可以接收数据。 当串行发送完毕后,将在标志位 TI 置 1,同样,当收到了数据后,也会在 RI 置 1。 无论 RI 或 TI 出现了 1,只要串口中断处于开放状态,单片机都会进入串口中断处理程序。 在中断程序中,要区分出来究竟是发送引起的中断,还是接收引起的中断,然后分别进行处理。 常用的方法有: 接收数据时,使用“中断方式”,清除 RI 后,用一个变量通知主函数,收到新数据。 发送数据时,也用“中断方式”,清除 TI 后,用另一个变量通知主函数,数据发送完毕。 这样一来,收、发两者基本一致,编写程序也很规范、易懂。 更重要的是,主函数中,不用在那儿死等发
[单片机]
51单片机(二十一)—— 定时器计数功能
在本文,我们对51单片机定时器的计数功能进行测试,采用定时器0通过方式2产生10KHz的方波,并通过单片机的P1.0口输出。定时器1采用方式1的计数功能,即对外部输入的脉冲进行计数。T1与P3.5引脚复用。实验时,需要用杜邦线将单片机的P1.0引脚,与P3.5引脚连接在一起。T0输出的脉冲又通过P3.5引脚输入给定时器1的计数器。定时器1对脉冲进行计数,设置为5000个脉冲溢出一次。脉冲的周期为0.1ms,即定时器1的溢出周期为500ms,所以LED1以1秒一次的频率闪烁。 定时器0和定时器1的初始化代码如下所示 void init_T0_T1(void) { TMOD= 0x52; //定时器0使用方式2,8位自
[单片机]
项目实战:51单片机控制交通信号灯
51单片机控制交通信号灯 说明:最近接了一个小项目,要在一个十字路口用单片机实现交通信号灯的控制 我试着用仿真软件做了一下,效果还可以,希望和大家一起学习 总体设计仿真图 单片机仿真设计部分 公路信号灯显示仿真部分 四个方向仿真设计部分 启动仿真后开始计时 C语言参考源代码: /***************************************************** 十字路口交通灯控制 C 程序 ******************************************************/ #define uchar unsigned char #define uint uns
[单片机]
项目实战:<font color='red'>51单片机</font>控制交通信号灯
51单片机红外接收解码程序
接收以S52单片机作为接收系统。以S52的P3.3口作为接收端口,该端口是外部中断1。 这个接受程序是以 XC866作为红外发送控制系统 ,接收程序如下: #include reg52.h //头文件 #include intrins.h #define uchar unsigned char //宏定义 #define uint unsigned int sbit HWRx=P3^3; //位声明 code uchar Table = //共阴数码管 0-9 a-f - 表 {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5
[单片机]
51单片机----sbit
sbit: 定义特殊功能寄存器的位变量。 ​典型应用:sbit P0_0=P0^0;//即定义P0_0为P0口的第1位,以便进行位操作。 用法:​ ​在C语言里,如果直接写P1.0,C编译器并不能识别,而且P1.0也不是一个合法的C语言变量名,所以得给它另起一个名字,这里起的名为P1_0,可是P1_0是不是就是P1.0呢?你这么认为,C编译器可不这么认为,所以必须给它们建立联系,这里使用了Keil C的关键字sbit来定义,sbit的用法有三种: 第一种方法:sbit 位变量名=地址值 第二种方法:sbit 位变量名=SFR名称^变量位地址值 第三种方法:sbit 位变量名=SFR地址值^变量位地址值 如定义PSW中的O
[单片机]
51单片机按键控制蜂鸣器启停程序
51单片机按键控制蜂鸣器启停程序 #include reg52.h #define uint unsigned int //宏定义 sbit SPK=P3^5; //定义喇叭端口 sbit key=P3^1; //开发板上对应的是s18按键 void delay(uint z) { uint x,y; for(x=z;x 0;x--) for(y=110;y 0;y--); } void main() { while(1) { if(key==0) { delay(100); SPK=0; delay(100); SPK=1; } else { SPK=1; } } }
[单片机]
51单片机-支持连按与全局变量
1.支持连按的思路 支持连按的代码就是在“不支持连按”代码的思路上把“if(KEY4==1)”改为“if(KEY4==0)”,这样的话按键不松手程序就能一直进入“if(KEY4==0)”的大括号里面。然后我们定义一个变量times,如果一直按着不放,times就一直累加,累加到1000,意味着低电平已经持续了一定的时间,我们就可以执行功能代码了,如图所示 2.全局变量 全局变量就是先在所有函数前定义,这种变量可以在所有函数中使用,例如这个变量的值发生改变成为另一个值时,假设是12,其他函数此时运用这个变量的值就是12。关于全局变量的利弊请参考《手把手教你学51单片机》文档7.1.2节。 所以这次我们把数码管显示的内容
[单片机]
<font color='red'>51单片机</font>-支持连按与全局变量
一种简单的基于51单片机的电子密码锁设计
  1 单片机电子密码锁的背景和设计特点   在高科技迅速发展的今天,人们已经发明了密码锁、电子锁和激光锁等多种形式。这些锁在传统钥匙的基础上,利用磁场、声波和光束等多种方式来控制锁的开启和关闭,从而有效地增强了锁的安全性,保护了人们的生命财产和安全,有效地防止盗贼的光顾。   单片机又称为单片微电脑或者单片微型计算机,它有效的集合了中央处理器、只读存储器、随机存取存储器和输入输出端口等计算机功能部件。计算机体积庞大,不易携带,导致单片机的应运而生,电子密码锁就是在单片机的外部接上简单的电路,人为的写入程序来完成其核心部分,这样不仅能够缩小锁的体积还能够降低成本,保持精度,并且能够有效的升级和改善电子密码锁。   2 单片机
[单片机]
一种简单的基于<font color='red'>51单片机</font>的电子密码锁设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved