原创 第二十九课 点阵之五 玩贪吃蛇

2009-6-5 11:09 5280 10 14 分类: MCU/ 嵌入式

第二十九课 点阵之五 玩贪吃蛇


程序讲解
/*--------------------------------------------------------------*/
//LED8*8显示


/*--------------------------------------------------------------*/
//按键配置
//              上S7


// 左S10  中S11   右S12


//              下S15



#include <reg52.h>
#include "74HC595.H"
#include "Beep.H"
#include "Key_Board.H"


 


/*--------------------------------------------------------------*/
//全局变量定义
#define len 30                       //最大长度
unsigned char disram[8];       //显示缓冲区
unsigned char x[len],y[len];   //蛇身坐标
char dx, dy;                          //点坐标
unsigned char speed;            //移动速度
unsigned char level;              //关数
unsigned char life;                 //生命值



volatile void key_pro(void);


/*--------------------------------------------------------------*/
//定时器初始化
void T0_init(void)
{
    TMOD |= 0x01;                //定时器0工作在方式1(16位)
    TH0  = 0xf8;  //2ms
    TL0  = 0x36;
    IE  |= 0x82;                    //开总中断和定时器0中断
    PT0 = 1;                         //定时器0 中断优先级最高
    TR0  = 1;                        //允许定时器0工作
}



/*--------------------------------------------------------------*/
//定时器初始化
void T1_init(void)                   
{
    TMOD |= 0x10;              //定时器1工作在方式2(8位自动装载)
    TH1  = 0x00;                 //65ms
    TL1  = 0x00;
    IE  |= 0x88;                   //开总中断和定时器1中断
    TR1  = 1;                      //允许定时器1工作
}



/*-------------- ------------------------------------------------*/
//清除显示缓冲区,即清屏
void clr_ram(void)
{
 unsigned char i;
 for(i = 0; i < 8; i++)
 disram = 0x00;
}


/*--------------------------------------------------------------*/
//画点函数,擦点或者绘点(将点的坐标(dx、dy)转换的数据缓冲区)
//点阵左上角坐标为(0, 0) 右下角坐标为(7, 7)
//横坐标为x:0~7  纵坐标为y:0~7
//k = 1 --绘点    k = 0 --擦点 
void point1(unsigned char x, unsigned char y, bit k)
{
 if(k) disram[x] |= 0x01 << y;  
 else  disram[x] &= ~(0x01 << y);
}


 


/*--------------------------------------------------------------*/
//定时器中断服务 用来显示点阵
void T0_intservice(void) interrupt 1
{
    static unsigned char n;
    TR1 = 0;                          //关闭定时器1
    TH0  = 0xf8;                    //2ms
    TL0  = 0x36;


    Ser_IN(0x01 << n);         //列选
    Ser_IN(~disram[n]);        //行数据
    Par_OUT();                    //输出
    n++; if(n == 8) n = 0;      //循环扫描
    TR1 = 1;                         //开定时器1
}



/*--------------------------------------------------------------*/
//定时器中断服务 用来按键扫描和产生食物的随机坐标
void T1_intservice(void) interrupt 3
{
    TH1  = 0x00;
    TL1  = 0x00;
    key_pro();                    //按键扫描
}



/*--------------------------------------------------------------*/
//延时100000+0us 函数定义
void delay(void)
{
    unsigned char i,j,k;
    for(i=7;i>0;i--)
    for(j=74;j>0;j--)
    for(k=95;k>0;k--);
}



/*--------------------------------------------------------------*/
//按键扫描 及处理
volatile void key_pro(void)
{
 key_scan();
 if(key == 6)                   //上
 {
  dx = 0; dy = -1;


 }
 if(key == 14)                 //下
 {
  dx = 0; dy = 1;


 }
 if(key == 9)                  //左
 {
  dy = 0; dx = -1;
 
 }
 if(key == 11)                //右
 {
  dy = 0; dx = 1;


 }
  
}



/*--------------------------------------------------------------*/
//定点显示,一次只显示一个点 
void gotoxy(unsigned char x, unsigned char y)
{
 Ser_IN(0x01 << x);          //列选        
 Ser_IN(~(0x01 << y));     //行数据
 Par_OUT();                      //上升沿输出
 delay();
 speaker();                        //声音
}



/*--------------------------------------------------------------*/
//通关演示
void congrate(void)
{
 char i, j;
 TR0 = 0;
 TR1 = 0;


 for(j = 0; j < 5; j++)
 {
  for(i = j ; i < 8-j; i++)gotoxy(j, i);               //此时j 对应x,i 对应y,x不变 y增大,即垂直下移
  for(i = j+1 ; i < 8-j; i++)gotoxy(i, 7-j);       //此时i 对应x,7- j 对应y,x增大 y 不变,即水平右移
  for(i = j+1 ; i < 8-j; i++)gotoxy(7-j, 7-i);    //此时7- j 对应x,7- i 对应y,x不变y减小 ,即垂直上移
  for(i = j+1 ; i < 7-j; i++)gotoxy(7-i, j);       //此时7- i 对应x,j 对应y,x减小 y不变,即水平左移
 }


 for(j = 4; j >= 0; j--)
 {
  for(i = 6-j ; i >= j+1; i--)gotoxy(7-i, j);      //此时7- i 对应x,j 对应y,x减小 y不变,即水平左移
  for(i = 7-j ; i >= j+1; i--)gotoxy(7-j, 7-i);   //此时 7- j 对应x,7- i 对应y,x不变y减小 ,即垂直上移
  for(i = 7-j ; i >= j+1; i--)gotoxy(i, 7-j);      //此时 i 对应x,7- j 对应y,x增大 y 不变,即水平右移
  for(i = 7-j ; i >= j; i--)gotoxy(j, i);             //此时 j 对应x,i 对应y,x不变 y增大,即垂直下移 
 }
}



/*--------------------------------------------------------------*/
//主函数
void main (void)

 unsigned char i;                        //通用循环变量
 unsigned char num;                  //蛇的长度
 bit food, over;                          //食物和结束标志位
 unsigned char foodx, foody;     //食物坐标
 
 life = 3;                                 //设定生命次数
 speed = 8;                            //设定初始速度
 num = 2;                               //设定初始蛇身长度
 T0_init();                               //定时器初始化
 T1_init();
 clr_ram();                              //清显示缓冲区
 x[0] = 1;                               //初始化位置
 y[0] = 2;
 dx = 1;                                 //向右运动
 while(1)
 {
  x[0] += dx; y[0] += dy;
  x[0] &= 0x07; y[0] &= 0x07;  //穿墙
 
  if(!food)                                  //放置食物
  {
again:  foodx = TL1&0x07;     //随机
    foody = TH1&0x07;
    for(i = 0; i < num; i++)
   {
    if(foodx == x && foody == y)  //如果显示食物的坐标和蛇身重叠
    goto again;                                     //则重新获取食物
   }
   point1(foodx, foody, 1);                   //显示食物
   food = 1;                                         //置食物标志位
  }


  if(x[0] == foodx && y[0] == foody) //吃到食物 
  {
   speaker();                                       //声音指示
   num++;    
   food = 0;                                        //清食物标志位
  }


  for(i = 0; i < num; i++)                    //显示蛇身
  point1(x, y, 1);
  point1(x, y, 0);                          //清蛇尾


  for(i = 1; i < num; i++)                    //判断是否自撞
  {
   if((x[0] == x) && (y[0] == y)) //蛇头坐标和蛇身某点坐标相同则自撞
   over = 1;                                        //置结束标志位
  }


  for(i = 0; i < speed; i++) delay();   //蛇运动速度
  
  for(i = 0; i < num; i++)                  //蛇移动蛇身
  {
   x[num-i] = x[num-i-1];                 //前一点的坐标给后一点
   y[num-i] = y[num-i-1];
  }
  
  if(num > 10 + level)                    //过关
  {
   if(num > 28)                             //通关!!!
   {
    while(1){congrate();inverse = ~inverse;}
   }
   delay(); speaker();                   //声音指示


   if(speed > 1) speed--;             //速度加一
   num = 2;                                 //重定蛇长
   level += 1;                              //总的蛇长增加1
   clr_ram();                               //清除屏幕
   goto again;                             //新的一关开始
  }


  if(over)                                   //判断是否结束
  {
   clr_ram();                              //清除屏幕
   num = 2;                               //重新设定蛇长
   point1(foodx, foody, 1);        //重新放置食物
   x[0] = 1; y[0] = 2;                 //起点位置
   dx = 1;                                  //向右运动
   over = 0;                              //清结束标志位
   life--;                                    //生命值减1
  } 
  if(!life) congrate();                   //生命用完
 }
}


本节重点:


1、前面知识的综合应用,关键在于理解


演示视频:


http://v.youku.com/v_show/id_XOTIzNjU3NDg=.html


相关程序:https://static.assets-stash.eet-china.com/album/old-resources/2009/6/5/44739cf9-2cc5-4ee8-9385-0e99e3fa7878.rar

PARTNER CONTENT

文章评论4条评论)

登录后参与讨论

用户206768 2009-6-9 07:27

多谢分享 ~

用户209148 2009-6-6 12:23

谢谢分享!

用户518079 2009-6-5 20:36

好!

tengjingshu_112148725 2009-6-5 14:30

谢谢了
相关推荐阅读
用户222124 2010-12-08 22:18
台达PLC监控
台达PLC监控网上有很多例子,自己也照着弄了个,挺方便的,分享下串口数据格式:COM1,9600,8,N,1  ...
用户222124 2010-06-27 16:36
基于NIOS II和FPGA无线小车控制系统的设计
   主控制台以Cyclone II系列的EP2C8Q208C8为核心,通过nRF24L01进行无线通讯,来控制以ATmega8为微处理器的两轮小车,可以实现小车按控制平台发送的控制信息来准确运动。所...
用户222124 2009-11-13 15:58
51开发板已经销售完了,谢谢大家的支持!
51开发板已经销售完了,谢谢大家的支持!...
用户222124 2009-09-28 16:13
51开发板十一大放送!!!赶快行动吧!!!
  51开发板十一大放送!  赶快行动吧!!!   开发板硬件介绍: http://group.ednchina.com/2031/24972.aspx  开发板实物图片总汇: http://grou...
用户222124 2009-09-13 19:02
nios II 实验五 数码管显示数字钟(定时器实现 外部中断调节)
#include "system.h"                      //包含基本的硬件描述信息#include "altera_avalon_timer_regs.h"    //定义内...
用户222124 2009-09-13 18:57
nios II 实验四 PIO外部中断
#include "system.h"                      //包含基本的硬件描述信息#include "altera_avalon_timer_regs.h"    //定义内...
我要评论
4
10
关闭 站长推荐上一条 /3 下一条