📄 snake.h
字号:
/*------------------------------
SNAKE.H
-------------------------------*/
#ifndef _SNAKE_INCLUDED_
#define _SNAKE_INCLUDED_
#include<stdlib.h> //包含srand函数
#include <delay.h>
#include <string.h> //包含memset函数
#include "5110.h"
#define GAME_FIELD_HEIGHT 10
#define GAME_FIELD_WIDTH 21
#define SNAKE_GROUND 0
#define SNAKE_UP 1
#define SNAKE_RIGHT 2
#define SNAKE_DOWN 3
#define SNAKE_LEFT 4
#define SNAKE_FOOD 255
#define KEY_UP PIND.6
#define KEY_DOWN PIND.5
#define KEY_LEFT PINB.0
#define KEY_RIGHT PIND.7
#define KEY_QUIT PIND.0
#define TIMER 2
typedef struct SnakeBody //蛇身结构体
{
unsigned int x;
unsigned int y;
}SNAKE_BODY;
SNAKE_BODY SnakeHead = {0}; //蛇头
SNAKE_BODY SnakeTail = {0}; //蛇尾
unsigned char cDisplayRam[504] = {0}; //显示缓存6*84
unsigned char cGameField[GAME_FIELD_HEIGHT*GAME_FIELD_WIDTH] = {0}; //游戏地图
unsigned char keyCode = 0; //键值
unsigned char snakeHeadDir; //蛇头运动方向
unsigned char timerCnt = 0; //定时器累加变量
unsigned char snakeMoveFlag = 0; //蛇运动标志位
eeprom unsigned char topMark = 0;
flash unsigned char cBmpCode[160] = //snake图形
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xB8,0xB8,0xF8,
0xF0,0xE0,0x80,0x80,0x80,0x80,0x00,0xE0,0xF0,0x98,0x08,0x08,0xB8,0xB0,0x80,0x80,
0x80,0x00,0xF8,0xF8,0xF8,0xC0,0x00,0xF8,0xF8,0x00,0x80,0x80,0x00,0x00,0xE0,0xF8,
0xF8,0xF8,0x00,0x80,0x80,0x80,0x00,0xF8,0xF8,0x80,0xC0,0xF0,0x38,0x88,0x80,0x80,
0x00,0xF8,0xF8,0x08,0x08,0x08,0x08,0x00,0x80,0x00,0x00,0x00,0x80,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0F,0x1F,0x3F,
0x7F,0x77,0x77,0x7F,0x3F,0x1F,0x07,0x07,0x07,0x07,0x17,0x76,0x65,0x45,0x43,0x7E,
0x3E,0x01,0x0F,0x0F,0x07,0x78,0x7F,0x07,0x03,0x1F,0x7C,0x7F,0x07,0x08,0x0F,0x67,
0x78,0x1F,0x07,0x04,0x07,0x7F,0x7C,0x03,0x0F,0x07,0x78,0x7F,0x07,0x03,0x0F,0x7F,
0x70,0x0F,0x0F,0x07,0x78,0x7F,0x47,0x41,0x41,0x41,0x01,0x00,0x0F,0x07,0x03,0x03
};
void Timer0Initial(void);
void SnakeInitial(void);
unsigned int SnakeRand(unsigned int dRange);
void SnakePutFood(void);
void RefreshRam(unsigned char *pcBuff);
void DrawBox(unsigned int x, unsigned int y);
void ClearBox(unsigned int x, unsigned int y);
void SnakeOption(void);
unsigned char KeyScan(void);
void SnakeGame(void);
/*
*函数介绍:刷新显示缓存
*输入参数:缓存数组
*输出参数:无
*返回值: 无
*/
void RefreshRam(unsigned char *pcBuff)
{
unsigned int i;
WriteByte(0x80, 0);
WriteByte(0x40, 0);
WriteByte(0x80, 0);
for (i = 0; i < 504; i++)
{
WriteByte(*pcBuff++, 1);
}
}
/*
*函数介绍:画点块函数
*输入参数:画点块坐标
*输出参数:无
*返回值: 无
*/
void DrawBox(unsigned int x, unsigned int y)
{
unsigned char Temp = 0x0F; //方块为4*4点块
unsigned char offset;
offset = y * 4 % 8;
x = x * 4;
y = y * 4 / 8;
Temp <<= offset;
cDisplayRam[y*84+x] |= Temp;
cDisplayRam[y*84+x + 1] |= Temp;
cDisplayRam[y*84+x + 2] |= Temp;
cDisplayRam[y*84+x + 3] |= Temp;
RefreshRam(cDisplayRam);
}
/*
*函数介绍:清点块函数
*输入参数:清除点块坐标
*输出参数:无
*返回值: 无
*/
void ClearBox(unsigned int x, unsigned int y)
{
unsigned char Temp = 0x0F;
unsigned char offset;
offset = y * 4 % 8;
x = x * 4;
y = y * 4 / 8;
Temp <<= offset;
cDisplayRam[y*84+x] &= ~Temp; //取反清除
cDisplayRam[y*84+x + 1] &= ~Temp;
cDisplayRam[y*84+x + 2] &= ~Temp;
cDisplayRam[y*84+x + 3] &= ~Temp;
RefreshRam(cDisplayRam);
}
/*
*函数介绍:按键扫描函数
*输入参数:无
*输出参数:无
*返回值: 键值或255
*/
unsigned char KeyScan(void)
{
if(!KEY_UP)
{
delay_ms(TIMER);
if(!KEY_UP)
{
return SNAKE_UP;
}
}
else if(!KEY_DOWN)
{
delay_ms(TIMER);
if(!KEY_DOWN)
{
return SNAKE_DOWN;
}
}
else if(!KEY_LEFT)
{
delay_ms(TIMER);
if(!KEY_LEFT)
{
return SNAKE_LEFT;
}
}
else if(!KEY_RIGHT)
{
delay_ms(TIMER);
if(!KEY_RIGHT)
{
return SNAKE_RIGHT;
}
}
else
{
return 255;
}
}
/*
*函数介绍:food随即分布函数
*输入参数:dRange
*输出参数:unsigned int
*返回值: 无
*/
unsigned int SnakeRand(unsigned int dRange)
{
srand(TCNT0);
return (rand()%dRange) ;
}
/*
*函数介绍:放置food函数
*输入参数:无
*输出参数:无
*返回值: 无
*/
void SnakePutFood(void)
{
unsigned int x;
unsigned int y;
do
{
x = SnakeRand(GAME_FIELD_WIDTH);
y = SnakeRand(GAME_FIELD_HEIGHT);
}while( cGameField[y*GAME_FIELD_WIDTH+x] != SNAKE_GROUND);
cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_FOOD;
DrawBox(x, y);
}
/*
*函数介绍:贪吃蛇初始化函数
*输入参数:无
*输出参数:无
*返回值: 无
*/
void SnakeInitial(void)
{
unsigned int i;
unsigned int j;
for(i = 0; i < GAME_FIELD_HEIGHT; i ++) //打扫游戏场地
{
for(j = 0; j < GAME_FIELD_WIDTH; j ++)
{
cGameField[i*GAME_FIELD_WIDTH+j] = SNAKE_GROUND;
}
}
memset(cDisplayRam,0, 504);//清空显示缓存
SnakeHead.x = 11;//设置蛇头位置
SnakeHead.y = 3;
SnakeTail.x = 8;//设置蛇尾位置
SnakeTail.y = 3;
DrawBox(11, 3); //画出蛇头
snakeHeadDir = SNAKE_RIGHT;
DrawBox(10, 3); //画蛇身
cGameField[3*GAME_FIELD_WIDTH+10] = SNAKE_RIGHT; //移动方向右
DrawBox(9, 3); //画蛇身
cGameField[3*GAME_FIELD_WIDTH+9] = SNAKE_RIGHT; //移动方向右
DrawBox(8, 3); //画蛇尾
cGameField[3*GAME_FIELD_WIDTH+8] = SNAKE_RIGHT; //移动方向右
SnakePutFood();
}
/*
*函数介绍:贪吃蛇游戏函数
*输入参数:无
*输出参数:无
*返回值: 无
*/
void SnakeGame(void)
{
unsigned int x = 0;
unsigned int y = 0;
unsigned int foodCnt = 0; //食物计数器
unsigned char markTab[] = {"Mark:"};
unsigned char overTab[] = {"Game over"};
unsigned char coolTab[] = {"You are Cool!"};
unsigned char scoreTab[] = {"Score:"};
while(1)
{
keyCode = KeyScan(); //获取用户按键
PrintString(10, 5, scoreTab);
PrintChar(numberTab[foodCnt/100]);
PrintChar(numberTab[foodCnt%100/10]);
PrintChar(numberTab[foodCnt%10]);
if (KEY_QUIT == 0) //退出游戏
{
topMark = foodCnt;
Clean();
break;
}
if(keyCode != 255)
{
if(keyCode != ((snakeHeadDir - 1 + 2) % 4) + 1) //如果不是后退
{
snakeHeadDir = keyCode;
}
}
if(snakeMoveFlag == 1) //运动延时时间到
{
#asm("cli") //关闭中断
snakeMoveFlag = 0;
if(cGameField[y*GAME_FIELD_WIDTH+x] != SNAKE_FOOD) //如果没有吃到食物
{
x = SnakeTail.x; //获取当前蛇尾位置
y = SnakeTail.y;
switch(cGameField[y*GAME_FIELD_WIDTH+x]) //判断蛇尾的移动方向
{
case SNAKE_UP:
{
if(y == 0)
{
y = GAME_FIELD_HEIGHT;
}
y--;
break;
}
case SNAKE_DOWN:
{
y++;
if(y == GAME_FIELD_HEIGHT)
{
y = 0;
}
break;
}
case SNAKE_LEFT:
{
if(x == 0)
{
x = GAME_FIELD_WIDTH;
}
x--;
break;
}
case SNAKE_RIGHT:
{
x++;
if(x == GAME_FIELD_WIDTH) //如果移动到场地宽度
{
x = 0; //水平位置清零
}
break;
}
default:
break;
}
cGameField[SnakeTail.y*GAME_FIELD_WIDTH+SnakeTail.x] = SNAKE_GROUND;
ClearBox(SnakeTail.x , SnakeTail.y); //清除尾巴
SnakeTail.x = x; //重新定位蛇尾
SnakeTail.y = y;
}
else //吃到食物
{
SnakePutFood();
foodCnt++;
if(foodCnt >= 284) //满分
{
PrintString(15, 2, coolTab);
PrintString(20, 4, markTab);
PrintChar(numberTab[foodCnt/100]);
PrintChar(numberTab[foodCnt%100/10]);
PrintChar(numberTab[foodCnt%10]);
}
}
x = SnakeHead.x; //获取当前蛇头位置
y = SnakeHead.y;
switch(snakeHeadDir) //判断蛇头的移动方向
{
case SNAKE_UP:
{
cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_UP;
if(y == 0)
{
y = GAME_FIELD_HEIGHT;
}
y--;
break;
}
case SNAKE_DOWN:
{
cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_DOWN;
y++;
if(y == GAME_FIELD_HEIGHT)
{
y = 0;
}
break;
}
case SNAKE_LEFT:
{
cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_LEFT;
if(x == 0)
{
x = GAME_FIELD_WIDTH;
}
x--;
break;
}
case SNAKE_RIGHT:
{
cGameField[y*GAME_FIELD_WIDTH+x] = SNAKE_RIGHT;
x++;
if(x == GAME_FIELD_WIDTH)
{
x = 0;
}
break;
}
default:
{
break;
}
}
DrawBox(x, y);
SnakeHead.x = x; //重新定位蛇头
SnakeHead.y = y;
if(cGameField[y*GAME_FIELD_WIDTH+x] != SNAKE_GROUND && cGameField[y*GAME_FIELD_WIDTH+x]
!= SNAKE_FOOD)
{
PrintString(20, 2, overTab);
PrintString(20, 4, markTab);
topMark = foodCnt;
SetAddress(50, 4);
PrintChar(numberTab[foodCnt/100]);
PrintChar(numberTab[foodCnt%100/10]);
PrintChar(numberTab[foodCnt%10]);
memset(cDisplayRam,0, 504);
delay_ms(200);
Clean();
#asm("sei")
return;
}
TCNT0 = 150;
#asm("sei")
}
}
}
/*
*函数介绍:界面选择函数
*输入参数:无
*输出参数:无
*返回值: 无
*/
void SnakeOption(void)
{
unsigned char i = 3;
unsigned char menuTab0[] = {"New Game"};
unsigned char menuTab1[] = {"Top Mark"};
unsigned char menuTab2[] = {"Help"};
unsigned char pointTab[] = {">"};
unsigned char speaceTab[] = {" "};
unsigned char helpTab[] = {"Mark the snakegrow longer by directing it to the food."};
PrintBmp(0, 0);
PrintString(25, 3, menuTab0);
PrintString(25, 4, menuTab1);
PrintString(25, 5, menuTab2);
PrintString(14, 3, pointTab);
while(1)
{
keyCode = KeyScan(); //获取用户按键
switch(keyCode)
{
case SNAKE_UP:
{
if(i > 3)
{
PrintString(15, i, speaceTab);
i--;
}
PrintString(15, i, pointTab);
while(keyCode == KeyScan());
break;
}
case SNAKE_DOWN:
{
if(i < 5)
{
PrintString(15, i, speaceTab);
i++;
}
PrintString(15, i, pointTab);
while(keyCode == KeyScan());
break;
}
case SNAKE_RIGHT:
{
if(i == 3)
{
SnakeInitial();
SnakeGame();
PrintBmp(0, 0);
PrintString(25, 3, menuTab0);
PrintString(25, 4, menuTab1);
PrintString(25, 5, menuTab2);
PrintString(15, i,pointTab);
}
if(i == 4)
{
Clean();
SetAddress(10, 3);
PrintChar(numberTab[topMark/100]);
PrintChar(numberTab[topMark%100/10]);
PrintChar(numberTab[topMark%10]);
}
if(i == 5)
{
Clean();
PrintString(0, 0, helpTab);
}
while(keyCode == KeyScan());
break;
}
case SNAKE_LEFT:
{
Clean();
i = 3;
PrintBmp(0, 0);
PrintString(25, 3, menuTab0);
PrintString(25, 4, menuTab1);
PrintString(25, 5, menuTab2);
PrintString(14, 3, pointTab);
while(keyCode == KeyScan());
}
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -