本帖最后由 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;
- }
|