找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2619|回复: 2
打印 上一主题 下一主题
收起左侧

51单片机2.0寸tft彩屏贪吃蛇有开关机动画详解注释及红外遥控

[复制链接]
跳转到指定楼层
楼主
ID:471699 发表于 2019-3-21 18:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
部分代码:
#include<reg52.h>
#include "lcd_driver.h"
#include "gui.h"
#include "touch.h"

typedef unsigned int u16;          //对数据类型进行声明定义
typedef unsigned char u8;


u8 snake_long = 5;//蛇开始长度
u8 snake_x[20] = {14,11,8,5,2};//蛇的开始位置                                                                                                                 
u8 snake_y[20] = {2,2,2,2,2};
u8 food_x[100] = {10,10,15,16,27,34,21,23,15,17,11,13,20,16,16,30,42,36,45,67,41,35,27};
u8 food_y[100] = {24,26,5,17,4,20,4,4,6,22,4,6,7,2,1,31,15,45,18,32,44,63,12,46};

u8 score = 0;

sbit beep=P1^4;
sbit IRIN=P3^2;



u8 IrValue[6];
u8 Time;
u8 t;
u8 ki;


void oppencarton();//开机动画
void overcarton();//游戏结束
void delay(u16 i);//延时子程序
void Snake_go();//把蛇前点的位置赋给蛇的后点
void Snake_turn();//蛇转弯指令
void dead(); //显示死后的得分和结束动画
void eating();//蛇头与食物是否重合判断
void DisDigplay();//显示
void gameover();//死亡判断
void IrInit();//红外初始化
void select();//判断显示的得分



void delay(u16 i)
{
        while(i--);       
}


void IrInit()
{
        IT0=1;//下降沿触发
        EX0=1;//打开中断0允许
        EA=1;        //打开总中断
        IRIN=1;//初始化端口
}
void oppencarton()
{
                u16 i=0;
           for(i;i<5;i++)
           {
                GUI_Write32CnChar(1,1,"欢",RED,BLUE);
                GUI_Write32CnChar(145,1,"迎",RED,BLUE);
                GUI_Write32CnChar(1,75,"来",RED,BLUE);
                GUI_Write32CnChar(145,75,"到",RED,BLUE);
                GUI_Write32CnChar(75,120,"贪",RED,BLUE);
                GUI_Write32CnChar(1,190,"吃",RED,BLUE);
                GUI_Write32CnChar(145,190,"蛇",RED,BLUE);
                }

}
void overcarton()
{       
                u16 i=0;
                   for(i;i<5;i++)
                {
                GUI_Write32CnChar(1,1,"结",RED,BLUE);
                GUI_Write32CnChar(115,1,"结",RED,BLUE);
                   GUI_Write32CnChar(1,190,"结",RED,BLUE);
                   GUI_Write32CnChar(115,190,"结",RED,BLUE);
                GUI_Write32CnChar(33,1,"束",RED,BLUE);
                GUI_Write32CnChar(148,1,"束",RED,BLUE);
                  GUI_Write32CnChar(33,190,"束",RED,BLUE);
                GUI_Write32CnChar(148,190,"束",RED,BLUE);
                TFT_ClearScreen(BLACK);
                }
}

void Snake_go()        //把后一个点的坐标覆盖在前一个坐标上或指令的方向
{
    u8 i;
        for(i = 1; i < snake_long;i++)
        {
            snake_x[snake_long - i] = snake_x[snake_long - i - 1];
                snake_y[snake_long - i] = snake_y[snake_long - i - 1];
          
        }
             
}

/*蛇转弯*/
void Snake_turn()
{       

     switch(IrValue[2])
         {       
          case 0x45: //进入游戏默向右走--开机键
                      Snake_go();
                        if(snake_x[0] == 70)//        snake_x[0]为蛇头
                        snake_x[0] = 0;
                        else
                            snake_x[0] = snake_x[0]+3;//蛇向右走由1-》2 x轴向右移
                            DisDigplay();//显示蛇和食物
                        break;
           case 0x18: //向上走--2
                      Snake_go();
                                  
                                  if(snake_y[0] == 0)
                                     snake_y[0] = 70;
                          else
                                     snake_y[0] = snake_y[0]-3;
                             DisDigplay();//显示蛇和食物
                                  break;
          case 0x52: //向下走--8
                      Snake_go();
                                 
                                  if(snake_y[0] == 70)
                                     snake_y[0] = 0;
                          else
                                     snake_y[0] = snake_y[0]+3;
                              DisDigplay();//显示蛇和食物
                                  break;
          case 0x08: //向左走--4
                      Snake_go();
                         
                                  if(snake_x[0] == 0)
                                     snake_x[0] = 70;
                          else
                                     snake_x[0] = snake_x[0]-3;
                              DisDigplay();//显示蛇和食物
                                  break;
          case 0x5a: //向右走--6   
                      Snake_go();
                                  if(snake_x[0] == 70)
                                     snake_x[0] = 0;
                          else
                                     snake_x[0] = snake_x[0]+3;
                             DisDigplay();//显示蛇和食物
                                  break;
         default:break;
         }
}

/*发生碰撞*/
void dead()
{
                   u8 i;
                i=1;
                for(i;i<snake_long;i++)
                     if(((snake_x[0] == snake_x[i])||(snake_x[0] == snake_x[i]+1)||(snake_x[0] == snake_x[i]-1))&&((snake_y[0] == snake_y[i])||(snake_y[0] == snake_y[i]+1)||(snake_y[0] == snake_y[i]-1)))
                  {
             gameover();
                }
}


void feel()         //触屏暂停
{       
             uchar temp=0;
                if(TOUCH_XPT_ReadXY() == 1)
                {
                 while(1)
                 {
                  if(temp==0)
                  TFT_ClearScreen(CYAN);
                  temp=1;
                  if(TOUCH_XPT_ReadXY() == 1)
                  {
                  temp=0;
                  TFT_ClearScreen(BLACK);
                  break;
                  }
                 }
                }
       
}



void gameover()
{                 
               
                select();
                select();
                select();
                TFT_ClearScreen(CYAN);
                overcarton();
                ki++;
         

}

/*吃豆豆*/
void eating()
{
   if(((snake_x[0] == food_x[snake_long - 2])||(snake_x[0] == food_x[snake_long - 2]-1)||(snake_x[0] == food_x[snake_long - 2]+1)) && ((snake_y[0] == food_y[snake_long - 2])||(snake_y[0] == food_y[snake_long - 2]+1)||(snake_y[0] == food_y[snake_long - 2]-1)))
   {
                     snake_long++;
                 delay(10);
                beep = ~beep;
                  score++;
       
   }

}
void select()
{
        if(score == 0)
        GUI_WriteASCII(120, 170, "0", CYAN, BLACK);
        else if(score == 1)
        GUI_WriteASCII(120, 170, "1", CYAN, BLACK);
        else if(score == 2)
        GUI_WriteASCII(120, 170, "2", CYAN, BLACK);
        else  if(score == 3)
        GUI_WriteASCII(120, 170, "3", CYAN, BLACK);
        else if(score == 4)
        GUI_WriteASCII(120, 170, "4", CYAN, BLACK);
        else if(score == 5)
        GUI_WriteASCII(120, 170, "5", CYAN, BLACK);
        else if(score == 6)
        GUI_WriteASCII(120, 170, "6", CYAN, BLACK);
        else if(score == 7)
        GUI_WriteASCII(120, 170, "7", CYAN, BLACK);
}






void DisDigplay()//显示蛇和食物
{
   u8 i;

   for(i = 0;i < snake_long;i++)
   {

         GUI_Dot(snake_x[i],snake_y[i],RED);//蛇点
          
         GUI_Dot(food_x[snake_long - 2],food_y[snake_long - 2],BLUE);//食物点
         
         GUI_Write32CnChar(50, 170, "得分", CYAN, BLACK);
               
         select();
        }
        GUI_Dot(snake_x[snake_long-1],snake_y[snake_long-1],BLACK);       
}
                                                                



void main()
{
        TFT_Init();
        IrInit();
        TFT_ClearScreen(BLACK);
        oppencarton();
        TFT_ClearScreen(BLACK);
        while(1)
        {       
                   Snake_turn();
                eating();
                dead();
                feel();
                               
        }
}

void ReadIr() interrupt 0
{
        u8 j,k;
        u16 err;
        Time=0;                                         
        delay(700);        //7ms
        if(IRIN==0)                //确认是否真的接收到正确的信号
        {         
               
                err=1000;                                //1000*10us=10ms,超过说明接收到错误的信号
                /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
                侯,程序死在这里*/       
                while((IRIN==0)&&(err>0))        //等待前面9ms的低电平过去                 
                {                       
                        delay(1);
                        err--;
                }
                if(IRIN==1)                        //如果正确等到9ms低电平
                {
                        err=500;
                        while((IRIN==1)&&(err>0))                 //等待4.5ms的起始高电平过去
                        {
                                delay(1);
                                err--;
                        }
                        for(k=0;k<4;k++)                //共有4组数据
                        {                               
                                for(j=0;j<8;j++)        //接收一组数据
                                {

                                        err=60;               
                                        while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
                                        {
                                                delay(1);
                                                err--;
                                        }
                                        err=500;
                                        while((IRIN==1)&&(err>0))         //计算高电平的时间长度。
                                        {
                                                delay(10);         //0.1ms
                                                Time++;
                                                err--;
                                                if(Time>30)
                                                {
                                                        return;
                                                }
                                        }
                                        IrValue[k]>>=1;         //k表示第几组数据
                                        if(Time>=8)                        //如果高电平出现大于565us,那么是1
                                        {
                                                IrValue[k]|=0x80;
                                        }
                                        Time=0;                //用完时间要重新赋值                                                       
                                }
                        }
                }
                if(IrValue[2]!=~IrValue[3])
                {
                        return;
                }
        }                       
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2019-3-21 20:49 | 只看该作者
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

板凳
ID:470508 发表于 2019-4-7 21:55 | 只看该作者
你这个数组定义的够大,
思路很好,但是代码是有问题的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表