这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » proteus仿真的贪吃蛇程序

共3条 1/1 1 跳转至

proteus仿真的贪吃蛇程序

助工
2015-05-05 16:22:05     打赏

//贪吃蛇游戏程序,屏左半部用于游戏活动,右半部为分数显示
//游戏屏为16*16游戏点阵,可容纳蛇身块数256。每个游戏点阵又由4*4个LCD基本点阵组成
//蛇行标志在定时器上置位,这里为游戏的主体部分。
/*************************************************************************************************/
#include <reg51.h>
#include <absacc.h>
#include <intrins.h>
#define CS1WC XBYTE[0x8004]//CS1写指令         
#define CS1WD XBYTE[0x8005]//CS1写数据
#define CS1RS XBYTE[0x8006]//CS1读状态
#define CS1RD XBYTE[0x8007]//CS1读数据
#define CS2WC XBYTE[0x8008]
#define CS2WD XBYTE[0x8009]
#define CS2RS XBYTE[0x800a]
#define CS2RD XBYTE[0x800b]
#define P0   LCMDATA
#define BUSY_STATUS 0x80
#define uchar unsigned char 
#define uint unsigned int 
#define DISP_OFF 0x3e
#define DISP_ON  0x3f
#define START_LINE 0xc0
#define LEFT 0
#define RIGHT 1
#define TURN 1
#define FALSE 0
//定义键值
#define up 0x21
#define down 0x24
#define left 0x12
#define right 0x42
#define F1 0x18   //F1为ON
#define F2 0x28   //F2为0键
#define TIME_RUN 10          //软件计数器用他来调节游戏的速度

uchar getkey(void);//键盘扫描
void dlms(void);
//游戏部分
//x,y最大极限
#define MAX_GAME_X 15
#define MAX_GAME_Y 15
uchar snake_flag,                        //蛇头标志  7  6  5  4  3  2         1     0 
                                                         //          上 下 左 右 x  gameover  food  run
                snake_len,                        //蛇身长度
                snake_food;                        //食物位置,高4位Y,低4位x
        
uchar xdata snake_body[256];        //蛇身每个部分的数据
                                                        //          7  6  5  4  3  2  1  0
                                                        //                        高4位Y方向  低4位X方向
uchar *len=&snake_len;

#define lcd_no_read                                 //编译选项,把这项屏蔽掉就采用LCD读出方式,否则采用显存形式
#ifdef lcd_no_read
uchar xdata lcd_buf[8][64];//lcd缓冲,用于记录LCD内部的点阵,可以理解为显存
                                                        //当LCD无读出功能时,就要采用显示缓冲。本LCD为可读,一般不用这个功能
                                                        //缓冲只记录蛇身活动的部分,即LCD左半屏
#endif        




uchar  set_time;                        //贪吃蛇游戏频率计数值
/***********************以下为LCM部分***********************************************************/  

uchar dot_buffer[32];
uchar disp_buffer[]={0,1,2,3,4,5,6,7,8,9};
// ------------------  ASCII字模的数据表 ------------------------ //
// 码表从0x20~0x7e                                                //
// 字库: F:\技术文章LCD12864\LcmZimo\Asc8X16E.dat 纵向取模下高位 //
// -------------------------------------------------------------- //
unsigned char code nAsciiDot[] =              // ASCII
{
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  // - -
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

        0x00,0x00,0x38,0xFC,0xFC,0x38,0x00,0x00,  // -!-
        0x00,0x00,0x00,0x0D,0x0D,0x00,0x00,0x00,

        0x00,0x0E,0x1E,0x00,0x00,0x1E,0x0E,0x00,  // -"-
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

        0x20,0xF8,0xF8,0x20,0xF8,0xF8,0x20,0x00,  // -#-
        0x02,0x0F,0x0F,0x02,0x0F,0x0F,0x02,0x00,

        0x38,0x7C,0x44,0x47,0x47,0xCC,0x98,0x00,  // -$-
        0x03,0x06,0x04,0x1C,0x1C,0x07,0x03,0x00,

        0x30,0x30,0x00,0x80,0xC0,0x60,0x30,0x00,  // -%-
        0x0C,0x06,0x03,0x01,0x00,0x0C,0x0C,0x00,

        0x80,0xD8,0x7C,0xE4,0xBC,0xD8,0x40,0x00,  // -&-
        0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00,

        0x00,0x10,0x1E,0x0E,0x00,0x00,0x00,0x00,  // -'-
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

        0x00,0x00,0xF0,0xF8,0x0C,0x04,0x00,0x00,  // -(-
        0x00,0x00,0x03,0x07,0x0C,0x08,0x00,0x00,

        0x00,0x00,0x04,0x0C,0xF8,0xF0,0x00,0x00,  // -)-
        0x00,0x00,0x08,0x0C,0x07,0x03,0x00,0x00,

        0x80,0xA0,0xE0,0xC0,0xC0,0xE0,0xA0,0x80,  // -*-
        0x00,0x02,0x03,0x01,0x01,0x03,0x02,0x00,

        0x00,0x80,0x80,0xE0,0xE0,0x80,0x80,0x00,  // -+-
        0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00,

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  // -,-
        0x00,0x00,0x10,0x1E,0x0E,0x00,0x00,0x00,

        0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,  // ---
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  // -.-
        0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,

        0x00,0x00,0x00,0x80,0xC0,0x60,0x30,0x00,  // -/-
        0x0C,0x06,0x03,0x01,0x00,0x00,0x00,0x00,

        0xF8,0xFC,0x04,0xC4,0x24,0xFC,0xF8,0x00,  // -0-
        0x07,0x0F,0x09,0x08,0x08,0x0F,0x07,0x00,

        0x00,0x10,0x18,0xFC,0xFC,0x00,0x00,0x00,  // -1-
        0x00,0x08,0x08,0x0F,0x0F,0x08,0x08,0x00,

        0x08,0x0C,0x84,0xC4,0x64,0x3C,0x18,0x00,  // -2-
        0x0E,0x0F,0x09,0x08,0x08,0x0C,0x0C,0x00,

        0x08,0x0C,0x44,0x44,0x44,0xFC,0xB8,0x00,  // -3-
        0x04,0x0C,0x08,0x08,0x08,0x0F,0x07,0x00,

        0xC0,0xE0,0xB0,0x98,0xFC,0xFC,0x80,0x00,  // -4-
        0x00,0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,

        0x7C,0x7C,0x44,0x44,0xC4,0xC4,0x84,0x00,  // -5-
        0x04,0x0C,0x08,0x08,0x08,0x0F,0x07,0x00,

        0xF0,0xF8,0x4C,0x44,0x44,0xC0,0x80,0x00,  // -6-
        0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,

        0x0C,0x0C,0x04,0x84,0xC4,0x7C,0x3C,0x00,  // -7-
        0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,

        0xB8,0xFC,0x44,0x44,0x44,0xFC,0xB8,0x00,  // -8-
        0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,

        0x38,0x7C,0x44,0x44,0x44,0xFC,0xF8,0x00,  // -9-
        0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00,

        0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,  // -:-
        0x00,0x00,0x00,0x06,0x06,0x00,0x00,0x00,

        0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,  // -;-
        0x00,0x00,0x08,0x0E,0x06,0x00,0x00,0x00,

        0x00,0x80,0xC0,0x60,0x30,0x18,0x08,0x00,  // -<-
        0x00,0x00,0x01,0x03,0x06,0x0C,0x08,0x00,

        0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,  // -=-
        0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,

        0x00,0x08,0x18,0x30,0x60,0xC0,0x80,0x00,  // ->-
        0x00,0x08,0x0C,0x06,0x03,0x01,0x00,0x00,

        0x18,0x1C,0x04,0xC4,0xE4,0x3C,0x18,0x00,  // -?-
        0x00,0x00,0x00,0x0D,0x0D,0x00,0x00,0x00,

        0xF0,0xF8,0x08,0xC8,0xC8,0xF8,0xF0,0x00,  // -@-
        0x07,0x0F,0x08,0x0B,0x0B,0x0B,0x01,0x00,

        0xE0,0xF0,0x98,0x8C,0x98,0xF0,0xE0,0x00,  // -A-
        0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00,

        0x04,0xFC,0xFC,0x44,0x44,0xFC,0xB8,0x00,  // -B-
        0x08,0x0F,0x0F,0x08,0x08,0x0F,0x07,0x00,

        0xF0,0xF8,0x0C,0x04,0x04,0x0C,0x18,0x00,  // -C-
        0x03,0x07,0x0C,0x08,0x08,0x0C,0x06,0x00,

        0x04,0xFC,0xFC,0x04,0x0C,0xF8,0xF0,0x00,  // -D-
        0x08,0x0F,0x0F,0x08,0x0C,0x07,0x03,0x00,

        0x04,0xFC,0xFC,0x44,0xE4,0x0C,0x1C,0x00,  // -E-
        0x08,0x0F,0x0F,0x08,0x08,0x0C,0x0E,0x00,

        0x04,0xFC,0xFC,0x44,0xE4,0x0C,0x1C,0x00,  // -F-
        0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00,

        0xF0,0xF8,0x0C,0x84,0x84,0x8C,0x98,0x00,  // -G-
        0x03,0x07,0x0C,0x08,0x08,0x07,0x0F,0x00,

        0xFC,0xFC,0x40,0x40,0x40,0xFC,0xFC,0x00,  // -H-
        0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00,

        0x00,0x00,0x04,0xFC,0xFC,0x04,0x00,0x00,  // -I-
        0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

        0x00,0x00,0x00,0x04,0xFC,0xFC,0x04,0x00,  // -J-
        0x07,0x0F,0x08,0x08,0x0F,0x07,0x00,0x00,

        0x04,0xFC,0xFC,0xC0,0xF0,0x3C,0x0C,0x00,  // -K-
        0x08,0x0F,0x0F,0x00,0x01,0x0F,0x0E,0x00,

        0x04,0xFC,0xFC,0x04,0x00,0x00,0x00,0x00,  // -L-
        0x08,0x0F,0x0F,0x08,0x08,0x0C,0x0E,0x00,

        0xFC,0xFC,0x38,0x70,0x38,0xFC,0xFC,0x00,  // -M-
        0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00,

        0xFC,0xFC,0x38,0x70,0xE0,0xFC,0xFC,0x00,  // -N-
        0x0F,0x0F,0x00,0x00,0x00,0x0F,0x0F,0x00,

        0xF0,0xF8,0x0C,0x04,0x0C,0xF8,0xF0,0x00,  // -O-
        0x03,0x07,0x0C,0x08,0x0C,0x07,0x03,0x00,

        0x04,0xFC,0xFC,0x44,0x44,0x7C,0x38,0x00,  // -P-
        0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00,

        0xF8,0xFC,0x04,0x04,0x04,0xFC,0xF8,0x00,  // -Q-
        0x07,0x0F,0x08,0x0E,0x3C,0x3F,0x27,0x00,

        0x04,0xFC,0xFC,0x44,0xC4,0xFC,0x38,0x00,  // -R-
        0x08,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00,

        0x18,0x3C,0x64,0x44,0xC4,0x9C,0x18,0x00,  // -S-
        0x06,0x0E,0x08,0x08,0x08,0x0F,0x07,0x00,

        0x00,0x1C,0x0C,0xFC,0xFC,0x0C,0x1C,0x00,  // -T-
        0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

        0xFC,0xFC,0x00,0x00,0x00,0xFC,0xFC,0x00,  // -U-
        0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,

        0xFC,0xFC,0x00,0x00,0x00,0xFC,0xFC,0x00,  // -V-
        0x01,0x03,0x06,0x0C,0x06,0x03,0x01,0x00,

        0xFC,0xFC,0x00,0x80,0x00,0xFC,0xFC,0x00,  // -W-
        0x03,0x0F,0x0E,0x03,0x0E,0x0F,0x03,0x00,

        0x0C,0x3C,0xF0,0xC0,0xF0,0x3C,0x0C,0x00,  // -X-
        0x0C,0x0F,0x03,0x00,0x03,0x0F,0x0C,0x00,

        0x00,0x3C,0x7C,0xC0,0xC0,0x7C,0x3C,0x00,  // -Y-
        0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

        0x1C,0x0C,0x84,0xC4,0x64,0x3C,0x1C,0x00,  // -Z-
        0x0E,0x0F,0x09,0x08,0x08,0x0C,0x0E,0x00,

        0x00,0x00,0xFC,0xFC,0x04,0x04,0x00,0x00,  // -[-
        0x00,0x00,0x0F,0x0F,0x08,0x08,0x00,0x00,

        0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,  // -\-
        0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x00,

        0x00,0x00,0x04,0x04,0xFC,0xFC,0x00,0x00,  // -]-
        0x00,0x00,0x08,0x08,0x0F,0x0F,0x00,0x00,

        0x08,0x0C,0x06,0x03,0x06,0x0C,0x08,0x00,  // -^-
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  // -_-
        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

        0x00,0x00,0x03,0x07,0x04,0x00,0x00,0x00,  // -`-
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

        0x00,0xA0,0xA0,0xA0,0xE0,0xC0,0x00,0x00,  // -a-
        0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00,

        0x04,0xFC,0xFC,0x20,0x60,0xC0,0x80,0x00,  // -b-
        0x08,0x0F,0x07,0x08,0x08,0x0F,0x07,0x00,

        0xC0,0xE0,0x20,0x20,0x20,0x60,0x40,0x00,  // -c-
        0x07,0x0F,0x08,0x08,0x08,0x0C,0x04,0x00,

        0x80,0xC0,0x60,0x24,0xFC,0xFC,0x00,0x00,  // -d-
        0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00,

        0xC0,0xE0,0xA0,0xA0,0xA0,0xE0,0xC0,0x00,  // -e-
        0x07,0x0F,0x08,0x08,0x08,0x0C,0x04,0x00,

        0x40,0xF8,0xFC,0x44,0x0C,0x18,0x00,0x00,  // -f-
        0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00,

        0xC0,0xE0,0x20,0x20,0xC0,0xE0,0x20,0x00,  // -g-
        0x27,0x6F,0x48,0x48,0x7F,0x3F,0x00,0x00,

        0x04,0xFC,0xFC,0x40,0x20,0xE0,0xC0,0x00,  // -h-
        0x08,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00,

        0x00,0x00,0x20,0xEC,0xEC,0x00,0x00,0x00,  // -i-
        0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

        0x00,0x00,0x00,0x00,0x20,0xEC,0xEC,0x00,  // -j-
        0x00,0x30,0x70,0x40,0x40,0x7F,0x3F,0x00,

        0x04,0xFC,0xFC,0x80,0xC0,0x60,0x20,0x00,  // -k-
        0x08,0x0F,0x0F,0x01,0x03,0x0E,0x0C,0x00,

        0x00,0x00,0x04,0xFC,0xFC,0x00,0x00,0x00,  // -l-
        0x00,0x00,0x08,0x0F,0x0F,0x08,0x00,0x00,

        0xE0,0xE0,0x60,0xC0,0x60,0xE0,0xC0,0x00,  // -m-
        0x0F,0x0F,0x00,0x0F,0x00,0x0F,0x0F,0x00,

        0x20,0xE0,0xC0,0x20,0x20,0xE0,0xC0,0x00,  // -n-
        0x00,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x00,

        0xC0,0xE0,0x20,0x20,0x20,0xE0,0xC0,0x00,  // -o-
        0x07,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,

        0x20,0xE0,0xC0,0x20,0x20,0xE0,0xC0,0x00,  // -p-
        0x40,0x7F,0x7F,0x48,0x08,0x0F,0x07,0x00,

        0xC0,0xE0,0x20,0x20,0xC0,0xE0,0x20,0x00,  // -q-
        0x07,0x0F,0x08,0x48,0x7F,0x7F,0x40,0x00,

        0x20,0xE0,0xC0,0x60,0x20,0x60,0xC0,0x00,  // -r-
        0x08,0x0F,0x0F,0x08,0x00,0x00,0x00,0x00,

        0x40,0xE0,0xA0,0x20,0x20,0x60,0x40,0x00,  // -s-
        0x04,0x0C,0x09,0x09,0x0B,0x0E,0x04,0x00,

        0x20,0x20,0xF8,0xFC,0x20,0x20,0x00,0x00,  // -t-
        0x00,0x00,0x07,0x0F,0x08,0x0C,0x04,0x00,

        0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,  // -u-
        0x07,0x0F,0x08,0x08,0x07,0x0F,0x08,0x00,

        0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,  // -v-
        0x00,0x03,0x07,0x0C,0x0C,0x07,0x03,0x00,

        0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00,  // -w-
        0x07,0x0F,0x0C,0x07,0x0C,0x0F,0x07,0x00,

        0x20,0x60,0xC0,0x80,0xC0,0x60,0x20,0x00,  // -x-
        0x08,0x0C,0x07,0x03,0x07,0x0C,0x08,0x00,

        0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00,  // -y-
        0x47,0x4F,0x48,0x48,0x68,0x3F,0x1F,0x00,

        0x60,0x60,0x20,0xA0,0xE0,0x60,0x20,0x00,  // -z-
        0x0C,0x0E,0x0B,0x09,0x08,0x0C,0x0C,0x00,

        0x00,0x40,0x40,0xF8,0xBC,0x04,0x04,0x00,  // -{-
        0x00,0x00,0x00,0x07,0x0F,0x08,0x08,0x00,

        0x00,0x00,0x00,0xBC,0xBC,0x00,0x00,0x00,  // -|-
        0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,

        0x00,0x04,0x04,0xBC,0xF8,0x40,0x40,0x00,  // -}-
        0x00,0x08,0x08,0x0F,0x07,0x00,0x00,0x00,

        0x08,0x0C,0x04,0x0C,0x08,0x0C,0x04,0x00,  // -~-
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

        0x80,0xC0,0x60,0x30,0x60,0xC0,0x80,0x00,  // --
        0x07,0x07,0x04,0x04,0x04,0x07,0x07,0x00,
};


// ------------------  汉字字模的数据结构定义 ------------------------ //
typedef struct typFNT_GB16                 // 汉字字模数据结构
{
       uchar Index[2];               // 汉字内码索引
       uchar Msk[32];                       // 点阵码数据
};

/////////////////////////////////////////////////////////////////////////
// 汉字字模表                                                          //
// 汉字库: 宋体16.dot 纵向取模下高位,数据排列:从左到右从上到下         //
/////////////////////////////////////////////////////////////////////////
struct typFNT_GB16 code GB_16[] =          // 数据表
{
"北", 0x00,0x20,0x20,0x20,0x20,0xFF,0x00,0x00,0xFF,0x20,0x10,0x08,0x0C,0x00,0x00,0x00,
      0x20,0x60,0x20,0x10,0x10,0x7F,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x70,0x00,

"方", 0x10,0x10,0x10,0x10,0x10,0xF1,0x92,0x96,0x90,0x90,0x90,0xD0,0x90,0x18,0x10,0x00,
      0x00,0x80,0x40,0x20,0x18,0x07,0x00,0x00,0x40,0x80,0x40,0x3F,0x00,0x00,0x00,0x00,

"工", 0x00,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x06,0x04,0x00,0x00,
      0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x00,

"业", 0x00,0x10,0x60,0x80,0x00,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0xC0,0x30,0x00,0x00,
      0x40,0x40,0x40,0x47,0x40,0x7F,0x40,0x40,0x40,0x7F,0x44,0x43,0x40,0x60,0x40,0x00,

"大", 0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x7F,0xA0,0x20,0x20,0x20,0x20,0x30,0x20,0x00,
      0x00,0x40,0x40,0x20,0x10,0x0C,0x03,0x00,0x01,0x06,0x08,0x10,0x20,0x60,0x20,0x00,

"学", 0x40,0x30,0x11,0x96,0x90,0x90,0x91,0x96,0x90,0x90,0x98,0x14,0x13,0x50,0x30,0x00,
      0x04,0x04,0x04,0x04,0x04,0x44,0x84,0x7E,0x06,0x05,0x04,0x04,0x04,0x06,0x04,0x00,

"信", 0x80,0x40,0x20,0xF8,0x07,0x24,0x24,0x24,0x25,0x26,0x24,0x24,0xB4,0x26,0x04,0x00,
      0x00,0x00,0x00,0xFF,0x00,0x01,0xFD,0x45,0x45,0x45,0x45,0x45,0xFD,0x01,0x00,0x00,

"研", 0x82,0x42,0xF2,0x4E,0x43,0xC2,0x80,0x82,0xFE,0x82,0x82,0x82,0xFF,0x82,0x80,0x00,
      0x00,0x00,0x3F,0x10,0x10,0x5F,0x20,0x18,0x07,0x00,0x00,0x00,0xFF,0x00,0x00,0x0

"刚", 0x00,0xFE,0x32,0xC2,0x02,0xC2,0x32,0xFF,0x02,0x00,0xF8,0x00,0x00,0xFF,0x00,0x00,
      0x00,0xFF,0x08,0x06,0x01,0x42,0x8C,0x7F,0x00,0x00,0x0F,0x40,0x80,0x7F,0x00,0x00,

"电", 0x00,0xF8,0x48,0x48,0x48,0x48,0xFF,0x48,0x48,0x48,0x48,0xFC,0x08,0x00,0x00,0x00,
      0x00,0x07,0x02,0x02,0x02,0x02,0x3F,0x42,0x42,0x42,0x42,0x47,0x40,0x70,0x00,0x00,

"话", 0x40,0x42,0x44,0xCC,0x00,0x40,0x44,0x44,0x44,0xFC,0x42,0x43,0x42,0x60,0x40,0x00,
      0x00,0x00,0x00,0x7F,0x20,0x10,0xFE,0x42,0x42,0x43,0x42,0x42,0xFF,0x02,0x00,0x00,

"贪", 0x20,0x20,0x10,0x90,0x88,0x94,0x96,0x99,0xD2,0xB4,0x88,0xC8,0x90,0x30,0x10,0x00,
      0x00,0x00,0x80,0x9F,0x40,0x20,0x10,0x0E,0x20,0x20,0x40,0x5F,0x80,0x00,0x00,0x00,

"吃", 0x00,0xFC,0x04,0x04,0xFE,0x44,0x20,0x50,0x4F,0x48,0x48,0xC8,0x4C,0x08,0x00,0x00,
      0x00,0x1F,0x08,0x08,0x1F,0x00,0x30,0x48,0x44,0x42,0x41,0x40,0x40,0x40,0x70,0x00,

"蛇", 0x00,0xF0,0x10,0xFF,0x10,0xF0,0x20,0x18,0xC8,0x09,0x0E,0x08,0x88,0x28,0x18,0x00,
      0x20,0x67,0x22,0x1F,0x12,0x3B,0x00,0x00,0x3F,0x44,0x42,0x41,0x41,0x40,0x70,0x00,

"游", 0x10,0x22,0x6C,0x00,0x08,0x08,0xF9,0x4A,0xC8,0x18,0x28,0x27,0xA4,0x66,0x24,0x00,
      0x04,0x04,0xFE,0x41,0x20,0x18,0x07,0x40,0x7F,0x02,0x42,0x82,0x7F,0x02,0x02,0x00,

"戏", 0x00,0x14,0x24,0xC4,0x04,0xE4,0x1C,0x10,0x10,0xFF,0x10,0x12,0x14,0xD0,0x10,0x00,
      0x20,0x10,0x08,0x06,0x01,0x02,0x8C,0x40,0x20,0x17,0x18,0x24,0x43,0x80,0xE0,0x00,

"退", 0x40,0x42,0x44,0xCC,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0xFF,0x40,0x00,0x00,
      0x00,0x40,0x20,0x1F,0x20,0x40,0x9F,0x88,0x85,0x81,0x82,0x85,0x88,0xD8,0x40,0x00,

"出", 0x00,0x00,0xFC,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0xFC,0x00,0x00,0x00,
      0x00,0xFE,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0xFE,0x00,0x00,

"任", 0x80,0x40,0x20,0xF8,0x87,0x80,0x84,0x84,0x84,0xFC,0x84,0x82,0x82,0xC0,0x80,0x00,
      0x00,0x00,0x00,0xFF,0x00,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x30,0x20,0x00,0x00,

"意", 0x10,0x10,0x12,0xD2,0x56,0x5A,0x52,0x53,0x52,0x5A,0x56,0xF3,0x52,0x18,0x10,0x00,
      0x40,0x30,0x00,0x77,0x85,0x85,0x8D,0x95,0xB5,0x85,0x85,0xE7,0x00,0x10,0x60,0x00,

"键", 0x10,0x28,0xE7,0x24,0x24,0xC2,0xB2,0x8E,0x10,0x54,0x54,0xFF,0x54,0x7C,0x10,0x00,
      0x01,0x01,0x7F,0x21,0x51,0x24,0x18,0x27,0x48,0x89,0x89,0xFF,0x89,0xCD,0x48,0x00,

"进", 0x40,0x42,0xCC,0x00,0x08,0x08,0xFF,0x08,0x08,0x08,0xFF,0x08,0x8C,0x08,0x00,0x00,
      0x40,0x20,0x1F,0x20,0x41,0x51,0x4F,0x41,0x41,0x41,0x7F,0x41,0x41,0x61,0x20,0x00,

"入", 0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0x1C,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x03,0x0C,0x30,0x40,0xC0,0x40,0x00,

"分", 0x00,0x80,0x40,0x20,0x98,0x86,0x80,0x80,0x83,0x8C,0x90,0x20,0xC0,0x80,0x80,0x00,
      0x01,0x00,0x80,0x40,0x20,0x1F,0x00,0x40,0x80,0x40,0x3F,0x00,0x00,0x01,0x00,0x00,

"数", 0x10,0x92,0x54,0x30,0xFF,0x50,0x94,0x32,0xD8,0x17,0x10,0x10,0xF0,0x18,0x10,0x00,
      0x02,0x82,0x4E,0x33,0x22,0x52,0x8E,0x40,0x23,0x14,0x08,0x16,0x61,0xC0,0x40,0x00,

"为", 0x20,0x20,0x20,0x22,0x24,0x2C,0x20,0xE0,0x3F,0x20,0x20,0x20,0x20,0xF0,0x20,0x00,
      0x00,0x40,0x20,0x10,0x08,0x04,0x03,0x00,0x02,0x04,0x4C,0x80,0x40,0x3F,0x00,0x00,

"回", 0x00,0xFC,0x04,0x04,0x04,0xE4,0x24,0x24,0x24,0xF4,0x24,0x04,0x04,0xFE,0x04,0x00,
      0x00,0x7F,0x20,0x20,0x20,0x2F,0x24,0x24,0x24,0x2F,0x20,0x20,0x20,0x7F,0x00,0x00,

"车", 0x00,0x04,0xC4,0xA4,0x94,0x8C,0x87,0xF4,0x84,0x84,0xC4,0x84,0x06,0x04,0x00,0x00,
      0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x06,0x04,0x00,

"继", 0x20,0x30,0xAC,0x63,0x30,0x00,0xFE,0x88,0x90,0xA0,0xFF,0xA0,0x90,0x98,0x00,0x00,
      0x22,0x67,0x22,0x12,0x12,0x00,0x7F,0x48,0x44,0x42,0x7F,0x42,0x44,0x6C,0x40,0x00,

"续", 0x20,0x30,0xAC,0x63,0x30,0x20,0x24,0x64,0xA4,0x3F,0xE4,0x26,0xA4,0x60,0x00,0x00,
      0x22,0x63,0x22,0x12,0x12,0x14,0x85,0x46,0x24,0x1C,0x17,0x24,0x44,0xC6,0x04,0x00

};

// 汉字表:
void LCM_busy(uchar lr)//LCM判断忙,lr=0表示左屏,1为右屏,以下类同
{        
        uchar tempdata;
        if(lr==0)
        {
                tempdata=CS1RS;
                while(tempdata&BUSY_STATUS );
        }
        else 
                
        {
                tempdata=CS2RS;
                while(tempdata&BUSY_STATUS );
        }
                
}
void LCMWC(uchar lr,uchar com)
{
        LCM_busy(lr);
        if(lr==0)
        {         
                CS1WC=com;
        }
        else
        {
                CS2WC=com;
        }
}
void LCMWD(uchar lr,uchar dat)
{
                 LCM_busy(lr);
        if(lr==0)
        {        
                CS1WD=dat;
        }
        else
        {        
                CS2WD=dat;
        }
}
uchar LCMRD(uchar lr)
{
        uchar tempdata;
        LCM_busy(lr);
        if(lr==0)
        {        
                
        //        tempdata=CS1RD;
        //        LCM_busy(lr);
                tempdata=CS1RD;
        }
        else
        {         
                
        //        tempdata=CS2RD;
         //   LCM_busy(lr);
                tempdata=CS2RD;
        }
        return(tempdata);
}
void LCM_init(void)
{
        LCMWC(LEFT,0xc0);
        LCMWC(LEFT,DISP_ON);
        LCMWC(RIGHT,0xc0);
        LCMWC(RIGHT,DISP_ON);
}                        
void LCM_clr(void)
{
        uchar page,i;
        for(page=0;page<8;page++)
        {
                LCMWC(LEFT,0xb8|page);
                LCMWC(RIGHT,0xb8|page);
                for(i=0;i<64;i++)
                {
                        LCMWC(LEFT,0x40|i);
                        LCMWD(LEFT,0x0);
                        LCMWC(RIGHT,0x40|i);
                        LCMWD(RIGHT,0x0);
                }
        }
}
void putchar_l(uchar c)
{
        LCMWD(LEFT,c);
}
void putchar_r(uchar c)
{
        LCMWD(RIGHT,c);
}







/*******************************************************************************************/
        
void draw_bmp(uchar col,uchar layer,uchar width,uchar *bmp)
{
        uchar x;
        uchar address;
        uchar p=0;
        uchar page=0;
        uchar window=0;
         if(layer==1) page=0;
         if(layer==2) page=2;
         if(layer==3) page=4;
         if(layer==4) page=6;

        for(x=col;x<col+width;x++)
        {
                if(x>128) return;  //超过边界
                if(x>64)
                {
                        window=1;           //window=1表示在右屏
                        address=x%64;
                }
                else
                        address=x;

                        LCMWC(LEFT,page|0xb8);          //设置显示位置上半个字
                        LCMWC(LEFT,address|0x40);
                         LCMWC(RIGHT,page|0xb8);
                        LCMWC(RIGHT,address|0x40);


                        if(window)
                                putchar_r(bmp[p]);
                         else
                                 putchar_l(bmp[p]);


                        LCMWC(LEFT,(page+1)|0xb8);//下半个字
                        LCMWC(LEFT,address|0x40);
                         LCMWC(RIGHT,(page+1)|0xb8);
                        LCMWC(RIGHT,address|0x40);

                        if(window)
                                putchar_r(bmp[p+width]);
                        else
                                putchar_l(bmp[p+width]);
                                
                        p++;
                }
}
/*****************************************************************************************************/
void disp_one_ascii(uchar col,uchar layer,uchar ascii_code,uchar mode) //8*16ASCII显示
{
        uchar i;
        for(i=0;i<16;i++)
        {
                if(mode) dot_buffer=~nAsciiDot[(ascii_code-0x20)*16+i];//前面20个是控制符,没有用到
                else     dot_buffer=nAsciiDot[(ascii_code-0x20)*16+i]; //mode=1表示反显,以下类同
        }
        draw_bmp(col,layer,8,dot_buffer);
}
/*************************************************************************************/
void disp_ram_data(uchar col,uchar layer,uchar number,uchar mode)//显示数字,数字为ASCII+0x30
{       
             uchar i=0;
        

                if(mode) disp_one_ascii(col,layer,number+0x30,1);
                else     disp_one_ascii(col,layer,number+0x30,0);
        
        

        
}
/*************************************************************************************/
void dprintf(uchar col,uchar layer,uchar *ptr,uchar mode)//ASCII的汉字混合显示程序
{
        uchar c1,c2;
        uchar i,j,k;
        uchar ulen;
        uchar ucol,ulayer;
        ulen=0;
        ucol=col;
        ulayer=layer;
        i=0;
        while(ptr[ulen]!=0) ulen++;//判断字符串的长度

        while(i<ulen)
        {
                c1=ptr;
                c2=ptr[i+1];



                if(c1<=128)//字符和汉字的分界线
                {
                        if(mode) disp_one_ascii(ucol,ulayer,c1,1);
                        else     disp_one_ascii(ucol,ulayer,c1,0);
                        ucol+=8;
                        i++;
                }
                else
                {
                        for(j=0;j<sizeof(GB_16)/sizeof(GB_16[0]);j++)
                        {
                                if((c1==GB_16[j].Index[0])&&(c2==GB_16[j].Index[1]))//索引汉字
                                break;
                        }
                        for(k=0;k<32;k++)
                        {
                                if(mode) dot_buffer[k]=~GB_16[j].Msk[k];
                                else          dot_buffer[k]=GB_16[j].Msk[k];
                        }
                        draw_bmp(ucol,ulayer,16,dot_buffer);
                        ucol+=16;
                        i+=2;
                        }
                }
        }

/**************************************************************************************************/
/******************************************************
*        游戏LCD部分,根据游戏的特点把LCD分成16*16块
*        用作游戏点阵,这部分来源于网络,作了一下修改
*******************************************************/

//
//函数名:clr_game_dot
//功能:清一个游戏点
//输入参数:游戏点的X,Y坐标
//注意事项:这里的X,Y坐标和LCD底层的X,Y坐标不同,他最大只能是MAX_GAME_X,MAX_GAME_Y
//使用方式:内部调用
void clr_game_dot(uchar x,uchar y)
{
         uchar lcd_x,i,tmp;
         
        while(x>MAX_GAME_X)x-=(MAX_GAME_X+1);        //这个是写程序习惯的保护措施,预防输入范围过大
        while(y>MAX_GAME_Y)y-=(MAX_GAME_Y+1);
        lcd_x=x<<2;
        LCMWC(LEFT,0xc0);
        LCMWC(LEFT,0xb8|(y/2));
    LCMWC(LEFT,lcd_x|0x40);
        
        LCMWC(LEFT,0x3e);//关显示
if(y%2)//行的下半部
        {
                for(i=0;i<4;i++)
                {
#ifdef lcd_no_read                                //以下是显存法的清点程序,其他例如亮点的部分和这个原理一样
        
                        tmp=lcd_buf[y>>1][(x<<2)+i];                        //先从缓冲读出要修改的LCD片的数据
                        tmp&=0xf0;                                                        //清对应的游戏点
                        LCMWD(LEFT,tmp);
                        _nop_();
                        lcd_buf[y>>1][(x<<2)+i]=tmp;                        //把新数据写回缓冲
#else
                tmp=LCMRD(LEFT);
                tmp=LCMRD(LEFT);                                        //读LCD的方法,要求连读2次
                LCMWD(LEFT,tmp&0xf0);

#endif
                }
        }
        else                        //行的上半部,下同
        {
                for(i=0;i<4;i++)
                {
#ifdef lcd_no_read
                
                
                        tmp=lcd_buf[y>>1][(x<<2)+i];                        //先从缓冲读出要修改的LCD片的数据
                        tmp&=0x0f;                                                        //清对应的游戏点
                        LCMWD(LEFT,tmp);
                        _nop_();
                        lcd_buf[y>>1][(x<<2)+i]=tmp;                        //把新数据写回缓冲
#else
                tmp=LCMRD(LEFT);
                tmp=LCMRD(LEFT);                                        //读LCD的方法,要求连读2次
                LCMWD(LEFT,tmp&0x0f);
#endif
                }
        }
        LCMWC(LEFT,0x3f);
}
//函数名:fill_game_dot
//功能:亮一个游戏点
//输入参数:游戏坐标的X,Y坐标                                
//注意事项:这里的X,Y坐标和LCD底层的X,Y坐标不同,他最大只能是MAX_GAME_X,MAX_GAME_Y
//           这个函数和上面的clr_game_dot基本相同,只是在写LCD数据的时候是全1而不是0        
//使用方式:内部调用
void fill_game_dot(uchar x,uchar y)
{
         uchar lcd_x,i,tmp;
        while(x>MAX_GAME_X)x-=(MAX_GAME_X+1);        //这个是写程序习惯的保护措施,预防输入范围过大
        while(y>MAX_GAME_Y)y-=(MAX_GAME_Y+1);
        lcd_x=x<<2;
        LCMWC(LEFT,0xc0);
        LCMWC(LEFT,0xb8|(y/2));
    LCMWC(LEFT,lcd_x|0x40);
        
        LCMWC(LEFT,0x3e);
if(y%2)//行的下半部
        {
                for(i=0;i<4;i++)
                {
#ifdef lcd_no_read                                //以下是显存法的清点程序,其他例如亮点的部分和这个原理一样
        
                        tmp=lcd_buf[y>>1][(x<<2)+i];                        //先从缓冲读出要修改的LCD片的数据
                        tmp|=0x0f;                                                        //清对应的游戏点
                        LCMWD(LEFT,tmp);
                        _nop_();
                        lcd_buf[y>>1][(x<<2)+i]=tmp;                        //把新数据写回缓冲
#else
                tmp=LCMRD(LEFT);
                tmp=LCMRD(LEFT);                                        //读LCD的方法,要求连读2次
                LCMWD(LEFT,tmp|0x0f);

#endif
                }
        }
        else                        //行的上半部,下同
        {
                for(i=0;i<4;i++)
                {
#ifdef lcd_no_read
                
                
                        tmp=lcd_buf[y>>1][(x<<2)+i];                        //先从缓冲读出要修改的LCD片的数据
                        tmp|=0xf0;                                                        //清对应的游戏点
                        LCMWD(LEFT,tmp);
                        _nop_();
                        lcd_buf[y>>1][(x<<2)+i]=tmp;                        //把新数据写回缓冲
#else
                tmp=LCMRD(LEFT);
                tmp=LCMRD(LEFT);                                        //读LCD的方法,要求连读2次
                LCMWD(LEFT,tmp|0xf0);
#endif
                }
        }
        LCMWC(LEFT,0x3f);
}
//函数名:fill_game_dot2
//功能:亮一个游戏点(另一种方式,这里用来显示食物用)
//输入参数:X,Y
//注意事项:X,Y为游戏的点阵,非LCD点阵...还有LCD填充数据是0x05或0x50
//使用方式:内部调用,显示蛇的食物的时候用这个函数,区分开蛇身和食物.
void fill_game_dot2(uchar x,uchar y)
{
         uchar lcd_x,i,tmp;
        while(x>MAX_GAME_X)x-=(MAX_GAME_X+1);        //这个是写程序习惯的保护措施,预防输入范围过大
        while(y>MAX_GAME_Y)y-=(MAX_GAME_Y+1);
        lcd_x=x<<2;
         LCMWC(LEFT,0xc0);
        LCMWC(LEFT,0xb8|(y/2));
    LCMWC(LEFT,lcd_x|0x40);
        LCMWC(LEFT,0x3e);
        if(y%2)//行的下半部
        {
                for(i=0;i<4;i++)
                {
#ifdef lcd_no_read                                //以下是显存法的清点程序,其他例如亮点的部分和这个原理一样
        
                        tmp=lcd_buf[y>>1][(x<<2)+i];                        //先从缓冲读出要修改的LCD片的数据
                        tmp|=0x05;                                                        //清对应的游戏点
                        LCMWD(LEFT,tmp);
                        _nop_();
                        lcd_buf[y>>1][(x<<2)+i]=tmp;                        //把新数据写回缓冲
#else
                tmp=LCMRD(LEFT);
                tmp=LCMRD(LEFT);                                        //读LCD的方法,要求连读2次
                LCMWD(LEFT,tmp|0x05);

#endif
                }
        }
        else                        //行的上半部,下同
        {
                for(i=0;i<4;i++)
                {
#ifdef lcd_no_read
                
                
                        tmp=lcd_buf[y>>1][(x<<2)+i];                        //先从缓冲读出要修改的LCD片的数据
                        tmp|=0x50;                                                        //清对应的游戏点
                        LCMWD(LEFT,tmp);
                        _nop_();
                        lcd_buf[y>>1][(x<<2)+i]=tmp;                        //把新数据写回缓冲
#else
                tmp=LCMRD(LEFT);
                tmp=LCMRD(LEFT);                                        //读LCD的方法,要求连读2次
                LCMWD(LEFT,tmp|0x50);
#endif
                }
        }
        LCMWC(LEFT,0x3f);
}

/************************************************************
*
*                                        游戏算法部分(4*4LCD)
*
**************************************************************/

//函数名 game_init()
//功能:游戏开始的时候初始化画面的,这里只是简单地把132*64LCD用一条中间线划分开来
//注意事项:暂时在中间画条线用来划分游戏空间
//使用方式:内部调用,
void game_init()
{
         uchar i;
    LCM_clr();                                        
        LCM_init();
        //在64列画一条竖线当游戏的边界
        for(i=0;i<8;i++)
        {
                LCMWC(RIGHT,0xb8|i);
                LCMWC(RIGHT,0|0x40);
                LCMWC(RIGHT,0x3e);
                LCMWD(RIGHT,0xff);
        }
        LCMWC(RIGHT,0x3f);
}


//函数名:snake_init
//功能:蛇初始化
//注意事项:初始化只有3节蛇身,向右跑
//使用情况:内部调用
void snake_init()
{
        fill_game_dot(0,0);                //显示蛇身
        fill_game_dot(1,0);
        fill_game_dot(2,0);
        snake_len=2;
        snake_flag=0x10;                //蛇的初始化,3个身.向右跑
        snake_body[0]=0x02;                //装入射身数据
        snake_body[1]=0x01;
        snake_body[2]=0x00;

}

//函数名:show_mark
//功能:显示当前分数,暂时以蛇身个数为分数
//参数说明:0,和非0, 0代表游戏中的显示,!0代表挂了的显示
//注意事项:调用到LCD.c显示函数,并需要汉字库的支持.
//                        返回值在GAMEOVER时候有效,返回0退出游戏,1从新游戏                        
//使用情况:snake_run()在蛇吃到食物的时候调用,在GAMEOVER后调用
uchar show_mark(uchar mode)
{
         uchar ch;
        dprintf(66,1,"分",0);
        disp_ram_data(66,2,(snake_len-2),0);

        if(mode)//gameover中显示
        {        
                 dprintf(66,1,"分",0);
            disp_ram_data(65,2,len[1],0);
                disp_ram_data(67,2,len[2],0);
                dprintf(66,3,"C 退出",0);
                dprintf(66,4,"回车继续",0);
                do        ch=getkey();
                while((ch!=F1) && (ch!=F2) );                        //游戏结束了会在这里死等,直到用户按键
                if(ch==F2)
                        return(1);
                else 
                        return(0);
        }
        
        return(0);        

}

//函数名:snake_run
//功能:蛇运行函数
//输入参数:一个全局变量flag_snake,蛇根据这个变量判断运动方向
//注意事项:蛇跑动函数,用于判断路径,食物,长大,死亡
//使用情况:内部调用
void snake_run()
{
         uchar tmp_head_x,tmp_head_y;
         uchar i;
        switch(snake_flag&0xf0)                //取蛇头方向
                {
                case 0x80://向上走 y--
                                        
                                        tmp_head_y=(snake_body[0]>>4);
                                        tmp_head_x=snake_body[0]&0x0f;                                                
                                        if(tmp_head_y==0)snake_flag|=0x04;//这个代表撞墙了,就置GAMEOVER标志,下同
                                        else tmp_head_y--;
                                        break;
                case 0x40://向下走 y++
                                        
                                        tmp_head_y=(snake_body[0]>>4);
                                         tmp_head_x=snake_body[0]&0x0f;
                                        if(tmp_head_y==MAX_GAME_Y)snake_flag|=0x04;
                                        else tmp_head_y++;
                                        
                                        break;
                case 0x20://向左走 x--
                                        tmp_head_y=(snake_body[0]>>4);
                                        tmp_head_x=snake_body[0]&0x0f;
                                        if(tmp_head_x==0)snake_flag|=0x04;
                                        else tmp_head_x--;
                                        break;
                case 0x10://向右走 x++                                                
                                        tmp_head_y=(snake_body[0]>>4);
                                        tmp_head_x=snake_body[0]&0x0f;
                                        if(tmp_head_x==MAX_GAME_X)snake_flag|=0x04;
                                        else tmp_head_x++;
                                        break;
                default:break;
                }
                if(!(snake_flag&0x04))                        //如果在之前没有撞墙,就可以进行下一步判断
                {                        
                        //以下是得到食物的判断。

                        if(snake_food!=( (tmp_head_y<<4)+tmp_head_x ))//蛇头和食物坐标没重叠就代表没有吃到食物
                        {//得不到食物的处理
                                
                                clr_game_dot(snake_body[snake_len]&0x0f,snake_body[snake_len]>>4);//灭蛇尾巴
                        //        fill_game_dot(tmp_head_x,tmp_head_y);//显示新蛇头
                                for(i=snake_len;i>0;i--)                                                                                        //柔体传动
                                snake_body=snake_body[i-1];
                                snake_body[0]=( tmp_head_y<<4 ) + tmp_head_x;
                                
                                
                        }
                        else
                        {//得到食物的处理                        
                                snake_body[snake_len+1]=snake_body[snake_len];                                //保留蛇尾巴(这是增长型柔体传动)
                                for(i=snake_len;i>0;i--)
                                snake_body=snake_body[i-1];

                                snake_body[0]=( tmp_head_y<<4 ) + tmp_head_x;                                //新蛇头
                                snake_len++;//长度增加1
                                snake_flag&=~0x02;//清食物标志
                                show_mark(0);//显示分数
                        }        
                        
                        fill_game_dot(tmp_head_x,tmp_head_y);//显示新蛇头
                }
                for(i=1;i<snake_len+1;i++)                                                //判断是否撞中自己
                {
                        if(snake_body[0]==snake_body)                                
                        {
                                snake_flag|=0x04;                                                //撞中了就置GAMEOVER标志
                                break;
                        }
                }
}



//函数名:set_food
//功能:放食物
//注意事项:这个函数在被调用前会先判断是否需要放食物,
//                        这里用自己编写的随机数来产生食物,随机数和蛇身位置,定时器有关
//                        每次放食物的时候必须先判断是否和蛇身重叠了,重叠了要重新放
//                        这里设定了如果蛇长度达到某值了就不再放食物.
//影响变量:snake_food
//使用情况:内部调用
void set_food()
{
        
         uchar seed0,seed1,i=0;
        seed0=snake_body[snake_len-2];

        if(snake_len==100)
        {
           return;//蛇都快满屏了,就不放食物了,事实上我还没玩过超过100的呢
        }
        seed0=((seed1>>3)*4+seed0+TL0);//随机数的生成,其实乱做就可以了:)
        seed1=(snake_body[0]>>4)+seed0;
        snake_food=(seed1+seed0*3);
        while( (snake_food&0xf0)>0xf0)
        snake_food+=0x30;                                //Y位置不得超过15
        
        
food:        
        for(i=0;i<snake_len+1;i++)        //食物不能和蛇身重叠
        {
                if( snake_body==snake_food )
                {
                
                        snake_food=(snake_food+0x01);                //如果重叠了,位置就+1,然后
                        if((snake_food&0xf0)>0xf0)
                                snake_food&=0x0f;                                //Y方向只能到15,超过12就要回0
                        goto food;                                                        //重新比较,这里可以换成i=255,效果一样
                }
        }

        fill_game_dot2(snake_food&0x0f,snake_food>>4);//放食物
        snake_flag|=0x02;//置有食物标志
}

//        函数名:定时器1初始化程序
//        晶振22.1184,定时时间35MS
void snake_init_timer0(void)
{
        TMOD=0x01;
        TH0=(65536-35000)/256;
        TL0=(65536-35000)%256;
}




//函数名:snake_game
//功能:整个游戏的主要函数
//注意事项:游戏利用了定时器产生蛇的运行速速度
//                        调用前应该先初始化定时器
//使用情况:外部调用
//

                        //这个东东是使定时器公用的。
void snakegame()
{
         uchar tmp_snake_flag,ch;
        LCM_clr();
                                                        
        set_time=0;
        dprintf(0,2,"贪吃蛇游戏",0);
        dprintf(0,3,"C 退出",0);
        dprintf(0,4,"任意键进入",0);
        while((ch=getkey())==0);
        if(ch==F1)        return;
        ch=0;

                

begin_game:        
        game_init();        //一堆初始化
        snake_init();
        snake_init_timer0();//timer0_init();
        TR0=1;
        ET0=1;
        EA=1;
        
        tmp_snake_flag=snake_flag;
        while(1)
        {
                ch=getkey();
                switch(ch)
                {
                        case up://按了上按键
                                        if( (snake_flag&0x40) || (snake_flag&0x80) )break;//向上走的时候,上下键盘都无效,下同
                                        tmp_snake_flag&=0x0f;tmp_snake_flag|=0x80;
                                        break;
                        case down://按了下按键
                                        if( (snake_flag&0x80) || (snake_flag&0x40) )break;
                                        tmp_snake_flag&=0x0f;tmp_snake_flag|=0x40;
                                        break;
                        case left://按了左按键
                                        if( (snake_flag&0x10 || (snake_flag&0x20) ))break;
                                        tmp_snake_flag&=0x0f;tmp_snake_flag|=0x20;
                                        break;
                        case right://按了右按键
                                        if( (snake_flag&0x20 || (snake_flag&0x10) ))break;
                                        tmp_snake_flag&=0x0f;tmp_snake_flag|=0x10;
                                        break;
                        case F1://任何时候,按C就结束游戏
                                        
                                        return;
                        default:
                                        break;
                 }

                if(!(snake_flag&0x02))        //如果图上已经没食物了,就
                        set_food();                        //放食物        

                if((snake_flag&0x01))                                                                //判断是否够时间跑一步
                {
                        snake_flag=( snake_flag&0x0e ) | tmp_snake_flag;//取消跑动标志,置新方向
                        snake_run();
                        tmp_snake_flag=snake_flag;
                }
        
                if((snake_flag&0x04))                        //判断游戏结束标志
                {
                        if(show_mark(1))
                        {
                                snake_flag&=~0x04;
                                goto begin_game;
                        }
                        else 
                        {
                                
                                return;                                                //游戏结束                        
                        }
                        
                }                                                
        }
}

/*******************************************************************/
uchar getkey(void)
{
        uchar scode,recode;
        P1=0xf0;
        if((P1&0xf0)!=0xf0)
        dlms();
        if((P1&0xf0)!=0xf0)
        {
                scode=0xfe;
                while((scode&0x10)!=0)
                {P1=scode;
                 if((P1&0xf0)!=0xf0)
                 { recode=(P1&0xf0)|0x0f;
                   return((~scode)+(~recode));
                   }
                else 
                        scode=(scode<<1)|0x01;
                }
        }
        return(0);
}
/******************************************************************/
void dlms(void)
{
        uchar i;
        for(i=100;i>0;i--){}
}
/***********************************************************/
void time0(void) interrupt 1 using 1  //35ms定时蛇的心脏跳动

{
        TH0=(65536-35000)/256;
        TL0=(65536-35000)%256;
        set_time++;
        if(set_time==TIME_RUN)
        {set_time=0;
         snake_flag|=0x01;
         }

}
/**************************************************************************************************/
void delay(void)//长延时
{
        uint i,j;
        for(i=100;i>0;i--)
                for(j=1000;j>0;j--);
}


/***********************************************************************************************/
void main(void)
{ 
        uchar i;
        uint j;
        for(i=0;i<10;i++)for(j=1;j<100;j++);
        LCM_init();
        LCM_clr();
//         disp_ram_data(10,1,disp_buffer[2],0);
        dprintf(0,1,"我爱方案网",0);
        delay();                                                        
        dprintf(0,3,"momo",0);
          delay();
do{
snakegame();}while(1);
}

 



工程师
2015-05-05 16:36:51     打赏
2楼
MARK一下

菜鸟
2016-05-30 14:34:05     打赏
3楼
能有人告诉我protues图里都是用的什么元器件么?图片看不清啊!!

共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]