⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snake.c

📁 51单片机上的贪吃蛇游戏
💻 C
📖 第 1 页 / 共 2 页
字号:
       }
          else My_snake.Game_Mode=GAME_OVER;
       return ;
    }
       break;
     case LEFT:
      {
     if(Press_Oppsite_Direction())
         {
      My_snake.direction=RIGHT;
         return ;      //如果是按了相反方向那么就返回并把方向转过来
      }
      else if(Sure_No_Stock()) //看看有障碍物
          Go_Ahead();
        else My_snake.Game_Mode=GAME_OVER;
       return ;
   }
       break;
  case UP:
            {
       if(Press_Oppsite_Direction())
         {
      My_snake.direction=DOWN;
         return ;      //如果是按了相反方向那么就返回并把方向转过来
      }
      else if(Sure_No_Stock()) //看看有障碍物
          Go_Ahead();
        else My_snake.Game_Mode=GAME_OVER;
       return ;
       }
       break;
     case DOWN:
          {    
          if(Press_Oppsite_Direction())
         {
      My_snake.direction=UP;
         return ;      //如果是按了相反方向那么就返回并把方向转过来
      }
      else if(Sure_No_Stock()) //看看有障碍物
          Go_Ahead();
        else My_snake.Game_Mode=GAME_OVER;
       return ;
    }
       break;
   default:
        break;
     return;            
    }
    return;
  
 }
 return ;
  
}
 
 
/*-------------------写数据或指令到LCD-------------*/
void wr_lcd (bit dat_comm,uchar content) /*-------------------写数据或指令到LCD-------------*/
{
  chk_busy ();
  if(dat_comm)
   {
    rs=1;   //data
    rw=0;   //write
   }
  else
   {
    rs=0;   //command
    rw=0;   //write
   }
  P0=content;   //output data or comm
  e=1;
  ;
  ;
  e=0;
}
 
 void init_lcd (void) //初始化定时器
{
 
 
  wr_lcd (comm,0x30);  /*--30---基本指令动作--*/  
  wr_lcd (comm,0x01);  /*--清屏,地址指针指向00H--*/
  wr_lcd (comm,0x06);  /*---光标的移动方向--*/
  wr_lcd (comm,0x0c);  /*---开显示,关游标--*/
}
 
 
 
 
  /*------------显示一个整屏----------*/
 void display_all_screen (uchar screen_num)
 { 
  uchar counter;
 wr_lcd (comm,0x30);  /*30---基本指令动作*/
    wr_lcd (comm,0x01);  /*清屏,地址指针指向00H*/
    
    wr_lcd (comm,0x34);
 wr_lcd (comm,0x30);
  
   wr_lcd (comm,clear_screen);//这里是写入清屏指令
   wr_lcd (comm,0x80);    //置AC为0
   for(counter=0;counter<64;counter++)
    {
     wr_lcd (dat,screen_data[screen_num][counter]);
    }
// screen_num

 }
 

 /*---------------检测忙信号----------------*/
void chk_busy (void)  /*---------------检测忙信号----------------*/
{
  P0=0xff;
  rs=0;
  rw=1;
  e =1;
  while(busy==1);
  e =0;
}
void Erasure()  //擦除屏幕函数 这是在绘图模式下 (uchar data1,uchar data2)
{
  uchar i,j,k,x;
   wr_lcd (comm,0x30);  /*30---基本指令动作*/
  wr_lcd (comm,0x01);  /*清屏,地址指针指向00H*/
  x=0x80;
  for(k=0;k<2;k++)
  {
    for(j=0;j<16;j++)
    {
      for(i=0;i<8;i++)
      {
        wr_lcd (comm,0x34);
        wr_lcd (comm,0x80+j*2);
        wr_lcd (comm,x+i);
        wr_lcd (comm,0x30);
        wr_lcd (dat,0x00);
        wr_lcd (dat,0x00);
      }
      for(i=0;i<8;i++)
      {
        wr_lcd (comm,0x34);
        wr_lcd (comm,0x80+j*2+1);
        wr_lcd (comm,x+i);
        wr_lcd (comm,0x30);
        wr_lcd (dat,0x00);
        wr_lcd (dat,0x00);
      }
    }
    x=0x88;
  }
  wr_lcd (comm,0x36);
}

void Write_Screen_Data_To_Screen(uchar x,uchar y)//这个函数是用来将缓存数据定入LCD的其中两个参数是缓存坐标
{
   uchar Screen_x=0,Screen_y=0,i,j;
 
   if(y<8) {
           Screen_x=0x80+x;
     Screen_y=0x80+y*4;
     }
      else
   {
   Screen_x=0x88+x;
   Screen_y=0x80+(y-8)*4;
   } //游戏中的坐标和屏上的坐标不一样,要换一下
   for(i=0;i<4;i++)
   {
    j=0;
        wr_lcd (comm,0x34);
        wr_lcd (comm,Screen_y+i);
        wr_lcd (comm,Screen_x);
        wr_lcd (comm,0x30);
        wr_lcd (dat,My_snake.Screen_data[j++][i]);
        wr_lcd (dat,My_snake.Screen_data[j++][i]);
  j=0;    
   }
     wr_lcd (comm,0x36);
   
}
void Re_Build_Buffer(uchar x,uchar y)//这个是用来重构缓存数据
{
  uchar i,j,k;
   for(i=0;i<2;i++)
      for(j=0;j<4;j++)
    {
    My_snake.Screen_data[i][j]=0x00;
    }
   
  for(i=0;i<SNAKE_LONG;i++)
  {
     if(My_snake.Snake_body[i][X_POT]/4==x&&My_snake.Snake_body[i][Y_POT]==y)
  {
  j=My_snake.Snake_body[i][X_POT]%4;
  switch(j)
    {
     case 0:
       {
   for(k=0;k<4;k++)   
          {
                 My_snake.Screen_data[0][k]=My_snake.Screen_data[0][k]|0xf0;
                }
        }
   break;
     case 1:
      {
   for(k=0;k<4;k++)   
              {
                      My_snake.Screen_data[0][k]=My_snake.Screen_data[0][k]|0x0f;
                    }
      }
   break;
  case 2:
      {
   for(k=0;k<4;k++)   
             {
                        My_snake.Screen_data[1][k]=My_snake.Screen_data[1][k]|0xf0;
                           }
             }
   break;
    case 3:
      {
   for(k=0;k<4;k++)   
             {
                            My_snake.Screen_data[1][k]=My_snake.Screen_data[1][k]|0x0f;
                           }
       }
   break;
   default:
         break;          
    }
  }
   }
   if(My_snake.Food_Postion.x/4==x&&My_snake.Food_Postion.y==y)
   {
   j=My_snake.Food_Postion.x%4;
  switch(j)
    {
     case 0:
       {
   for(k=0;k<4;k++)   
          {
                 My_snake.Screen_data[0][k]=My_snake.Screen_data[0][k]|0xf0;
                }
        }
   break;
     case 1:
      {
   for(k=0;k<4;k++)   
              {
                      My_snake.Screen_data[0][k]=My_snake.Screen_data[0][k]|0x0f;
                    }
      }
   break;
  case 2:
      {
   for(k=0;k<4;k++)   
             {
                        My_snake.Screen_data[1][k]=My_snake.Screen_data[1][k]|0xf0;
                           }
             }
   break;
    case 3:
      {
   for(k=0;k<4;k++)   
             {
                            My_snake.Screen_data[1][k]=My_snake.Screen_data[1][k]|0x0f;
                           }
       }
   break;
   default:
         break;          
    }
    }
}
 
void delay_ms(unsigned int ms)////延时毫秒级的
{  unsigned int i,j;
   uchar timer;
 for(i=0;i<ms;i++)
  for(j=0;j<30;j++)
     { for(timer=10;timer>1;timer--)
  {
  ;
  }
   }
}
void Inicial_Game()
{ 
  uchar i;
  TR1=0;
  for(i=0;i<SNAKE_LONG;i++)
   {
   My_snake.Snake_body[SNAKE_LONG-i-1][X_POT]=i;
   My_snake.Snake_body[SNAKE_LONG-i-1][Y_POT]=0;
   }  //初始化蛇身!
 My_snake.direction=RIGHT;                //初始化蛇方向!
      
    My_snake.Game_Mode=GAME_RUNING;
 My_snake.Record=0;
 KEY_DOWN=0;
 
 
     wr_lcd (comm,0x30);  /*30---基本指令动作*/
     wr_lcd (comm,0x01);  /*清屏,地址指针指向00H*/
     Erasure();
 
     // My_snake.Food_Postion.x=0;
 //My_snake.Food_Postion.y=0;
 Creat_Food();
   Write_Food();
  
 
  for(i=0;i<4;i++)
      {
   Re_Build_Buffer(i,0);
   Write_Screen_Data_To_Screen(i,0);
    
   }
   //voice_function();
  
  
   TR1=1;

}
void Erasure_Trail()  //擦尾
{
   uchar i;
   i=My_snake.Temp_Pot_Or_Last_Trail.x/4;
   Re_Build_Buffer(i,My_snake.Temp_Pot_Or_Last_Trail.y);
  Write_Screen_Data_To_Screen(i,My_snake.Temp_Pot_Or_Last_Trail.y);
     
}
void Draw_Head()//画头
{
  uchar i;
  i=My_snake.Snake_body[0][X_POT]/4;
  Re_Build_Buffer(i,My_snake.Snake_body[0][Y_POT]);
   Write_Screen_Data_To_Screen(i,My_snake.Snake_body[0][Y_POT]);
}
 
void test_inicial()
{
   uchar i;
  for(i=0;i<SNAKE_LONG;i++)
   {
   My_snake.Snake_body[SNAKE_LONG-i-1][X_POT]=i+SNAKE_LONG;
   My_snake.Snake_body[SNAKE_LONG-i-1][Y_POT]=0;
   }  //初始化蛇身!
 My_snake.direction=DOWN;                //初始化蛇方向!
 My_snake.Speed=0;        //初始化速度 
 My_snake.Game_Mode=GAME_RUNING;        //初始化状态
 My_snake.Current_screen_num=0;
 //Creat_Food();
 My_snake.Food_Postion.x=16;
 My_snake.Food_Postion.y=15;
 

}

void Creat_Food()//产生一个食物并且检测食物是不是产生在蛇的身上如果是重新产生
{
   uchar i;
  My_snake.Food_Postion.x=TH0%32; //丛定时器里面读数这样可以是随机的
  My_snake.Food_Postion.y=TL0%16;
  for(i=0;i<SNAKE_LONG;i++)
    {
 if(My_snake.Food_Postion.x==My_snake.Snake_body[i][X_POT]&&My_snake.Food_Postion.y==My_snake.Snake_body[i][Y_POT])
   {
   My_snake.Food_Postion.x=TH0%32;
      My_snake.Food_Postion.y=TH0%16;
   i=0;
   }
   }
 
        
}
void Write_Food()//把食物画到屏上
{
   uchar i;
   i=My_snake.Food_Postion.x/4;
   Re_Build_Buffer(i,My_snake.Food_Postion.y);
   Write_Screen_Data_To_Screen(i,My_snake.Food_Postion.y);

 
}

void Re_Build_Food_Buffer(uchar x,uchar y)//这个是用来重构缓存数据
{
uchar i,j,k;
   for(i=0;i<2;i++)
      for(j=0;j<4;j++)
    {
    My_snake.Screen_data[i][j]=0x00;
    }
   
  for(i=0;i<SNAKE_LONG;i++)
  {
     if(My_snake.Snake_body[i][X_POT]/4==x&&My_snake.Snake_body[i][Y_POT]==y)
  {
  j=My_snake.Snake_body[i][X_POT]%4;
  switch(j)
    {
     case 0:
       {
   for(k=0;k<4;k++)   
          {
                 My_snake.Screen_data[0][k]=My_snake.Screen_data[0][k]|0xf0;
                }
        }
   break;
     case 1:
      {
   for(k=0;k<4;k++)   
              {
                      My_snake.Screen_data[0][k]=My_snake.Screen_data[0][k]|0x0f;
                    }
      }
   break;
  case 2:
      {
   for(k=0;k<4;k++)   
             {
                        My_snake.Screen_data[1][k]=My_snake.Screen_data[1][k]|0xf0;
                           }
             }
   break;
    case 3:
      {
   for(k=0;k<4;k++)   
             {
                            My_snake.Screen_data[1][k]=My_snake.Screen_data[1][k]|0x0f;
                           }
       }
   break;
   default:
         break;          
    }
  }
   }
 
   j=My_snake.Food_Postion.x%4;
  switch(j)
    {
     case 0:
       {
   for(k=0;k<4;k++)   
          {
                 My_snake.Screen_data[0][k]=My_snake.Screen_data[0][k]|0xf0;
                }
        }
   break;
     case 1:
      {
   for(k=0;k<4;k++)   
              {
                      My_snake.Screen_data[0][k]=My_snake.Screen_data[0][k]|0x0f;
                    }
      }
   break;
  case 2:
      {
   for(k=0;k<4;k++)   
             {
                        My_snake.Screen_data[1][k]=My_snake.Screen_data[1][k]|0xf0;
                           }
             }
   break;
    case 3:
      {
   for(k=0;k<4;k++)   
             {
                            My_snake.Screen_data[1][k]=My_snake.Screen_data[1][k]|0x0f;
                           }
       }
   break;
   default:
         break;          
    }

 
  
 
}
void Test_inter_timer1()  //这个是用来做调试的
{
        TR1=0;
    TR0=0;
  if(My_snake.soft_conter>=My_snake.Speed)
     {
  My_snake.soft_conter=0;
  if(My_snake.Game_Mode==GAME_RUNING)
      {
         
            One_Step();
            Erasure_Trail();
            Draw_Head();
    //  Write_Food();
      if(My_snake.Snake_body[0][Y_POT]==My_snake.Food_Postion.y&&My_snake.Snake_body[0][X_POT]==My_snake.Food_Postion.x)
         {
     Creat_Food();//产生一个食物并且检测食物是不是产生在蛇的身上如果是重新产生
     Write_Food();     
      }
          
       }
    else My_snake.soft_conter++;
  
  }
   else My_snake.soft_conter++;
    TR1=1;
    TR0=1; 
}
 
/*-----------------显示你的成绩------------*/
void Show_Your_Record()
{
   display_all_screen(YOUR_RECORD);
 wr_lcd (comm,0x34);
 wr_lcd (comm,0x30);
    wr_lcd (comm,0x86);
 wr_lcd(dat,NO_Data[My_snake.Record/100]);
 wr_lcd(dat,NO_Data[(My_snake.Record%100)/10]);
 wr_lcd(dat,NO_Data[My_snake.Record%10]);
}
 
 main()
  { 
    //uchar i;
   inicial_timer();//初始化定时器
   Erasure();
    display_all_screen(WELCOME_SCREEN); //显示屏第一屏的欢迎信息
   My_snake.Current_screen_num=WELCOME_SCREEN;//
   My_snake.Game_Mode=GAME_WELCOME_SCREEN;
   My_snake.Speed=DEFAULT_SPEED;
   
 
  while(1) 
  {
 
 
  Key_Respond();
   
  } 
 
 
   // direction=right;//初始化方向
 // speech=2;//初始化速度
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -