打印
[应用方案]

光立方实现3D贪吃蛇

[复制链接]
1853|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Roderman_z|  楼主 | 2016-4-11 11:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这段代码是贪吃蛇的核心代码,一般贪吃蛇只有4个方向,这个是6个方向也就是3D的。
蛇能自己移动,用函数Snake_Move和Change_Direction实现。
我使用的是STC12C5A60S2,所以要更改的,只有以LED开头的函数
只要能实现一个点亮指定位置(x,y,z)灯的函数Led_Set_Bit
/******************************************************************************
* 文    件: Snake.c
* 作    者: ZhnJa  
* 修改日期: 2013-7-10
* 说    明: 贪吃蛇相关
******************************************************************************/  
#include "MyType.h"  
#include "LED_CMD.H"  
#include "snake.h"  
#include "STC12C5A60S2.h"  
#include <stdlib.h>  

#define WidthMax  4  //蛇最寸高度  
#define HeightMax 4  //蛇最大长度  
#define LengthMax 4  //蛇最大长度  
#define MaxLength 20 //总长度  

#define Up 6  
#define Down 5  
#define Left 4  
#define Right 3  
#define For 2  
#define Rea 1  

typedef struct _Food  //食物结构体  
{  
   uchar x;/*食物的横坐标*/  
   uchar y;/*实物的纵坐标*/  
     uchar z;/*实物的z坐标*/  
   uchar yes;/*是否出现食物的标志,0表示未产生,1表示产生*/  
}Food;/*食物*/  

typedef struct _Point //点结构体  
{  
  uchar x;  
  uchar y;  
    uchar z;  
}Point;  

typedef struct _Snake  
{  
   uchar x[MaxLength]; //蛇身节点的横坐标  
   uchar y[MaxLength]; //蛇身节点的纵坐标  
     uchar z[MaxLength]; //蛇节点  
   uchar node;/*蛇长度*/  
   uchar direction;/*蛇移动方向*/  
   uchar life;/*蛇是否存活标志,0死亡,1存活,2表示暂停*/  
}Snake;  

xdata Snake snake={{1,2,3},{1,1,1},{1,1,1},3,Up,1};  
xdata Food food={1,4,4};    //食物  
Point TailPoint;//存放蛇尾巴节点的临时变量  
Point NextPoint;//存放蛇下一次移动的位置  

/********************************************
*                           蛇初始化
*参数:
*功能:
*********************************************/  
void Init_Snake()  
{  
    unsigned char i;  
    for(i=0;i<=2;i++)  
    LED_Set_Bit(snake.x[i],snake.y[i],snake.z[i]);  
    LED_Set_Bit(food.x,food.y,food.z);  
}  
/********************************************
*                           蛇移动函数
*参数:无
*功能:删除最后一个节点,点亮下一个节点
*********************************************/  
uchar Snake_Move()  
{  
    uchar i;  
    TailPoint.x=snake.x[0]; //保存蛇尾  
    TailPoint.y=snake.y[0];  
    TailPoint.z=snake.z[0];  

  for(i=0;i<snake.node-1;i++)    //依次向尾部方向移动蛇各个节点的坐标  
  {  
        snake.x[i]=snake.x[i+1];  
        snake.y[i]=snake.y[i+1];  
        snake.z[i]=snake.z[i+1];  
    }     
    switch(snake.direction)  
    {  
        case Up:{snake.z[snake.node-1]+=1;break;}  
        case Down:{snake.z[snake.node-1]-=1;break;}  
        case Left:{snake.x[snake.node-1]-=1;break;}  
        case Right:{snake.x[snake.node-1]+=1;break;}  
        case For:{snake.y[snake.node-1]+=1;break;}  
        case Rea:{snake.y[snake.node-1]-=1;break;}  
    }  

    LED_Reset_Bit(TailPoint.x,TailPoint.y,TailPoint.z);  
    LED_Set_Bit(snake.x[snake.node-1],snake.y[snake.node-1],snake.z[snake.node-1]);  
    return 1;  
}  


沙发
Roderman_z|  楼主 | 2016-4-11 11:09 | 只看该作者
bit IsLive()  
{  
    uchar i=0;  
    //计算下一个点  
    NextPoint.x=snake.x[snake.node-1];  
    NextPoint.y=snake.y[snake.node-1];  
    NextPoint.z=snake.z[snake.node-1];  
    switch(snake.direction)  
    {  
        case Up:{NextPoint.z+=1;break;}  
        case Down:{NextPoint.z-=1;break;}  
        case Left:{NextPoint.x-=1;break;}  
        case Right:{NextPoint.x+=1;break;}  
        case For:{NextPoint.y+=1;break;}  
        case Rea:{NextPoint.y-=1;break;}  
    }  

    //判断蛇有没有撞到自身  
    for(i=0;i<=snake.node-1;i++)  
  {  
        if((snake.x[i]==NextPoint.x)&&(snake.y[i]==NextPoint.y)&&(snake.z[i]==NextPoint.z))  
        {  
           snake.life=0;  
             return 0;  
             break;  
        }  
    }  
        //判断蛇有没有撞到墙  
    if(NextPoint.x>=1&&NextPoint.x<=4  
        &&NextPoint.y>=1&&NextPoint.y<=4  
        &&NextPoint.z>=1&&NextPoint.z<=4)  
        return 1;                 
  else   
  {  
   snake.life=0;  
   return 0;  
  }  
}  

bit Change_Direction()  
{  
    uchar olddir=snake.direction;     
    if(snake.x[snake.node-1] < food.x)  
            snake.direction = Right;  
        else if(snake.x[snake.node-1] > food.x)  
                snake.direction = Left;  
        else if(snake.y[snake.node-1] <food.y)  
            snake.direction = For;  
        else if(snake.y[snake.node-1] > food.y)  
            snake.direction = Rea;  
        else if(snake.z[snake.node-1] > food.z)  
            snake.direction = Down;  
        else if(snake.z[snake.node-1] < food.z)  
            snake.direction = Up;         
        return 1;  
}  

//功能:吃食并且产生下一个实物的坐标  
//返回值:1表示吃到食物,0表示未吃到食物  
bit EatFood(void)  
{  
    uchar i;  
   if(((snake.x[snake.node-1])==food.x)&&((snake.y[snake.node-1])==food.y)&&(snake.z[snake.node-1]==food.z))    //如果吃到食物  
     {  
        for(i=snake.node;i>0;i--)  //依次向头部方向移动蛇各个节点的坐标  
        {  
          snake.x[i]=snake.x[i-1];  
          snake.y[i]=snake.y[i-1];  
            snake.z[i]=snake.z[i-1];  
        }  
        snake.x[0]=TailPoint.x;  //恢复尾巴坐标  
        snake.y[0]=TailPoint.y;  
        snake.z[0]=TailPoint.z;  

        snake.node++;    //节点个数加1  
    //以下程序段为产生食物  
        do  
        {  
          food.yes=1;//实物产生标志置1  
          GetNewFoodLoc(&food.x,&food.y,&food.z);//随机产生新的食物的坐标  
          for(i=0;i<snake.node-1;i++)  
          {  
            if((snake.x[i])==food.x&&((snake.y[i])==food.y)&&(snake.z[i]==food.z)) //判断食物出现的位置是否在蛇身上  
            {  
              food.yes=0; //食物产生标志置0  
              break;  
             }  
          }  
        }while(!food.yes);//直到产生的食物不在蛇身上为止  
        LED_Set_Bit(food.x,food.y,food.z);//产生新的食物  
        return 1;  
     }  
     return 0;  
}  

//读取定时器的随机值来获得食物坐标,同时不能越界  
void GetNewFoodLoc(uchar *x,uchar *y,uchar *z)  
{     
   *x=TH0%4+1;     
   *y=TL0%4+1;  
     *z=(TL0+TH0)%4+1;  
}  

void Change_Direction2()  
{  
    uchar olddir=snake.direction;     
    do{  
        snake.direction=rand()%6+1;  
        }  
    while(snake.direction == olddir);  
}  
//表示食物的LED灯闪烁  
void Shine_Food()  
{  
    LED_Shine(food.x,food.y,food.z);  
}  

指定位置灭LED灯Led_Reset_Bit 以及 让LED闪烁的函数LED_Shine 即可。

使用特权

评论回复
板凳
DreamofOven| | 2016-4-11 15:14 | 只看该作者
贪吃蛇、乒乓球游戏是最经典的单片机游戏设计了

使用特权

评论回复
地板
_寒寒_| | 2016-4-12 16:48 | 只看该作者
来个视频呀

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

41

主题

354

帖子

2

粉丝