极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 21445|回复: 11

发一个自己用12864做的贪吃蛇游戏

[复制链接]
发表于 2015-12-3 17:41:14 | 显示全部楼层 |阅读模式
本帖最后由 baiyalou 于 2015-12-17 15:43 编辑


实现的功能:5个游戏等级,记录最高分
游戏说明:
1.调节等级界面:摇杆上下调节等级,摇杆向右不动游戏开始
2.显示分数界面:摇杆向右不动游戏重新开始
3.游戏断电保存历史最高分以及上一次游戏的速度等级
接线:12864按照u8glib库接线,摇杆:S-Y 接 A0     S-X 接 A1

视频链接:http://v.youku.com/v_show/id_XMTQwMjI1MjQ2OA==.html#paction



[pre lang="arduino" line="1" file="初始化程序"]#include <EEPROM.h>
void setup()
{
  EEPROM.write(0, 0);//修改此值可以修改最高分
  EEPROM.write(1, 1);
}

void loop()
{
}[/code]
游戏程序:
#include "U8glib.h"
#include <EEPROM.h>
U8GLIB_ST7920_128X64_1X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);   // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=A4, RS=A3,rw=A2
static unsigned char snake[] U8G_PROGMEM =
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,
0x80,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,
0xC0,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x07,
0xC0,0xFF,0x37,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x0F,
0xE0,0xE3,0x3F,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xCE,0xFF,0xCF,0x0F,
0xF0,0x01,0x7F,0xFC,0x03,0x00,0x00,0x00,
0x00,0x00,0x00,0xFC,0xCF,0x7F,0x80,0x0F,
0xF0,0x01,0x7E,0xFC,0x07,0xFC,0x01,0x00,
0x02,0x80,0xFF,0xFC,0xCF,0x3F,0x00,0x0F,
0xF0,0x00,0x7C,0xE0,0x07,0xFC,0x0F,0xC0,
0x03,0xE0,0xFF,0xFC,0x07,0x3E,0x00,0x1E,
0xF0,0x00,0x7C,0xE0,0x0F,0xFC,0x0F,0xE0,
0x07,0xE0,0xFF,0xF0,0x01,0x3E,0x00,0x1E,
0xF0,0x00,0x78,0xE0,0x0F,0xE0,0x05,0xE0,
0x07,0x00,0x1F,0xF0,0x00,0x3E,0x00,0x1C,
0xF0,0x00,0x78,0xE0,0x1F,0xE0,0x00,0xE0,
0x07,0x00,0x1F,0x78,0x00,0x3E,0x00,0x04,
0xF0,0x00,0x70,0xE0,0x1F,0xE0,0x00,0xF0,
0x07,0x00,0x1F,0x78,0x00,0x3E,0x00,0x00,
0xF0,0x00,0x70,0xE0,0x3F,0xE0,0x00,0xF0,
0x0F,0x00,0x1F,0x3C,0x00,0x3E,0xE0,0x00,
0xF0,0x01,0x20,0xE0,0x3F,0xE0,0x00,0xF0,
0x0F,0x00,0x1F,0x1E,0x00,0x3E,0xE0,0x00,
0xF0,0x01,0x00,0xE0,0x7F,0xE0,0x00,0xF8,
0x0F,0x00,0x1F,0x1E,0x00,0x3E,0xE0,0x00,
0xF0,0x03,0x00,0xE0,0x7C,0xE0,0x00,0x78,
0x1F,0x00,0x1F,0x0F,0x00,0x3E,0xE0,0x00,
0xF0,0x0F,0x00,0xE0,0xFC,0xE0,0x00,0x38,
0x1F,0x00,0x9F,0x07,0x00,0x3E,0xE0,0x00,
0xE0,0x1F,0x00,0xE0,0xF8,0xE0,0x00,0x3C,
0x1F,0x00,0x9F,0x07,0x00,0x3E,0xE0,0x00,
0xC0,0x7F,0x00,0xE0,0xF8,0xE1,0x00,0x3C,
0x1F,0x00,0xDF,0x03,0x00,0x3E,0xF0,0x00,
0xC0,0xFF,0x00,0xE0,0xF0,0xE1,0x00,0x3C,
0x3E,0x00,0xFF,0x07,0x00,0xFE,0xFF,0x00,
0x00,0xFF,0x03,0xE0,0xF0,0xE3,0x00,0x1C,
0x3E,0x00,0xFF,0x07,0x00,0xFE,0xFF,0x00,
0x00,0xFE,0x07,0xE0,0xE0,0xE3,0x00,0x1E,
0x3E,0x00,0xFF,0x0F,0x00,0xFE,0xFF,0x00,
0x00,0xFC,0x1F,0xE0,0xE0,0xE7,0x00,0x1E,
0x7C,0x00,0xFF,0x0F,0x00,0x7E,0xF8,0x00,
0x00,0xF0,0x3F,0xE0,0xC0,0xEF,0x00,0x0E,
0x7C,0x00,0xBF,0x1F,0x00,0x3E,0xF0,0x00,
0x00,0xC0,0x3F,0xE0,0x80,0xEF,0x00,0xFF,
0x7F,0x00,0x1F,0x1F,0x00,0x3E,0xE0,0x00,
0x00,0x80,0x7F,0xE0,0x80,0xFF,0x00,0xFF,
0x7F,0x00,0x1F,0x3F,0x00,0x3E,0xE0,0x00,
0x00,0x00,0x7E,0xE0,0x00,0xFF,0x00,0xFF,
0xFF,0x00,0x1F,0x3E,0x00,0x3E,0xE0,0x00,
0x00,0x00,0xFC,0xE0,0x00,0xFF,0x00,0x07,
0xF8,0x00,0x1F,0x7E,0x00,0x3E,0xE0,0x00,
0x00,0x00,0xF8,0xE0,0x00,0xFE,0x80,0x07,
0xF8,0x00,0x1F,0x7C,0x00,0x3E,0xE0,0x00,
0x00,0x00,0xF8,0xE0,0x00,0xFE,0x80,0x07,
0xF8,0x00,0x1F,0xFC,0x00,0x3E,0x00,0x00,
0x20,0x00,0xF0,0xE0,0x00,0xFC,0x80,0x03,
0xF8,0x01,0x1F,0xF8,0x00,0x3E,0x00,0x00,
0x38,0x00,0xF0,0xE0,0x00,0xFC,0xC0,0x03,
0xF0,0x01,0x1F,0xF8,0x01,0x3E,0x00,0x00,
0x78,0x00,0xF0,0xE0,0x00,0xF8,0xC0,0x03,
0xF0,0x01,0x1F,0xF0,0x01,0x3E,0x00,0x00,
0x78,0x00,0xF8,0xE0,0x00,0xF0,0xC0,0x03,
0xF0,0x03,0x1F,0xF0,0x01,0x3E,0x00,0x18,
0x78,0x00,0xF8,0xE0,0x00,0xF0,0xE0,0x03,
0xF8,0x03,0x1F,0xE0,0x03,0x3E,0x00,0x1C,
0x70,0x00,0x78,0xE0,0x00,0xE0,0xF8,0x0F,
0xFC,0xEF,0x3F,0xE0,0x03,0x3E,0x00,0x1C,
0xF0,0x00,0x7C,0xE0,0x0F,0xE0,0xF8,0x0F,
0xFC,0xEF,0xFF,0xF8,0x07,0x3E,0x00,0x1E,
0xF0,0x00,0x3C,0xFC,0x0F,0xC0,0xF8,0x01,
0xC0,0xEF,0xFF,0xF8,0x1F,0x3E,0x00,0x1E,
0xF0,0x01,0x3E,0xFC,0x0F,0x00,0x00,0x00,
0x00,0x00,0xC0,0xF8,0xDF,0x3F,0x00,0x1F,
0xF0,0x87,0x1F,0xFC,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0xDF,0xFF,0x83,0x0F,
0xF0,0xFF,0x0F,0x04,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x0F,
0xF0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0x0F,
0xF0,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x0F,
0xE0,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,
0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x07,
0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//位图“SNAKE”
int level; //游戏等级
int leveltime;//相应游戏等级时,蛇移动一个格需要的时间(实际比leveltime稍大)(ms)
unsigned long time1=0;//记录系统时间
char r[3];//游戏结束用于显示最高分数
char u[3];//游戏结束用于显示当前分数
unsigned long time=0;//记录系统时间
int n=0;//当前蛇的长度
int wei=0;//纪录蛇尾坐标:0~511
int ore;//蛇的运动方向 1:向右  2:向上   3:向左   4:向下
int y;
int k[512];//从k[0]~k[511]依次存放蛇头到蛇尾的坐标,如没有则存为-1
//例:如蛇有两节,蛇头坐标为1,蛇尾坐标为0,则k[0]=1,k[1]=0,k[2]~k[511]=-1
int addr=0;//EEPROM存放最高分的地址
unsigned long s[16];//用于记录蛇的每一节是否占据的坐标
long randNumber;//随机产生一个点作为蛇的食物
unsigned long p,q;
void setup(void) {
int level=EEPROM.read(1);
  Serial.begin(9600);
// pinMode(12,INPUT);
while(analogRead(1)<1000)
{
  while(millis()-time1==300)
  {
if(analogRead(0)>900)
{
  level=level+1;
  if(level>6)
  {
  level=1;
  }
}
if(analogRead(0)<100)
{
  level=level-1;
  if(level<1)
  {
  level=6;
  }
}
u8g.firstPage();  
  do {
    u8g.setFont(u8g_font_helvB12);
    switch(level)
    {
    case 1:
     u8g.drawStr(32, 60,"LEVEL 1");
     break;
     case 2:
     u8g.drawStr(32, 60,"LEVEL 2");
     break;
     case 3:
     u8g.drawStr(32, 60,"LEVEL 3");
     break;
     case 4:
     u8g.drawStr(32, 60,"LEVEL 4");
     break;
     case 5:
     u8g.drawStr(32, 60,"LEVEL 5");
     break;
     case 6:
     u8g.drawStr(32, 60,"LEVEL 6");
     break;
    }
    u8g.drawXBMP( 0, 0, 128, 56, snake);
//   u8g.setFont(u8g_font_helvB24);
//   u8g.drawStr(12, 40,"SNAKE");
  } while( u8g.nextPage() );
  time1=millis();
  }
}
leveltime=le(level);
if(level!=EEPROM.read(1))
{
EEPROM.write(1,level);
}
Serial.println(leveltime);
  for(y=0;y<=511;y++)   
{
k[y]=-1;
}
  k[0]=240;
  k[1]=239;
  k[2]=238;
for(y=0;y<=15;y++)   
{
s[y]=0;
}
for(y=0;y<=511;y++)
  {
  if(k[y]>=0)
  {
  s[k[y]/32]=s[k[y]/32]+cifang(31-k[y]%32);
  }
  }
randomSeed(analogRead(5));
ore=1;
// attachInterrupt(0, downleft, CHANGE);
//  attachInterrupt(1, upright, CHANGE);
}
void draw1(void)
{

r[0]=(EEPROM.read(addr)-3)/100+48;
r[1]=((EEPROM.read(addr)-3)%100)/10+48;
r[2]=(EEPROM.read(addr)-3)%10+48;
u[0]=(n-3)/100+48;;
u[1]=((n-3)%100)/10+48;
u[2]=(n-3)%10+48;
u8g.setFont(u8g_font_helvB24);
u8g.drawStr(74, 28,r);
u8g.setFont(u8g_font_helvB24);
u8g.drawStr(74, 60,u );
u8g.drawHLine(0,32, 128);
u8g.setFont(u8g_font_helvB12);
u8g.drawStr(4,15,"HIGH");
u8g.drawStr(4,31,"SCORE");
u8g.drawStr(4,47,"YOUR");
u8g.drawStr(4,63,"SCORE");
}
void draw2(void)
{
u8g.setFont(u8g_font_helvB12);
u8g.drawStr(42, 32,"GAME");
u8g.drawStr(42, 46,"OVER");
u8g.drawRFrame(39,17, 53,32, 2);
}
void draw(void) {
  int x;
int m=0;
  for(x=0;x<=511;x++)
  {
  if(k[x]>=0)
  {
    m=m+1;     
  }
  }
for(x=0;x<=m;x++)
  {
  if((k[x]-k[x+1])*(k[x]-k[x+1])==1)
  {
  u8g.drawBox((min(k[x],k[x+1])%32)*4,(min(k[x],k[x+1])/32)*4,7,3);
  }
  }
   for(x=0;x<=m-2;x++)
  {
  if((k[x]-k[x+1])*(k[x]-k[x+1])==1024)
  {
  u8g.drawBox((min(k[x],k[x+1])%32)*4,(min(k[x],k[x+1])/32)*4,3,7);
  }
  }
u8g.drawBox((randNumber%32)*4,(randNumber/32)*4,3,3);  
//Serial.println(randNumber);
}


void loop(void) {
aa: do {randNumber=random(0,512);}
while(((s[randNumber/32])/(cifang(31-randNumber%32)))%2==1);
n=0;
  for(y=0;y<=511;y++)
  {
  if(k[y]>=0)
  {
    n=n+1;     
  }
  }

while(k[0]!=randNumber)
{

  u8g.firstPage();  
  do {
draw();
  } while( u8g.nextPage() );
  time=millis();
  while(millis()-time<leveltime)
{
if (analogRead(0)>900)
{
if((ore==1)||(ore==3))  
{
  ore=4;
  goto out;
}
}
if (analogRead(0)<100)
{
if((ore==1)||(ore==3))  
{
  ore=2;
  goto out;
}
}
if (analogRead(1)>900)
{
if((ore==2)||(ore==4))  
{
  ore=1;
  goto out;
}
}
if (analogRead(1)<100)
{
if((ore==2)||(ore==4))  
{
  ore=3;
  goto out;
}
}
}
out: wei=k[n-1];
  if(ore==1)
  {
  for(y=n-2;y>=0;y--)
  {
  k[y+1]=k[y];
  }
  k[0]=k[0]+1;
   if((k[0]%32==0)||(((s[k[0]/32])/(cifang(31-k[0]%32)))%2==1))   
  {
gameover();
while(analogRead(1)<900)
{
}
goto aa;
  }
writes();
  }
  if(ore==2)
  {
  for(y=n-2;y>=0;y--)
  {
  k[y+1]=k[y];
  }
  k[0]=k[0]-32;
   if((k[0]<0)||(((s[k[0]/32])/(cifang(31-k[0]%32)))%2==1))   
{
   gameover();
   while(analogRead(1)<900)
{
}
goto aa;
  }
writes();
  }
  if(ore==3)
  {
  for(y=n-2;y>=0;y--)
  {
  k[y+1]=k[y];
  }
  k[0]=k[0]-1;
  if(((k[0]+33)%32==0)||(((s[k[0]/32])/(cifang(31-k[0]%32)))%2==1))
{
  gameover();
while(analogRead(1)<900)
{
}
goto aa;
  }
writes();
  }
  if(ore==4)
  {
  for(y=n-2;y>=0;y--)
  {
  k[y+1]=k[y];
  }
  k[0]=k[0]+32;
   if((k[0]>511)||(((s[k[0]/32])/(cifang(31-k[0]%32)))%2==1))   
{
  gameover();
  while(analogRead(1)<900)
{
}
goto aa;
  }
  writes();
  }


}
k[n]=wei;
s[k[n]/32]=s[k[n]/32]+cifang(31-k[n]%32);
}
void writes()
{
  for(y=0;y<=15;y++)   
{
s[y]=0;
}
  for(y=0;y<n;y++)
  {
  s[k[y]/32]=s[k[y]/32]+cifang(31-k[y]%32);
  }
}
void gameover()
{
if(n>EEPROM.read(addr))
  {
  EEPROM.write(addr, n);//如果得分超最高分,则记录
  }
   u8g.firstPage();  
  do {
draw2();//显示GAME OVER
  } while( u8g.nextPage() );
  delay(1500);
  u8g.firstPage();  
  do {
draw1();//显示分数
  } while( u8g.nextPage() );
    for(y=0;y<=511;y++)//游戏结束时重新初始化,以重新开始   
{
k[y]=-1;
}
  k[0]=240;
  k[1]=239;
  k[2]=238;
for(y=0;y<=15;y++)   
{
s[y]=0;
}
for(y=0;y<=511;y++)
  {
  if(k[y]>=0)
  {
  s[k[y]/32]=s[k[y]/32]+cifang(31-k[y]%32);
  }
  }
ore=1;
}
unsigned long cifang(int w)//2的w次方
{
  int v;
  if(w<=30)
  {
unsigned long q=1;
for(v=0;v<=w;v++)
{
q=q*2;
}
unsigned long p=q/2;
return p;
  }
  if(w==31)
  {
  p=2147483648;
  return p;
  }

}
int le(int w)//等级w对应的延时
{
  int f;
if(w==1) f=900;
if(w==2) f=500;
if(w==3) f=250;
if(w==4) f=100;
if(w==5) f=50;
if(w==6) f=2;
return f;
}
游戏程序已经更新,附件在此

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2015-12-3 21:41:40 | 显示全部楼层
有点意思,不错
回复 支持 反对

使用道具 举报

发表于 2015-12-4 00:38:38 | 显示全部楼层
45度角走的时候速度好像加快了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-12-4 09:08:24 | 显示全部楼层
不好意思,程序有一点问题,写入snake程序前需要先把eeprom地址为0和1的值初始化为0,然后才能在写入snake程序,否则显示会有问题,具体eeprom写入方法请查看相关例程。我在这里就不说了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-12-4 09:28:06 | 显示全部楼层
davidce 发表于 2015-12-4 00:38
45度角走的时候速度好像加快了

这是一条开挂的贪吃蛇
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-12-6 22:29:09 | 显示全部楼层
附件已删
回复 支持 反对

使用道具 举报

发表于 2015-12-9 01:24:11 | 显示全部楼层
论坛还是这条蛇最好看,求代码{:3_59:}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-12-9 08:46:23 来自手机 | 显示全部楼层
jiangyou-555 发表于 2015-12-9 01:24
论坛还是这条蛇最好看,求代码

留下邮箱            
回复 支持 反对

使用道具 举报

发表于 2015-12-9 14:12:37 | 显示全部楼层
本帖最后由 jiangyou-555 于 2015-12-9 14:14 编辑
baiyalou 发表于 2015-12-9 08:46
留下邮箱


[email protected]
回复 支持 反对

使用道具 举报

发表于 2015-12-9 23:47:25 | 显示全部楼层
回复 支持 反对

使用道具 举报

发表于 2016-2-14 09:21:26 | 显示全部楼层
居然我的Seeed摇杆不匹配。
改了摇杆数据后能玩啦,非常赞!
向baiyalou同学学习。
有一点小问题,在开始选级别时摇杆有点不灵敏。
待我大玩一场后再看啦。
回复 支持 反对

使用道具 举报

发表于 2016-6-14 22:59:58 | 显示全部楼层
求一个代码,谢谢楼主![email protected]
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-15 19:33 , Processed in 0.044419 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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