我是靠谱客的博主 含糊夕阳,最近开发中收集的这篇文章主要介绍使用ks0108的12864液晶显示的俄罗斯方块,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

先等上来一个文件,还有几个以后登。算法参考了毛建忠的ToyBricks.c,在此表示感谢。

#include "Lcd_ks0108.h"

#define LINE 12//12行
#define ROW  8//8列
volatile unsigned char Block_Old[4][2],Block_Now[4][2];//记录方块原先的位置和现在的位置

,4,代表一个图形由4个方块组成,2代表x,y

volatile unsigned char MapCell[LINE+1][ROW+2];// =

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

,0,0,0,0,0,0,0,0,0,0};//方块活动区
volatile unsigned char flag;
volatile unsigned char top;
volatile unsigned char NumNow,NumNext;
volatile unsigned int  Score;
volatile unsigned char IsEnd;
volatile unsigned char IsStart;

//************************************************************************/
//*屏幕使用区域
// |----------x(0-95)------------|
// -         |
// |         |
// |         |   

96*64
// y(0-63)        |  
// |         | 
// |         |
// -         |
// |-----------------------------|
//每个方块8*8,屏幕上总共有12*8个方格,这样安排是由于液晶一页是8位,为了便于计算,取此值。
//可以建立一个12*8的数组,标记此块是否为使用,使用的话,增加新块的时候原先的块不被占用
//                                                                      */
//************************************************************************/
/**********************************************/
//write command
/**********************************************/
void Lcd_Command(unsigned char code)
{
 LOW(E);  //following the timing , first, start E.
 LOW(RS);
 LOW(RW);
 delay_nus(150);
 DATA = code;
 HIGH(E);
 delay_nms(1);
 LOW(E);
 delay_nus(300);
}

/**********************************************/
//write data
/**********************************************/
void Lcd_Data(unsigned char data)
{
 LOW(E);
 HIGH(RS);
 LOW(RW);
 delay_nus(150);
 DATA = data;
 HIGH(E);
 delay_nms(1);
 LOW(E);
 delay_nus(300);

}

/********************************************/
//initial
/********************************************/
void initial_lcd()
{
 Control_DDR = 0xFF;  //as output
 Data_DDR = 0xFF;
 Control_PORT = 0x00;
 Data_PORT = 0x00;

 HIGH(LCD_CS1);
 HIGH(LCD_CS2);
 Lcd_Command(OPEN_DISP); //open display
 //Lcd_Command(DISP_RAM_YROW); //Y position is 0;
}

void ks0108cls (void)       //清屏,光标回到左半屏左上角  
{  
 unsigned char i0,i1;  
 LOW(LCD_CS1);
 LOW(LCD_CS2);
 Lcd_Command(OPEN_DISP);          //打开显示  
 Lcd_Command(DISP_RAM_YROW);          //列地址回到0  
 for(i0=0;i0<8;i0++)     //页地址由0变到7  
 {  
  Lcd_Command(DISP_RAM_PAGE + i0);    
  for(i1=0;i1<64;i1++)//对某一行全写入0  
   Lcd_Data(0);
 }  
}

/********************************************/
//Draw a line
//
//
//           

   
// 0 *****************************************
//  *     *    

 *
//  *  part1  *  part2  *
//  *     *    

 *
//  *  0 - 64  *  0 - 64  * 
//  *     *    

 *
//  *     *    

 *
//  *     *    

 *
// 63 ***************************************** 
//
/********************************************/
void Lcd_DrawLine(unsigned char x,unsigned char y,unsigned char linelength)
{
 Lcd_Command(OPEN_DISP);
 Lcd_Command(DISP_RAM_STARTLINE);
 unsigned char i,temp,data;
 data = 0;
 x = (x>127)? 127:x;
 y = (y>63)? 63:y;
 //judge by the position and length
 switch (x>64)
 {
 case 1://this line is in part2
  HIGH(LCD_CS1);
  LOW(LCD_CS2);
  Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页,取其商

就是页数
  Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪一列,it has restriction

before,
           

//no less than 64, no more than 127.
  if (x + linelength > 128) linelength = 128 - x;//长度过长,就让他

在最右端结束

  data |= (1<<y%8);//we have confirm the page , now ,we need to know the

exactitude position
  for(i=0;i<linelength;i++)
   Lcd_Data(data);
  break;
 case 0://this line is in part1
  LOW(LCD_CS1);
  HIGH(LCD_CS2);
  Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页,取其商

就是页数
  Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列
  data |= (1<<y%8);
  switch(x + linelength > 64)
  {
  case 1://too long
   temp = 64 - x;
   for(i=0;i<temp;i++)//the part1
    Lcd_Data(data);
   LOW(LCD_CS2);
   HIGH(LCD_CS1);
   Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页

,取其商就是页数
   Lcd_Command(DISP_RAM_YROW);//确定在哪一列

   if (x + linelength < 128) //longer than part1,shorter than

part2
    linelength = linelength + x - 64;
   else
    linelength = 64;

   for(i=0;i<linelength;i++)//the part2
    Lcd_Data(data);

   break;
  case 0://not long
   for(i=0;i<linelength;i++)//the part1
    Lcd_Data(data);
   break;   
  }
  break;
 }


}
/********************************************/
//Draw a vertical line
//
//
//  0     63    

 127  
//  *****************************************
//  *     *    

 *
//  *  part1  *  part2  *
//  *     *    

 *
//  *  0 - 64  *  0 - 64  * 
//  *     *    

 *
//  *     *    

 *
//  *     *    

 *
//  ***************************************** 
//  63
/********************************************/
void Lcd_DrawVerticalLine(unsigned char x,unsigned char y,unsigned char linelength)
{
 unsigned char i,data,fullpagenum;
 Lcd_Command(OPEN_DISP);
 Lcd_Command(DISP_RAM_STARTLINE);
 x = (x>127)? 127:x;
 y = (y>63)? 63:y;
 data = 0;
    //this function is easier than top one,for he no need to judge the part1 or part2.

 fullpagenum = (linelength - 1 - (7 - (y%8)))/8;//how many full pages
 switch (x<64)
 {
 case 1://in part 1
  LOW(LCD_CS1);
  HIGH(LCD_CS2);
  Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页,取其商

就是页数
  Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列
  //接下来这个判断还挺麻烦,用英语更麻烦,还是写汉语吧.需要判断这根线有多高
  //写数据是一次写8位,应该又要和商和余数纠缠了
  

//
  //    --------------------*----------------

-----------------
  //  page1  *  *  * 

 *  *
  //     *  *  

*  *  *
  //    ----*-------*-------*-------*--------

------------------
  //  page2  *  *  *
  //       *  


  //    ------------*-------*----------------

----------------
  //  page3    *  *
  //
  //    -------------------------------------

----------------  //  
  

//
  //起始点不用判断,主要是判断跨越了多少个完整page
  if ((linelength - 1 + y%8) < 8)//只在一个page内
  {
   for (i = 0;i < linelength - y%8 + 1;i++)
   {
    Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列,列地址会

变,所以得改回来
    data |= (1<<(y%8 + i));
   }
   Lcd_Data(data);//把第一个page显示出来
  }
  else//在不只一个page内
  {
   if(fullpagenum > 0)//在不只一个page内,而且至少包含一个完整page
   {
    //在很多个page里,那么就先写第一个page
    for(i = 0;i < 7 - y%8 + 1;i++)
    {
     Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列,

列地址会变,所以得改回来
     data |= (1<<(y%8 + i));
    }
    Lcd_Data(data);//先把第一个page显示出来
    //then we display the leaving pages,注意!,these are

full pages
    for (i = 0;i < fullpagenum;i++)
    {
     Lcd_Command(DISP_RAM_PAGE + y/8 + 1 + i);//确

定在哪一页
     Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列,

列地址会变,所以得改回来
     Lcd_Data(0xFF);
    }
    //last ,we display the last page
    if (((linelength - 1 - (7 - (y%8)))%8)!=0)//表示下面还

突出去一页
    {
     for(i = 0;i < ((linelength - 1 - (7 - (y%

8)))%8);i++)
     {
      Lcd_Command(DISP_RAM_PAGE + y/8 +

fullpagenum + 1);//确定在哪一页
      Lcd_Command(DISP_RAM_YROW + x);//确定

在哪一列,列地址会变,所以得改回来
      data |= (1<<i);
      Lcd_Data(data);
     }
    }
   }
   else//在不只一个page内,but the second one is not full
   {
    for (i = 0;i < (linelength - 1 - (7 - (y%8)));i++)
    {
     Lcd_Command(DISP_RAM_PAGE + y/8 + 1);
     Lcd_Command(DISP_RAM_YROW + x);
     data |= (1<<i);
     Lcd_Data(data);
    }
   }
  }
  break;
 case 0://in part 2  两部分代码完全一样,就是改了改x,这样很傻,但是容易看懂
  LOW(LCD_CS2);
  HIGH(LCD_CS1);
  Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页,取其商

就是页数
  Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪一列
  if ((linelength - 1 + y%8) < 8)//只在一个page内
  {
   for (i = 0;i < linelength - y%8 + 1;i++)
   {
    Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪一列,列地

址会变,所以得改回来
    data |= (1<<(y%8 + i));
   }
   Lcd_Data(data);//把第一个page显示出来
  }
  else//在不只一个page内
  {
   if(fullpagenum > 0)//在不只一个page内,而且至少包含一个完整page
   {
    //在很多个page里,那么就先写第一个page
    for(i = 0;i < 7 - y%8 + 1;i++)
    {
     Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪

一列,列地址会变,所以得改回来
     data |= (1<<(y%8 + i));
    }
    Lcd_Data(data);//先把第一个page显示出来
    //then we display the leaving pages,注意!,these are

full pages
    for (i = 0;i < fullpagenum;i++)
    {
     Lcd_Command(DISP_RAM_PAGE + y/8 + 1 + i);//确

定在哪一页
     Lcd_Command(DISP_RAM_YROW + x - 64);//确定在哪

一列,列地址会变,所以得改回来
     Lcd_Data(0xFF);
    }
    //last ,we display the last page
    if (((linelength - 1 - (7 - (y%8)))%8)!=0)//表示下面还

突出去一页
    {
     for(i = 0;i < ((linelength - 1 - (7 - (y%

8)))%8);i++)
     {
      Lcd_Command(DISP_RAM_PAGE + y/8 +

fullpagenum + 1);//确定在哪一页
      Lcd_Command(DISP_RAM_YROW + x - 64);//

确定在哪一列,列地址会变,所以得改回来
      data |= (1<<i);
      Lcd_Data(data);
     }
    }
   }
   else//在不只一个page内,but the second one is not full
   {
    for (i = 0;i < (linelength - 1 - (7 - (y%8)));i++)
    {
     Lcd_Command(DISP_RAM_PAGE + y/8 + 1);
     Lcd_Command(DISP_RAM_YROW + x - 64);
     data |= (1<<i);
     Lcd_Data(data);
    }
   }
  }
  break;
 }
 
}

//
//
//draw a square
//
//
//disp_or_erasure : 1:display the square   ************
//     0:erasure the square   

************
//           

  ************
//           

     ************
//           

  ************
//           

  ************
//           

  ************
//
//
void Lcd_DrawSquare(unsigned char x,unsigned char y,unsigned char

sidelinelength,unsigned char disp_or_erasure)
{
 unsigned char i,j,data,fullpagenum;
 Lcd_Command(OPEN_DISP);
 Lcd_Command(DISP_RAM_STARTLINE);
 x = (x + sidelinelength > SCREEN_X)? SCREEN_X - sidelinelength + 1:x +

1;//because the square has a periphery
 y = (y + sidelinelength > SCREEN_Y)? SCREEN_Y - sidelinelength + 1:y + 1;
 sidelinelength -= 2;
 data = 0;
 //we draw a square,这个正方形外面一圈虚线,里面是实心,能看到的正方形比

sidelinelength小2。
 fullpagenum = (sidelinelength - 1 - (7 - (y%8)))/8;//how many full pages
 Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页,取其商就是页数
 //以下共有三种情况,完全在part1,part1、2各占一部分的,完全在part2
 if (x<64)//case 1、2
 {  
  LOW(LCD_CS1);
  HIGH(LCD_CS2);
  Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列
  if ((x<64)&&((x + sidelinelength - 1)<64))//case 1
  {
   //only need to finish part1
   if ((sidelinelength - 1 + y%8) < 8)//只在一个page内
   {
    for (i = 0;i < sidelinelength - 1;i++)//draw

sidelinelength 个垂线
    { 
     for (j = 0;j < sidelinelength;j++)//one 垂线
     {
      data |= (1<<(y%8 + j));
     }
     if (disp_or_erasure)//1 disp;0 erasure
     {
      Lcd_Data(data);//把第一个page显示出来,

这里面x是自加的,i循环确定次数
     }
     else
     {
      Lcd_Data(0);
     }
    }
   }
   else//在不只一个page内.想了想,把正方形画成5、6个点不错,按理说

肯定没有fullpage,但还是增加吧,一来严谨,二来avr的flash够大
   {
    if(fullpagenum > 0)//在不只一个page内,而且至少包含一个

完整page
    {
     data = 0;//data 一定要初始化
     //在很多个page里,那么就先写第一个page
     for (i = 0;i < sidelinelength - 1;i++)
     {
      for(j = 0;j < 7 - y%8 + 1;j++)
      {
       data |= (1<<(y%8 + j));
      }
      if (disp_or_erasure)//1 disp;0 erasure
      {
       Lcd_Data(data);//把第一个page

显示出来,这里面x是自加的,i循环确定次数
      }
      else
      {
       Lcd_Data(0);
      }
     }//先把第一个page显示出来
     //then we display the leaving pages,注

意!,these are full pages
     for (i = 0;i < fullpagenum ;i++)//fullpagenum

个完整页
     {
      Lcd_Command(DISP_RAM_PAGE + y/8 + i +

1);//确定在哪一页
      Lcd_Command(DISP_RAM_YROW + x);//确定

在哪一列,列地址会变,所以得改回来
      for (j = 0;j < sidelinelength -

1;j++)//sidelinelength条垂线
      {
       if (disp_or_erasure)
       {
        Lcd_Data(0xFF);
       }
       else
       {
        Lcd_Data(0);
       }
      }
     }
     //last ,we display the last page
     data = 0;//data 一定要初始化
     if (((sidelinelength - 1 - (7 - (y%8)))%8)!

=0)//表示下面还突出去一页
     {
      Lcd_Command(DISP_RAM_PAGE + y/8 +

fullpagenum + 1);//确定在哪一页
      Lcd_Command(DISP_RAM_YROW + x);//确定

在哪一列
      for (i = 0;i < sidelinelength -

1;i++)//画很多竖线
      {     
       for(j = 0;j < ((sidelinelength

- 1 - (7 - (y%8)))%8);j++)//一条竖线
       {
        data |= (1<<j);
       }
       if (disp_or_erasure)//1 disp;0

erasure
       {
        Lcd_Data(data);//把第

一个page显示出来,这里面x是自加的,i循环确定次数
       }
       else
       {
        Lcd_Data(0);
       }
      }
     }
    }
    else//在不只一个page内,but the second one is not full
    {
     Lcd_Command(DISP_RAM_PAGE + y/8);
     Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列

     //first finish the top one
     data = 0;//data 一定要初始化
     for (i = 0;i < sidelinelength

;i++)//sidelinelength 条垂线
     {
      for(j = 0;j < 7 - y%8 + 1;j++)//one

line
       data |= (1<<(y%8 + j));
      if (disp_or_erasure)//1 disp;0 erasure
      {
       Lcd_Data(data);//把第一个page

显示出来,这里面x是自加的,i循环确定次数
      }
      else
      {
       Lcd_Data(0);
      }
     }
     //second finish the bottom one
     Lcd_Command(DISP_RAM_PAGE + y/8 + 1);//page

add 1
     Lcd_Command(DISP_RAM_YROW + x);//x coordinate

will increase automaticly
     
     data = 0;//data 一定要初始化
     for (i = 0;i < sidelinelength

;i++)//sidelinelength 条垂线
     {  
      for (j = 0;j < (sidelinelength + y%8 -

8);j++)//one vertical line
      {
       data |= (1<<j);
      }
      if (disp_or_erasure)//1 disp;0 erasure
      {
       Lcd_Data(data);//把第一个page

显示出来,这里面x是自加的,i循环确定次数
      }
      else
      {
       Lcd_Data(0);
      }
     }
    }
   }
  }
  else//case2
  {
   //以下的程序都和上边一样,只是有几个参数变了
   //first finish the part1
   if ((sidelinelength - 1 + y%8) < 8)//只在一个page内
   {
    for (i = 0;i < 64 - x;i++)//这里的参数不一样
    { 
     for (j = 0;j < sidelinelength;j++)
     {
      data |= (1<<(y%8 + j));
     }
     if (disp_or_erasure)//1 disp;0 erasure
     {
      Lcd_Data(data);//把第一个page显示出来,

这里面x是自加的,i循环确定次数
     }
     else
     {
      Lcd_Data(0);
     }
    }
   }
   else
   {
    if(fullpagenum > 0)
    {
     data = 0;//data 一定要初始化
     for (i = 0;i < 64 - x;i++)
     {
      for(j = 0;j < 7 - y%8 + 1;j++)
      {
       data |= (1<<(y%8 + j));
      }
      if (disp_or_erasure)//1 disp;0 erasure
      {
       Lcd_Data(data);//把第一个page

显示出来,这里面x是自加的,i循环确定次数
      }
      else
      {
       Lcd_Data(0);
      }
     }
     for (i = 0;i < fullpagenum ;i++)
     {
      Lcd_Command(DISP_RAM_PAGE + y/8 + i +

1);
      Lcd_Command(DISP_RAM_YROW + x);
      for (j = 0;j < 64 - x;j++)
      {
       if (disp_or_erasure)//1 disp;0

erasure
       {
        Lcd_Data(0xFF);//把第

一个page显示出来,这里面x是自加的,i循环确定次数
       }
       else
       {
        Lcd_Data(0);
       }
      }
     }
     data = 0;//data 一定要初始化
     if (((sidelinelength - 1 - (7 - (y%8)))%8)!=0)
     {
      Lcd_Command(DISP_RAM_PAGE + y/8 +

fullpagenum + 1);
      Lcd_Command(DISP_RAM_YROW + x);
      for (i = 0;i < 64 - x;i++)
      {     
       for(j = 0;j < ((sidelinelength

- 1 - (7 - (y%8)))%8);j++)
       {
        data |= (1<<j);
       }
       if (disp_or_erasure)//1 disp;0

erasure
       {
        Lcd_Data(data);//把第

一个page显示出来,这里面x是自加的,i循环确定次数
       }
       else
       {
        Lcd_Data(0);
       }
      }
     }
    }
    else//在不只一个page内,but the second one is not full
    {
     Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页

,8位一页,共8页,取其商就是页数
     Lcd_Command(DISP_RAM_YROW + x);//x coordinate

should be confirmed
     //first finish the top one
     data = 0;//data 一定要初始化
     for (i = 0;i < 64 - x ;i++)//sidelinelength 条

垂线
     {
      for(j = 0;j < 7 - y%8 + 1;j++)//one

line
       data |= (1<<(y%8 + j));
      if (disp_or_erasure)//1 disp;0 erasure
      {
       Lcd_Data(data);//把第一个page

显示出来,这里面x是自加的,i循环确定次数
      }
      else
      {
       Lcd_Data(0);
      }
     }
     //second finish the bottom one
     Lcd_Command(DISP_RAM_PAGE + y/8 + 1);//page

add 1
     Lcd_Command(DISP_RAM_YROW + x);//x coordinate

will increase automaticly
     
     data = 0;//data 一定要初始化
     for (i = 0;i < 64 - x ;i++)//sidelinelength 条

垂线
     {  
      for (j = 0;j < (sidelinelength + y%8 -

8);j++)//one vertical line
      {
       data |= (1<<j);
      }
      if (disp_or_erasure)//1 disp;0 erasure
      {
       Lcd_Data(data);//把第一个page

显示出来,这里面x是自加的,i循环确定次数
      }
      else
      {
       Lcd_Data(0);
      }
     }
    }
   }
   //the part1 have been finished
   //then finish part2
   LOW(LCD_CS2);
   HIGH(LCD_CS1);
   Lcd_Command(DISP_RAM_PAGE + y/8);//确定在哪一页,8位一页,共8页

,取其商就是页数
   Lcd_Command(DISP_RAM_YROW);//确定在哪一列
   if ((sidelinelength - 1 + y%8) < 8)//只在一个page内
   {
    data = 0;//data 一定要初始化
    for (i = 0;i < sidelinelength + x  - 64;i++)//draw

sidelinelength 个垂线
    {  
     for (j = 0;j < sidelinelength - y%8 +

1;j++)//one 垂线
     {
      data |= (1<<(y%8 + j));
     }
     if (disp_or_erasure)//1 disp;0 erasure
     {
      Lcd_Data(data);//把第一个page显示出来,

这里面x是自加的,i循环确定次数
     }
     else
     {
      Lcd_Data(0);
     }//把第一个page显示出来,这里面x是自加的,i循环

确定次数
    }
   }
   else//在不只一个page内,想了想,把正方形画成5、6个点不错,按理说

肯定没有fullpage,但还是增加吧,一来严谨,二来avr的flash够大
   {
    if(fullpagenum > 0)//在不只一个page内,而且至少包含一个

完整page
    {
     //在很多个page里,那么就先写第一个page
     data = 0;//data 一定要初始化
     for (i = 0;i < sidelinelength + x - 64;i++)
     {
      for(j = 0;j < 7 - y%8 + 1;j++)
      {
       data |= (1<<(y%8 + j));
      }
      if (disp_or_erasure)//1 disp;0 erasure
      {
       Lcd_Data(data);//把第一个page

显示出来,这里面x是自加的,i循环确定次数
      }
      else
      {
       Lcd_Data(0);
      }
     }//先把第一个page显示出来
     //then we display the leaving pages,注

意!,these are full pages
     for (i = 0;i < fullpagenum ;i++)//fullpagenum

个完整页
     {
      Lcd_Command(DISP_RAM_PAGE + y/8 + 1 +

i);//确定在哪一页
      Lcd_Command(DISP_RAM_YROW );//确定在哪

一列,列地址会变,所以得改回来
      for (j = 0;j < sidelinelength + x -

64;j++)//sidelinelength条垂线
      {
       if (disp_or_erasure)//1 disp;0

erasure
       {
        Lcd_Data(0xFF);//把第

一个page显示出来,这里面x是自加的,i循环确定次数
       }
       else
       {
        Lcd_Data(0);
       }
      }
     }
     //last ,we display the last page
     if (((sidelinelength - 1 - (7 - (y%8)))%8)!

=0)//表示下面还突出去一页
     {
      Lcd_Command(DISP_RAM_PAGE + y/8 +

fullpagenum + 1);//确定在哪一页
      Lcd_Command(DISP_RAM_YROW );//确定在哪

一列
      
      data = 0;//data 一定要初始化
      for (i = 0;i < sidelinelength + x -

64;i++)//画很多竖线
      {     
       for(j = 0;j < ((sidelinelength

- 1 - (7 - (y%8)))%8);j++)//一条竖线
       {
        data |= (1<<j);
       }
       if (disp_or_erasure)//1 disp;0

erasure
       {
        Lcd_Data(data);//把第

一个page显示出来,这里面x是自加的,i循环确定次数
       }
       else
       {
        Lcd_Data(0);
       }
      }
     }
    }
    else//在不只一个page内,but the second one is not full
    {
     //first finish the top one
     Lcd_Command(DISP_RAM_PAGE + y/8 );//page be

make sure once is enougth
     Lcd_Command(DISP_RAM_YROW );//x coordinate

will increase automaticly
     
     data = 0;//data 一定要初始化
     for (i = 0;i < sidelinelength + x - 64

;i++)//sidelinelength 条垂线
     {
      for(j = 0;j < 7 - y%8 + 1;j++)//one

line
       data |= (1<<(y%8 + j));
      if (disp_or_erasure)//1 disp;0 erasure
      {
       Lcd_Data(data);//把第一个page

显示出来,这里面x是自加的,i循环确定次数
      }
      else
      {
       Lcd_Data(0);
      }
     }
     
     //second finish the bottom one
     Lcd_Command(DISP_RAM_PAGE + y/8 + 1);//page

add 1
     Lcd_Command(DISP_RAM_YROW );//x coordinate

will increase automaticly
     
     data = 0;//data 一定要初始化
     for (i = 0;i < sidelinelength + x -

64;i++)//sidelinelength 条垂线
     {  
      for (j = 0;j < (sidelinelength - 1 -

(7 - (y%8)));j++)//one vertical line
      {
       data |= (1<<j);
      }
      if (disp_or_erasure)//1 disp;0 erasure
      {
       Lcd_Data(data);//把第一个page

显示出来,这里面x是自加的,i循环确定次数
      }
      else
      {
       Lcd_Data(0);
      }
     }
    }
   }
  }
 }
 else//case3
 { 
  LOW(LCD_CS2);
  HIGH(LCD_CS1);
  x -= 64;
  if ((sidelinelength - 1 + y%8) < 8)//只在一个page内
  {
   for (i = 0;i < sidelinelength - 1;i++)//draw sidelinelength 个

垂线
   { 
    for (j = 0;j < sidelinelength;j++)//one 垂线
    {
     data |= (1<<(y%8 + j));
    }
    Lcd_Data(data);//把第一个page显示出来,这里面x是自加的,

i循环确定次数
   }
  }
  else//在不只一个page内.
  {
   if(fullpagenum > 0)//在不只一个page内,而且至少包含一个完整page
   {
    data = 0;//data 一定要初始化
    //在很多个page里,那么就先写第一个page
    for (i = 0;i < sidelinelength - 1;i++)
    {
     for(j = 0;j < 7 - y%8 + 1;j++)
     {
      data |= (1<<(y%8 + j));
     }
     Lcd_Data(data);
    }//先把第一个page显示出来
    //then we display the leaving pages,注意!,these are

full pages
    for (i = 0;i < fullpagenum ;i++)//fullpagenum 个完整页
    {
     Lcd_Command(DISP_RAM_PAGE + y/8 + i + 1);//确

定在哪一页
     Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列,

列地址会变,所以得改回来
     for (j = 0;j < sidelinelength -

1;j++)//sidelinelength条垂线
     {
      Lcd_Data(0xFF);
     }
    }
    //last ,we display the last page
    data = 0;//data 一定要初始化
    if (((sidelinelength - 1 - (7 - (y%8)))%8)!=0)//表示下

面还突出去一页
    {
     Lcd_Command(DISP_RAM_PAGE + y/8 + fullpagenum

+ 1);//确定在哪一页
     Lcd_Command(DISP_RAM_YROW + x);//确定在哪一列
     for (i = 0;i < sidelinelength - 1;i++)//画很多

竖线
     {     
      for(j = 0;j < ((sidelinelength - 1 -

(7 - (y%8)))%8);j++)//一条竖线
      {
       data |= (1<<j);
      }
      Lcd_Data(data);    

  
     }
    }
   }
   else//在不只一个page内,but the second one is not full
   {
    Lcd_Command(DISP_RAM_YROW + x);//x coordinate should

be confirmed
    //first finish the top one
    data = 0;//data 一定要初始化
    for (i = 0;i < sidelinelength ;i++)//sidelinelength 条

垂线
    {
     for(j = 0;j < 7 - y%8 + 1;j++)//one line
      data |= (1<<(y%8 + j));
     Lcd_Data(data);
    }
    //second finish the bottom one
    Lcd_Command(DISP_RAM_PAGE + y/8 + 1);//page add 1
    Lcd_Command(DISP_RAM_YROW + x);//x coordinate will

increase automaticly
    
    data = 0;//data 一定要初始化
    for (i = 0;i < sidelinelength ;i++)//sidelinelength 条

垂线
    {  
     for (j = 0;j < (sidelinelength + y%8 -

8);j++)//one vertical line
     {
      data |= (1<<j);
     }
     Lcd_Data(data); 
    }
   }
  }  
 }

/************************************************************************/
/* 根据方块的特点,画方块 。x(0 - 11),y(0 - 7)                          */
/************************************************************************/
void Lcd_DrawBlock(unsigned char x,unsigned char y,unsigned char disp_or_erasure)
{
 unsigned char i;
 Lcd_Command(OPEN_DISP);
 Lcd_Command(DISP_RAM_STARTLINE);
//  x = (x>11)? 11:x;
//  y = (y>11)? 11:y;
//  x = (x<0)? 0:x;
//  y = (y<0)? 0:y;
 
 switch (x>=8)
 {
 case 1://part2
  LOW(LCD_CS2);
  HIGH(LCD_CS1);
  x -=8;
  Lcd_Command(DISP_RAM_YROW + x*BLOCKLINE + 1);
  Lcd_Command(DISP_RAM_PAGE + y);
  if (y == 0)//两种特殊情况,保证两边的边线存在,要是不考虑这个边线的话,能

省下四个if。
  {
   for (i = 0;i < 7;i++)
   {
    if (disp_or_erasure)//display
    {
     Lcd_Data(0xFF);
    }
    else
    {
     Lcd_Data(0x80);
    }
   }
  }
  else if (y == 7)//两种特殊情况
  {
   for (i = 0;i < 7;i++)
   {
    if (disp_or_erasure)//display
    {
     Lcd_Data(0xFF);
    }
    else
    {
     Lcd_Data(0x01);
    }
   }
  }
  else
  {
   for (i = 0;i < 7;i++)
   {
    if (disp_or_erasure)//display
    {
     Lcd_Data(0x7F);
    }
    else
    {
     Lcd_Data(0);
    }
   }
  }
  break;
 case 0:
  LOW(LCD_CS1);
  HIGH(LCD_CS2);
  Lcd_Command(DISP_RAM_YROW + x*BLOCKLINE + 1);
  Lcd_Command(DISP_RAM_PAGE + y);
  if (y == 0)//两种特殊情况
  {
   for (i = 0;i < 7;i++)
   {
    if (disp_or_erasure)//display
    {
     Lcd_Data(0xFF);
    }
    else
    {
     Lcd_Data(0x80);
    }
   }
  }   
  else if (y == 7)//两种特殊情况
  {
   for (i = 0;i < 7;i++)
   {
    if (disp_or_erasure)//display
    {
     Lcd_Data(0xFF);
    }
    else
    {
     Lcd_Data(0x01);
    }
   }
  }
  else
  {
   for (i = 0;i < 7;i++)
   {
    if (disp_or_erasure)//display
    {
     Lcd_Data(0x7F);
    }
    else
    {
     Lcd_Data(0);
    }
   }
  }
  break;
 }
}

//************************************************************************/
//* 在某一位置写两个汉字,汉字大小固定  16*16格式,且y的起始点必须为页首,汉字本身必须完全

在某一part中。
//************************************************************************/
void Lcd_WirteHanZi(unsigned char x,unsigned char y,unsigned char hanzi[32])
{
 unsigned char i;
 Lcd_Command(OPEN_DISP);
 Lcd_Command(DISP_RAM_STARTLINE);
 if ((x>48)&&(x<63))
 {
  x = 48;
 }
 switch (x>=64)
 {
 case 1:
  LOW(LCD_CS2);
  HIGH(LCD_CS1);
  x -=64;
  break;
 case 0:
  LOW(LCD_CS1);
  HIGH(LCD_CS2);
  break;
 }
 Lcd_Command(DISP_RAM_YROW + x);
 Lcd_Command(DISP_RAM_PAGE + y/8);
 for (i = 0;i<16;i++)//two pages per one charactor,first make the top one
 {
  Lcd_Data(hanzi[i]);
//  SEEOUT(hanzi[i],1);
 }
 Lcd_Command(DISP_RAM_YROW + x);
 Lcd_Command(DISP_RAM_PAGE + y/8 + 1);
 for (i = 0;i<15;i++)//now make the bottom one
 {
  Lcd_Data(hanzi[16 + i]);
//  SEEOUT(hanzi[16 +i],2);
 }
}
//************************************************************************/
//*在某一位置写一个三位数,单个数字8*13,x和y确定了个位数的位置,十位和百位的位置分别加一。

                                                                    */
//************************************************************************/
void Lcd_WirteNum(unsigned char x,unsigned char y,unsigned int num)
{
 unsigned char i,j,temp;
 Lcd_Command(OPEN_DISP);
 Lcd_Command(DISP_RAM_STARTLINE);
 if ((x>48)&&(x<63))
 {
  x = 48;
 }
 switch (x>=64)
 {
 case 1:
  LOW(LCD_CS2);
  HIGH(LCD_CS1);
  x -=64;
  break;
 case 0:
  LOW(LCD_CS1);
  HIGH(LCD_CS2);
  break;
 }
 Lcd_Command(DISP_RAM_YROW + x);
 Lcd_Command(DISP_RAM_PAGE + y/8);
 if (num<10)
 {
  for (i = 0;i < 13;i++)
  {
   Lcd_Data(NUM[num][i]);
  }
  for (i = 1;i < 3;i++)
  {
   Lcd_Command(DISP_RAM_YROW + x);
   Lcd_Command(DISP_RAM_PAGE + y/8 + i);
   for (j = 0;j < 13;j++)
   {
    Lcd_Data(0);
   }
  }
 }
 else
 {
  if ((num>9)&&(num<100))
  {
   for (i = 0;i < 13;i++)
   {
    Lcd_Data(NUM[num%10][i]);
   }
   Lcd_Command(DISP_RAM_YROW + x);
   Lcd_Command(DISP_RAM_PAGE + y/8 + 1);
   for (i = 0;i < 13;i++)
   {
    Lcd_Data(NUM[num/10][i]);
   }
   Lcd_Command(DISP_RAM_YROW + x);
   Lcd_Command(DISP_RAM_PAGE + y/8 + 2);
   for (j = 0;j < 13;j++)
   {
    Lcd_Data(0);
   }   
  }
  else if((num>99)&&(num<1000))
  {
   temp = num%100;
   for (i = 0;i < 13;i++)//个位
   {
    Lcd_Data(NUM[temp%10][i]);
   }
   Lcd_Command(DISP_RAM_YROW + x);
   Lcd_Command(DISP_RAM_PAGE + y/8 + 1);
   for (i = 0;i < 13;i++)//十位
   {
    Lcd_Data(NUM[temp/10][i]);
   }
   Lcd_Command(DISP_RAM_YROW + x);
   Lcd_Command(DISP_RAM_PAGE + y/8 + 2);
   for (i = 0;i < 13;i++)//百位
   {
    Lcd_Data(NUM[num/100][i]);
   }
  }
  else
  {
   for (i = 0;i < 3;i++)
   {
    Lcd_Command(DISP_RAM_YROW + x);
    Lcd_Command(DISP_RAM_PAGE + y/8 + i);
    for (j = 0;j < 13;j++)
    {
     Lcd_Data(NUM[0][j]);
    }
   }
  }
 }
}

/************************************************************************/
/* 重绘游戏区域,当有一行消失的时候,需要用到这个                      */
/************************************************************************/
void Lcd_ReDrawAll(unsigned char Valid_Y_LOW,unsigned char Valid_Y_HIGH, unsigned char

Valid_X_LOW,unsigned char Valid_X_HIGH,unsigned char MapCell[12][8])
{
 unsigned char i,j;
 Lcd_Command(OPEN_DISP);
 Lcd_Command(DISP_RAM_STARTLINE);
 for (i = Valid_Y_LOW;i < Valid_Y_HIGH;i++)//列
 {
  Lcd_Command(DISP_RAM_PAGE + i);
  Lcd_Command(DISP_RAM_YROW);
  for (j = Valid_X_LOW;j < Valid_X_HIGH;j++)//一行一行的来,省点page
  {
   if (MapCell[j][i] == 1)
   {
    Lcd_DrawBlock(j,i,1);
   }
   else
   {
    Lcd_DrawBlock(j,i,0);
   }
  }  
 }
}
/************************************************************************/
/* 清除下面的区域 
  7   6   5   4      
103 *****************************
 |  | 0 | 0 | 0 |
110 *****************************
111 ******************************
 | 0 | 0 | 0 | 0 |
118 ****************************
119 *****************************
 |  | 0 | 0 | 0 |
127 ****************************就是这么4*3个格,需要清除的是8个
                                                   */
/************************************************************************/
void Lcd_Clear(void)
{
 unsigned char i;
 Lcd_Command(OPEN_DISP);
 Lcd_Command(DISP_RAM_STARTLINE);
 HIGH(LCD_CS1);
 LOW(LCD_CS2);//函数没有可移植性
 Lcd_Command(DISP_RAM_PAGE + 4);//page be make sure once is enougth
 Lcd_Command(DISP_RAM_YROW + 103-64);//x coordinate will increase automaticly
 for (i = 0;i<24;i++)
 {
  Lcd_Data(0);
 }
 Lcd_Command(DISP_RAM_PAGE + 5);
 Lcd_Command(DISP_RAM_YROW + 103-64);
 for (i = 0;i<25;i++)
 {
  Lcd_Data(0);
 }

 Lcd_Command(DISP_RAM_PAGE + 6);
 Lcd_Command(DISP_RAM_YROW + 103-64);
 for (i = 0;i<25;i++)
 {
  Lcd_Data(0);
 }

 Lcd_Command(DISP_RAM_PAGE + 7);//page be make sure once is enougth
 Lcd_Command(DISP_RAM_YROW + 111-64);//x coordinate will increase automaticly
 for (i = 0;i<9;i++)
 {
  Lcd_Data(0);
 }

}
/************************************************************************/
/* 在左下角画下一个图形   
//     ▓▓y
//     ▓▓
//   ▓▓▓▓x                                                     

           */
/************************************************************************/
void Lcd_DrawNext(unsigned char x,unsigned char y,unsigned char num)
{
 unsigned char i;
 unsigned char Block_Next[4][2];
 Lcd_Clear();
 switch (num)
 {
 case 0:
  // ▓▓
  // ▓▓
  Block_Next[0][0] =y;  Block_Next[0][1] =x;
  Block_Next[1][0] =y-1;  Block_Next[1][1] =x;
  Block_Next[2][0] =y;  Block_Next[2][1] =1+x;
  Block_Next[3][0] =y-1;  Block_Next[3][1] =1+x;
  break;
  
 case 1:
  // ▓▓▓▓
  Block_Next[0][0] =y+1;   Block_Next[0][1] =0+x;
  Block_Next[1][0] =y;   Block_Next[1][1] =0+x;
  Block_Next[2][0] =y-1;   Block_Next[2][1] =0+x;
  Block_Next[3][0] =y-2;   Block_Next[3][1] =0+x;
  break;
  
 case 2:
  //▓
  //▓▓
  //  ▓
  Block_Next[0][0] =y;   Block_Next[0][1] =0+x;
  Block_Next[1][0] =y;   Block_Next[1][1] =1+x;
  Block_Next[2][0] =y-1;   Block_Next[2][1] =1+x;
  Block_Next[3][0] =y-1;   Block_Next[3][1] =2+x;
  break;
  
 case 3:
  //  ▓
  //▓▓
  //▓
  Block_Next[0][0] =y-1;   Block_Next[0][1] =0+x;
  Block_Next[1][0] =y-1;   Block_Next[1][1] =1+x;
  Block_Next[2][0] =y;   Block_Next[2][1] =1+x;
  Block_Next[3][0] =y;   Block_Next[3][1] =2+x;
  break;
  
 case 4:
  //▓
  //▓
  //▓▓
  Block_Next[0][0] =y;   Block_Next[0][1] =0+x;
  Block_Next[1][0] =y;   Block_Next[1][1] =1+x;
  Block_Next[2][0] =y;   Block_Next[2][1] =2+x;
  Block_Next[3][0] =y-1;   Block_Next[3][1] =2+x;
  break;
  
 case 5:
  //  ▓
  //  ▓
  //▓▓
  Block_Next[0][0] =y-1;  Block_Next[0][1] =0+x;
  Block_Next[1][0] =y-1;  Block_Next[1][1] =1+x;
  Block_Next[2][0] =y-1;  Block_Next[2][1] =2+x;
  Block_Next[3][0] =y;   Block_Next[3][1] =2+x;
  break;
 case 6:
  //  ▓
  //▓▓▓
  Block_Next[0][0] =y;   Block_Next[0][1] =0+x;
  Block_Next[1][0] =y+1;  Block_Next[1][1] =1+x;
  Block_Next[2][0] =y;   Block_Next[2][1] =1+x;
  Block_Next[3][0] =y-1;  Block_Next[3][1] =1+x;
  break;  
 default:
  break;
 }
 for (i = 0;i<4;i++)
 {
  Lcd_DrawBlock(Block_Next[i][1],Block_Next[i][0],1);
 }

}

/************************************************************************/
/* 新的图形                                                             */
//    边界|  7|  6|  5|  4|  3|  2|  1|  0|边界
//     | | | | | | 

| | |
//     | | | | | | 

| | |
//     | | | | | | 

| | |
//     | | | | | | 

| | |  block[0] y; [1] x

//这个函数比较特别,y由左向右减少,不是增加,所以要移植的话需要重新修改
//    
//     ▓▓y
//     ▓▓
//   ▓▓▓▓x
/************************************************************************/
void Lcd_NewShape(unsigned char x,unsigned char y,unsigned char num)
{
 unsigned char i,j,k,lines;
 flag = 0;

 for(i=top; i<LINE-3; i++)
 {
  lines =0;
  // 循环语句检查是否有某一行全部被【方格】都填满
  for(j=1; j<=ROW+1; j++)
   if(! MapCell[j][i])
   { lines=1; break; }
   // 若该行被填满,则将上一行的填充状态复制到该行,依此类推
   // 即从该行开始,所有的【方格】都下移一行
   if(!lines)
   { 
    Score++;
    Lcd_WirteNum(114,8,Score);
    for(j=1;j<ROW+1; j++)
     for(k=i; k>=top; k--)
     MapCell[j][k]=MapCell[j][k-1];

    top++;
   }
 }
 SEEOUT(top,1);
 SEEOUT(Score,2);
 NumNow = NumNext;//等这个函数快结束的时候,就可以再产生新的num了
 
 switch (num)
 {
 case 0:
  // ▓▓
  // ▓▓
  Block_Old[0][0]=Block_Now[0][0] =y;   Block_Old[0]

[1]=Block_Now[0][1] =x;
  Block_Old[1][0]=Block_Now[1][0] =y-1;  Block_Old[1][1]

=Block_Now[1][1] =x;
  Block_Old[2][0]=Block_Now[2][0] =y;   Block_Old[2]

[1]=Block_Now[2][1] =1+x;
  Block_Old[3][0]=Block_Now[3][0] =y-1;  Block_Old[3][1]

=Block_Now[3][1] =1+x;
  break;
  
 case 1:
  // ▓▓▓▓
  Block_Old[0][0]=Block_Now[0][0] =y;   Block_Old[0]

[1]=Block_Now[0][1] =0+x;
  Block_Old[1][0]=Block_Now[1][0] =y-1;  Block_Old[1][1]

=Block_Now[1][1] =0+x;
  Block_Old[2][0]=Block_Now[2][0] =y-2;  Block_Old[2][1]

=Block_Now[2][1] =0+x;
  Block_Old[3][0]=Block_Now[3][0] =y-3;  Block_Old[3][1]

=Block_Now[3][1] =0+x;
  break;
  
 case 2:
  //▓
  //▓▓
  //  ▓
  Block_Old[0][0]=Block_Now[0][0] =y;   Block_Old[0]

[1]=Block_Now[0][1] =0+x;
  Block_Old[1][0]=Block_Now[1][0] =y;   Block_Old[1]

[1]=Block_Now[1][1] =1+x;
  Block_Old[2][0]=Block_Now[2][0] =y-1;  Block_Old[2][1]

=Block_Now[2][1] =1+x;
  Block_Old[3][0]=Block_Now[3][0] =y-1;  Block_Old[3][1]

=Block_Now[3][1] =2+x;
  break;
  
 case 3:
  //  ▓
  //▓▓
  //▓
  Block_Old[0][0]=Block_Now[0][0] =y-1;  Block_Old[0][1]

=Block_Now[0][1] =0+x;
  Block_Old[1][0]=Block_Now[1][0] =y-1;  Block_Old[1][1]

=Block_Now[1][1] =1+x;
  Block_Old[2][0]=Block_Now[2][0] =y;   Block_Old[2]

[1]=Block_Now[2][1] =1+x;
  Block_Old[3][0]=Block_Now[3][0] =y;   Block_Old[3]

[1]=Block_Now[3][1] =2+x;
  break;
  
 case 4:
  //▓
  //▓
  //▓▓
  Block_Old[0][0]=Block_Now[0][0] =y;   Block_Old[0]

[1]=Block_Now[0][1] =0+x;
  Block_Old[1][0]=Block_Now[1][0] =y;   Block_Old[1]

[1]=Block_Now[1][1] =1+x;
  Block_Old[2][0]=Block_Now[2][0] =y;   Block_Old[2]

[1]=Block_Now[2][1] =2+x;
  Block_Old[3][0]=Block_Now[3][0] =y-1;  Block_Old[3][1]

=Block_Now[3][1] =2+x;
  break;
  
 case 5:
  //  ▓
  //  ▓
  //▓▓
  Block_Old[0][0]=Block_Now[0][0] =y-1;  Block_Old[0][1]

=Block_Now[0][1] =0+x;
  Block_Old[1][0]=Block_Now[1][0] =y-1;  Block_Old[1][1]

=Block_Now[1][1] =1+x;
  Block_Old[2][0]=Block_Now[2][0] =y-1;  Block_Old[2][1]

=Block_Now[2][1] =2+x;
  Block_Old[3][0]=Block_Now[3][0] =y;   Block_Old[3]

[1]=Block_Now[3][1] =2+x;
  break;
 case 6:
  //  ▓
  //▓▓▓
  Block_Old[0][0]=Block_Now[0][0] =y;   Block_Old[0]

[1]=Block_Now[0][1] =0+x;
  Block_Old[1][0]=Block_Now[1][0] =y+1;  Block_Old[1][1]

=Block_Now[1][1] =1+x;
  Block_Old[2][0]=Block_Now[2][0] =y;   Block_Old[2]

[1]=Block_Now[2][1] =1+x;
  Block_Old[3][0]=Block_Now[3][0] =y-1;  Block_Old[3][1]

=Block_Now[3][1] =1+x;
  break;  
 default:
  break;
 }
 for (i = 0;i<4;i++)
 {
  Lcd_DrawBlock(Block_Now[i][1],Block_Now[i][0],1);
 } 

 NumNext =rand()%7;//再产生一个新的num.
}
/************************************************************************/
/*      这个函数放在timer里面                                                          

     */
/************************************************************************/
void Block_Timer(void)
{
 unsigned i,j;
 // if (x == 11) return;//最下边,退出
 for(i=0; i<4; i++)
  Block_Now[i][1]++;
 // 检查【方块】下移是否被档住,即判断下移后新位置是否有【方格】
 for(i=0; i<4; i++)
  if(MapCell[ Block_Now[i][1] ][ Block_Now[i][0] ])
  {
   for(i=0; i<4; i++)
    MapCell[ Block_Old[i][1] ][ Block_Old[i][0] ]=1;
   if(top>Block_Old[0][1]-2) top=Block_Old[0][1]-2;
   if (top==254)
   {
    IsEnd = 1;
    ks0108cls();//全部清屏
    Lcd_WirteHanZi(45,40,fen);
    Lcd_WirteHanZi(45,8,shu);
    Lcd_WirteNum(64,32,Score);
    return ;
   }
   Lcd_DrawNext(13,6,NumNext);

   Lcd_NewShape(0,4,NumNow);
   return ;
  }
  
  //没有的话就可以走到这一步
  for (i=0;i<4;i++)
  {
   Lcd_DrawBlock(Block_Old[i][1],Block_Old[i][0],0);
  }
  for(i=0; i<4; i++)
  {
   for(j=0; j<2; j++)
   {
    Block_Old[i][j]=Block_Now[i][j];
   }
  }
  for (i=0;i<4;i++)
  {
   Lcd_DrawBlock(Block_Now[i][1],Block_Now[i][0],1);
  }
}

/************************************************************************/
/* 向左走    x(0 - 11),y(0 - 7)           block[0] y; [1] x                          

                              */
/************************************************************************/
void Block_Left(void)
{
 unsigned i,j;
// if (y == (SCREEN_Y-7)/BLOCKLINE) return;//最左边,退出
 for(i=0; i<4; i++)
  Block_Now[i][0]++;
 //首先判断移动后,新位置上是否有块
 for(i=0; i<4; i++)
  if(MapCell[ Block_Now[i][1] ][ Block_Now[i][0] ])
  {
   for(i=0; i<4; i++)
    for(j=0; j<2; j++)
     Block_Now[i][j]=Block_Old[i][j];
    return;
  }
 //没有的话就可以走到这一步
 for (i=0;i<4;i++)
 {
  Lcd_DrawBlock(Block_Old[i][1],Block_Old[i][0],0);
 }
 for(i=0; i<4; i++)
 {
  for(j=0; j<2; j++)
  {
   Block_Old[i][j]=Block_Now[i][j];
  }
 }

 for (i=0;i<4;i++)
 {
  Lcd_DrawBlock(Block_Now[i][1],Block_Now[i][0],1);
 }    

}
/************************************************************************/
/* 向右走    x(0 - 11),y(0 - 7)           block[0] y; [1] x                          

                              */
/************************************************************************/
void Block_Right(void)
{
 unsigned i,j;
// if (y == 0/BLOCKLINE) return;//最右边,退出
 for(i=0; i<4; i++)
  Block_Now[i][0]--;
 //首先判断移动后,新位置上是否有块
 for(i=0; i<4; i++)
  if(MapCell[ Block_Now[i][1] ][ Block_Now[i][0] ])
  {
   for(i=0; i<4; i++)
    for(j=0; j<2; j++)
     Block_Now[i][j]=Block_Old[i][j];
    return;
  }
 //没有的话就可以走到这一步
 for (i=0;i<4;i++)
 {
  Lcd_DrawBlock(Block_Old[i][1],Block_Old[i][0],0);
 }
 for(i=0; i<4; i++)
 {
  for(j=0; j<2; j++)
  {
   Block_Old[i][j]=Block_Now[i][j];
  }
 }

 for (i=0;i<4;i++)
 {
  Lcd_DrawBlock(Block_Now[i][1],Block_Now[i][0],1);
 }    
 
}

/************************************************************************/
/* 向下走    x(0 - 11),y(0 - 7)         block[0] y; [1] x                            

                              */
/************************************************************************/
void Block_Down(void)
{
 unsigned i,j;
// if (x == 11) return;//最下边,退出
 for(i=0; i<4; i++)
  Block_Now[i][1]++;
 //首先判断移动后,新位置上是否有块
 for(i=0; i<4; i++)
 {
  if(MapCell[ Block_Now[i][1] ][ Block_Now[i][0] ])
  {
   for(i=0; i<4; i++)
    for(j=0; j<2; j++)
     Block_Now[i][j]=Block_Old[i][j];
    return;
  }
 }

 //没有的话就可以走到这一步
 for (i=0;i<4;i++)
 {
  Lcd_DrawBlock(Block_Old[i][1],Block_Old[i][0],0);
 }
 for(i=0; i<4; i++)
 {
  for(j=0; j<2; j++)
  {
   Block_Old[i][j]=Block_Now[i][j];
  }
 }
 for (i=0;i<4;i++)
 {
  Lcd_DrawBlock(Block_Now[i][1],Block_Now[i][0],1);
 }    
  
}
/************************************************************************/
/* 变换角度                   block[0] y; [1] x
//这个函数比较特别,y由左向右减少,不是增加,所以要移植的话需要重新修改
//不能移植的函数是短命的函数,反正这个程序也没打算让他多大发展          */
/************************************************************************/
void Change_Shape(void)
{
 unsigned char i,j,r;
 r=1;
 flag++;     //【方块】旋转加1
 switch(NumNow) // sel代表当前【方块】的形状
 {
 case 0: break;
  
 case 1:
  flag =flag%2;
  for(i=0; i<4; i++)
  {
   Block_Now[i][(flag+1)%2] =Block_Old[2][(flag+1)%2]; 
   Block_Now[i][flag] =Block_Old[2][flag]-2+i;
  }
  break;  
 case 2:
  flag =flag%2;
  if(flag)
  { 
   Block_Now[0][1] +=2; 
   Block_Now[3][0] +=2;
  }
  else
  { 
   Block_Now[0][1] -=2;
   Block_Now[3][0] -=2;
  }
  break;  
 case 3:
  flag =flag%2;
  if(flag)   
  { 
   Block_Now[0][1] +=2;
   Block_Now[3][0] -=2;
  }
  else   
  { 
   Block_Now[0][1] -=2;
   Block_Now[3][0] +=2;
  }
  break;  
 case 4:
  flag=flag%4;
  switch(flag)
  {
  case 0:
   Block_Now[2][0] -=2; Block_Now[3][0] -=2;
   Block_Now[2][1] +=1; Block_Now[3][1] +=1;
   break;
  case 1:
   Block_Now[2][0] -=1; Block_Now[3][0] -=1;
   Block_Now[2][1] -=2; Block_Now[3][1] -=2;
   break;
  case 2:
   Block_Now[2][0] +=2; Block_Now[3][0] +=2;
   Block_Now[2][1] -=1; Block_Now[3][1] -=1;
   break;
  case 3:
   Block_Now[2][0] +=1; Block_Now[3][0] +=1;
   Block_Now[2][1] +=2; Block_Now[3][1] +=2;
   break;
  }
  break;  
 case 5:
  flag=flag%4;
  switch(flag)
  {
  case 0:
   Block_Now[2][0] -=1; Block_Now[3][0] -=1;
   Block_Now[2][1] +=2; Block_Now[3][1] +=2;
   break;
  case 1:
   Block_Now[2][0] -=2; Block_Now[3][0] -=2;
   Block_Now[2][1] -=1; Block_Now[3][1] -=1;
   break;
  case 2:
   Block_Now[2][0] +=1; Block_Now[3][0] +=1;
   Block_Now[2][1] -=2; Block_Now[3][1] -=2;
   break;
  case 3:
   Block_Now[2][0] +=2; Block_Now[3][0] +=2;
   Block_Now[2][1] +=1; Block_Now[3][1] +=1;
   break;
  }
  break;  
 case 6:
  flag =flag%4;
  switch(flag)
  {
  case 0:
   Block_Now[0][0]--; Block_Now[0][1]--;
   Block_Now[1][0]++; Block_Now[1][1]--;
   Block_Now[3][0]--; Block_Now[3][1]++;
   break;
  case 1:
   Block_Now[1][0]--; Block_Now[1][1]++;
   break;
  case 2:
   Block_Now[0][0]++; Block_Now[0][1]++;
   break;
  case 3:
   Block_Now[3][0]++; Block_Now[3][1]--;
   break;
  }
  break;
 }
    
 //首先判断移动后,新位置上是否有块
 for(i=0; i<4; i++)
  if(MapCell[ Block_Now[i][1] ][ Block_Now[i][0] ])
  {
   for(i=0; i<4; i++)
    for(j=0; j<2; j++)
     Block_Now[i][j]=Block_Old[i][j];
    return;
  }
  //没有的话就可以走到这一步
  for (i=0;i<4;i++)
  {
   Lcd_DrawBlock(Block_Old[i][1],Block_Old[i][0],0);
  }
  for (i=0;i<4;i++)
  {
   Lcd_DrawBlock(Block_Now[i][1],Block_Now[i][0],1);
  }    
  
}

/************************************************************************/
/* 初始化block[][],两边为1底下为1,其余全是0                                           

                         */
/************************************************************************/
void Init_Block(void)
{
 unsigned char i,j;
 top = LINE - 1;

 for (i = 0;i<LINE+2;i++)//第一列全变成1
 {
  MapCell[i][0] = 1;
  MapCell[i][ROW+1] = 1;
 }
 for(i = 1;i<ROW+1;i++)
 {
  MapCell[LINE][i] = 1;
 }
 for (i = 0;i<LINE;i++)
 {
  for (j=1;j<ROW+1;j++)
  {
   MapCell[i][j] = 0;
  }
 }
 srand( 10);
 NumNow = rand()%7;
 srand( 11);
 NumNext =rand()%7;
//  SEEOUT(NumNext,1);
//  SEEOUT(NumNow,2);
 Lcd_DrawNext(13,6,NumNext);
 Lcd_NewShape(0,4,NumNow);
 

}

/************************************************************************/
/* 开始工作                                                                     */
/************************************************************************/
void Lcd_Start(void)
{
 Score = 0;
 IsEnd = 0;
 ks0108cls();
 Lcd_DrawLine(0,0,97);
 Lcd_DrawLine(0,63,97);
 // Lcd_DrawLine(97,33,40);
 
 Lcd_DrawVerticalLine(0,0,64);
 Lcd_DrawVerticalLine(97,0,64);
 // Lcd_DrawVerticalLine(127,0,64);
 
 Lcd_WirteHanZi(98,0,shu);
 Lcd_WirteHanZi(98,16,fen);
 Lcd_WirteNum(114,8,Score);
 Init_Block();
}

/************************************************************************/
/* 返回isend值                                                                     */
/************************************************************************/
unsigned char IsEndFun(void)
{
 return IsEnd;
}

 

最后

以上就是含糊夕阳为你收集整理的使用ks0108的12864液晶显示的俄罗斯方块的全部内容,希望文章能够帮你解决使用ks0108的12864液晶显示的俄罗斯方块所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部