用点阵玩贪吃蛇,适合新手入门算法经典的编程实例

近日,21ic论坛oufuqiang做了一个用点阵玩贪吃蛇,而这个例子非常适合新手入门算法,下面开始分享源码与原理图。不强调性能的源码就是耍流氓了,结果如下:

RAM:86.2

code:697

性能:38.4fps/Mhz@8051

源码167行的贪吃蛇

源码如下:

文字版:

#include

sbit DIN = P3^4;

sbit RCK = P3^5;

sbit SCK = P3^6; //74hc595接口

sbit k1 = P3^1;

sbit k2 = P3^0;

sbit k3 = P3^2;

sbit k4 = P3^3; //四个独立按键

unsigned char dpdat[8]=; //显存

unsigned char she[65]; //蛇体数组,由于点阵大小为8x8,所以一个字节表示蛇的一个节点,高四位和低四位分别表示xy坐标

unsigned char fangxiang; //蛇头移动方向

bit shiwushanshuo; //食物闪烁控制位

#define shang 0

#define xia 1

#define zuo 2

#define you 3

#define k1_anxia k1==0

#define k2_anxia k2==0

#define k3_anxia k3==0

#define k4_anxia k4==0 //一些替换,省得写着写着自己逻辑乱掉

void yidongshe(unsigned char fangxiang); //移动蛇函数

void xianshishe(); //显示蛇函数

void chulishe(); //处理蛇函数

void send595(unsigned char dat) //向595发送一个字节数据

{

unsigned char i=8;

do

{

DIN=dat&0x80;

SCK=1;

SCK=0;

dat

}while(--i);

RCK=1;

RCK=0;

}

void yanshi(unsigned int time) //一个简单的延时

{

while(--time);

}

void shechushihua() //蛇初始化,蛇长两个节点,0xff表示蛇尾,最后一个字节是食物坐标,初始向左移动

{

she[0]=0x33;she[1]=0x34;she[2]=0xff;she[64]=0x22;fangxiang=zuo;

}

void main()

{

unsigned int fps;

SCK=0;

RCK=0;

TMOD=0X01;

EA=1;

ET0=1;

TR0=1;

shechushihua();

while(1)

{

xianshishe(); //显示蛇

// yanshi(60000); //延时一下

yidongshe(fangxiang); //移动蛇

chulishe(); //处理蛇

fps++;

}

}

void t0() interrupt 1

{

code unsigned char hsm[]=; //行扫数据

static unsigned char cnt; //扫描变量

static unsigned int clk5hz; //5hz时钟用变量

TH0=(65536-2500)/256;

TL0=(65536-2500)%256; //2.5ms中断周期

P0=0XFF;

send595(hsm[cnt]); //发送行扫数据

P0=~dpdat[cnt]; //送出显存数据,由于点阵是0点亮,所以数据取反后送P0

cnt++; //移向下一行

cnt=cnt&0x07; //控制变量不超过0-7

if(k1_anxia && fangxiang!=xia)

if(k2_anxia && fangxiang!=shang)

if(k3_anxia && fangxiang!=you)

if(k4_anxia && fangxiang!=zuo) //按键控制蛇头方向

clk5hz++;if(clk5hz>=40)//以5hz闪烁食物

}

void yidongshe(unsigned char fangxiang) //移动蛇

{

unsigned char i;

for(i=63;i>0;i--) //从蛇尾向蛇头遍历蛇体数据

{

if(she[i]!=0xff) //不是蛇尾

{

she[i]=she[i-1]; //后一节点复制前一节点坐标

}

else

{

continue; //是0xff表示是蛇尾数据,继续向前

}

}

if(fangxiang==shang) //向上移动.点阵左上角坐标为0,0,右下角坐标为7,7

{

she[0]=she[0]-0x10; //高四位减1

}

if(fangxiang==xia)

{

she[0]=she[0]+0x10; //高四位加1

}

if(fangxiang==zuo)

{

she[0]=(she[0]&0xf0)|(she[0]-0x01)&0x07; //低四位减1

}

if(fangxiang==you)

{

she[0]=she[0]+0x01; //低四位加1

}

she[0]=she[0]&0x77; //控制坐标范围不超过0,0-7,7

}

void xianshishe() //显示蛇,将蛇体数据映射到显存

{

unsigned char i;

for(i=0;i

{

dpdat[i]=0;

}

for(i=0;i

{

if(she[i]!=0xff)//如果未到蛇尾

{

dpdat[she[i]>>4]|=0x80>>(she[i]&0x0f);//根据xy坐标绘制

}

else

{

break;//已到蛇尾,退出当前循环

}

}

if(shiwushanshuo)//绘制食物,蛇体最后一个字节是食物坐标

}

void chulishe()

{

unsigned char i;

bit shiwuzaisheshenshang;

if(she[0]==she[64])//蛇头坐标与食物坐标一致,说明吃到食物

{

for(i=0;i

{

if(she[i]==0xff)//如果到蛇尾

{

she[i]=she[i-1];//蛇尾复制前一节点坐标

she[i+1]=0xff;//蛇尾后移

break;

}

}

do

{

shiwuzaisheshenshang=0;//假设新生成的食物坐标不在蛇身上

she[64]=TL0&0x77;//使用TL0的值随机生成一个食物坐标

for(i=0;i

{

if(she[i]==she[64])//节点坐标与食物坐标相同

{

shiwuzaisheshenshang=1;//置标志位

}

}

}while(shiwuzaisheshenshang);//如果重合,再重新生成一个食物坐标

}

for(i=1;i

{

if(she[0]==she[i])//如果蛇头与蛇体节点重合,说明咬到自己了,重新初始化蛇

}

}

原理图如下:(请将手机翻转查看)

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190214B0VT2200?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券