//贪吃蛇游戏程序,屏左半部用于游戏活动,右半部为分数显示
//游戏屏为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);
}
我要赚赏金
