本帖最后由 yaosongjin2018 于 2019-4-30 14:54 编辑
前两天在本论坛看到有人分享的8*8点阵屏贪吃蛇,想到自己有个OLED屏,成功移植过来了,不敢独享,特分享给有需要的朋友。#include "snake.h"
extern u16 j;
extern u8 OLED_GRAM[128][8];//显示缓存
unsigned int she[65]; //蛇体数组,由于用的OLED显存为128*64,所以用两个字节表示蛇的一个节点,高8位和低8位分别表示y,x坐标
u8 fangxiang; //蛇头移动方向
u8 shiwushanshuo; //食物闪烁控制位
void xianshishe(void) //显示蛇,将蛇体数据映射到显存
{
unsigned char i,n;
u8 x,y;
for(i=0;i<8;i++)for(n=0;n<128;n++)
{
if(i==0)OLED_GRAM[n][i]=0X01;//绘制蛇之前先清除显存
else if(i==7)OLED_GRAM[n][i]=0X80;
else if(n==0)OLED_GRAM[n][i]=0Xff;
else if(n==127)OLED_GRAM[n][i]=0Xff;
else OLED_GRAM[n][i]=0X00;
if((i==0||i==7)&&(n==0||n==127))OLED_GRAM[n][i]=0Xff;
}
for(i=0;i<65;i++)//从头到尾遍历蛇体数据
{
if(she[i]!=0xffff)//如果未到蛇尾
{
y=she[i]>>8;
x=she[i]&0xff;//根据xy坐标绘制
OLED_DrawPoint(x,y,1);
}
else
{
break;//已到蛇尾,退出当前循环
}
}
if(shiwushanshuo) OLED_DrawPoint((she[64]&0xff),(she[64]>>8),1);//绘制食物,蛇体最后一个字节是食物坐标
OLED_Refresh_Gram();
}
void shechushihua(void) //蛇初始化,蛇长两个节点,0xff表示蛇尾,最后一个字节是食物坐标,初始向左移动
{
u8 a,b;
a=j;
if(j>62)j=124-j;//由于显示屏是长方形,所以要加此判断
b=j;
she[64]=((b<<8)|a)&0x7fff;//使用TL0的值随机生成一个食物坐标
she[0]=0x1008;//表示蛇头的坐标
she[1]=0x1007;
she[2]=0x1006;
she[3]=0x1005;
she[4]=0xffff;//蛇尾标志
fangxiang=xia;
}
void yidongshe(unsigned char fangxiang) //移动蛇
{
unsigned char i;
for(i=63;i>0;i--) //从蛇尾向蛇头遍历蛇体数据
{
if(she[i]!=0xffff) //不是蛇尾
{
she[i]=she[i-1]; //后一节点复制前一节点坐标
}
else
{
continue; //是0xff表示是蛇尾数据,继续向前
}
}
if(fangxiang==shang) //点阵左上角坐标为0,0,右下角坐标为127,63
{
she[0]=she[0]-0x100; //高8位减1
}
if(fangxiang==xia)
{
she[0]=she[0]+0x100; //高8位加1
}
if(fangxiang==zuo)
{
she[0]=she[0]-0x01; //低8位减1
}
if(fangxiang==you)
{
she[0]=she[0]+0x01; //低8位加1
}
she[0]=she[0]&0x7fff; //控制坐标范围不超过1,1-126,62,因为边缘画了框,所以坐标改小
}
u8 chulishe(void)
{
unsigned char i;
u8 a,b;
u8 shiwuzaisheshenshang;
if(she[0]==she[64])//蛇头坐标与食物坐标一致,说明吃到食物
{
for(i=0;i<65;i++)//遍历蛇体数据
{
if(she[i]==0xffff)//如果到蛇尾
{
she[i]=she[i-1];//蛇尾复制前一节点坐标
she[i+1]=0xffff;//蛇尾后移
break;
}
}
do
{
shiwuzaisheshenshang=0;//假设新生成的食物坐标不在蛇身上
a=j;
if(j>62)j=124-j;//由于显示屏是长方形,所以要加此判断
b=j;
she[64]=((b<<8)|a)&0x7fff;//使用J的值随机生成一个食物坐标
for(i=0;i<64;i++)//遍历蛇体判断新的食物是否跟蛇体重合
{
if(she[i]==she[64])//节点坐标与食物坐标相同
{
shiwuzaisheshenshang=1;//置标志位
break;
}
}
}while(shiwuzaisheshenshang);//如果重合,再重新生成一个食物坐标
}
for(i=1;i<64;i++)//遍历蛇体
{
if(she[0]==she[i])//如果蛇头与蛇体节点重合,说明咬到自己了,重新初始化蛇
{
shechushihua();
OLED_ShowString(25,25,"GAME OVER",12);
OLED_Refresh_Gram();
delay_ms(2000);
return 0;
}
if(((she[0]>>8)>62)||((she[0]>>8)<1)||((she[0]&0xff)>126)||((she[0]&0xff)<1))//如果蛇撞到屏幕边缘,游戏结束,重新初始化
{
shechushihua();
OLED_ShowString(25,25,"GAME OVER",12);
OLED_Refresh_Gram();
delay_ms(2000);
return 0;
}
}
return 1;
}
|