贪吃蛇游戏规则:通过方向控制蛇的移动方向,当蛇头碰到前方食物时,将食物转换为自己的身体。
游戏设定:
1)每吃到n颗食物,移动速度加快
2)每颗食物增加步骤时长限制,蛇在一定步骤内未吃到食物将重新生成新的食物
3)碰到自身或边界游戏结束
按键操作:方向键控制移动方向,A键重新开始
屏幕区域规划:屏幕分辨率240*135,显示分两个区域,左侧为游戏区域(180*135),右侧为分数与等级显示区域(60*135)。蛇身单个节点大小15*15。
具体实现:(数据结及显示屏驱动使用示例工程中的代码)
1)按键扫描,控制蛇的方向,按键是否有抖动不影响蛇的移动,故未做去抖动处理
void key_process(void)
{
if(!dev_read_key(KEY_UP) && my_eat_snake.snake_dir != S_DOWN)
my_eat_snake.snake_dir = S_UP;
if(!dev_read_key(KEY_DOWN) && my_eat_snake.snake_dir != S_UP)
my_eat_snake.snake_dir = S_DOWN;
if(!dev_read_key(KEY_LEFT) && my_eat_snake.snake_dir != S_RIGHT)
my_eat_snake.snake_dir = S_LEFT;
if(!dev_read_key(KEY_RIGHT) && my_eat_snake.snake_dir != S_LEFT)
my_eat_snake.snake_dir = S_RIGHT;
if(!dev_read_key(KEY_A))
{
score = 0;
LCD_1IN3_Clear(GLCD_COLOR_BLACK);
snake_reinit();
}
if(!dev_read_key(KEY_B))
{
music_on = !music_on;
}
}2)蛇的移动
void snake_move(){
uint16_t i;
//clear last body
clear_last_body(my_eat_snake.my_snake_body[my_eat_snake.snake_body_len - 1].iX,my_eat_snake.my_snake_body[my_eat_snake.snake_body_len - 1].iY);
for( i = my_eat_snake.snake_body_len - 1; i > 0; i--){
my_eat_snake.my_snake_body[i].iX = my_eat_snake.my_snake_body[i-1].iX;
my_eat_snake.my_snake_body[i].iY = my_eat_snake.my_snake_body[i-1].iY;
}
switch(my_eat_snake.snake_dir)
{
case S_UP: my_eat_snake.my_snake_body[0].iY -= my_eat_snake.snake_body_width; break;
case S_DOWN: my_eat_snake.my_snake_body[0].iY += my_eat_snake.snake_body_width; break;
case S_LEFT: my_eat_snake.my_snake_body[0].iX -= my_eat_snake.snake_body_width; break;
case S_RIGHT: my_eat_snake.my_snake_body[0].iX += my_eat_snake.snake_body_width; break;
}
} 如果使用全局刷新界面会有明显的抖动,游戏进行时采用了局部刷新。每移动一步只需绘制新的蛇头,清楚蛇尾即可。
void clear_last_body(int x, int y)
{
int i,j;
for(i=0;i<15;i++)
{//row
for(j=0;j<15;j++)
{//column
LCD_1IN3_DisplayPoint(x+j,y+i,GLCD_COLOR_BLACK);
}
}
}3)判断是否吃上食物
bool snake_eat()
{
int i;
int tempx,tempy;
tempx = my_eat_snake.my_snake_body[0].iX;
tempy = my_eat_snake.my_snake_body[0].iY;
switch(my_eat_snake.snake_dir)
{
case S_UP: tempy -= my_eat_snake.snake_body_width; break;
case S_DOWN: tempy += my_eat_snake.snake_body_width; break;
case S_LEFT: tempx -= my_eat_snake.snake_body_width; break;
case S_RIGHT: tempx += my_eat_snake.snake_body_width; break;
}
if(tempx >= W_WIDTH){
tempx = 0;
}
if(tempx < 0){
tempx = W_WIDTH-B_WIDTH;
}
if(tempy >= W_HEIGHT)
tempy = 0;
if(tempy < 0)
tempy = W_HEIGHT-B_WIDTH;
//eat food judge
if(tempy == my_snake_food.food.iY && tempx == my_snake_food.food.iX)
{
my_eat_snake.snake_body_len += 1;
score+=1;
for( i = my_eat_snake.snake_body_len - 1; i > 0; i--){
my_eat_snake.my_snake_body[i].iX = my_eat_snake.my_snake_body[i-1].iX;
my_eat_snake.my_snake_body[i].iY = my_eat_snake.my_snake_body[i-1].iY;
my_eat_snake.my_snake_body[i].img_index = my_eat_snake.my_snake_body[i-1].img_index;
}
my_eat_snake.my_snake_body[0].iY = my_snake_food.food.iY;
my_eat_snake.my_snake_body[0].iX = my_snake_food.food.iX;
my_eat_snake.my_snake_body[0].img_index = my_snake_food.food.img_index;
my_eat_snake.snake_speed = 800-(my_eat_snake.snake_body_len/3)*50;
level = my_eat_snake.snake_body_len/3;
//draw_snake();
new_food();
return true;
}
return false;
}4)游戏结束判断,当蛇头碰到身体或边界游戏结束
bool is_game_over()
{
int i;
for(i=my_eat_snake.snake_body_len-1;i>0;i--)
{
if(my_eat_snake.my_snake_body[0].iX == my_eat_snake.my_snake_body[i].iX && my_eat_snake.my_snake_body[0].iY == my_eat_snake.my_snake_body[i].iY)
return true;
}
if(my_eat_snake.my_snake_body[0].iX >= W_WIDTH){
return true;
}
if(my_eat_snake.my_snake_body[0].iX < 0){
return true;
}
if(my_eat_snake.my_snake_body[0].iY >= W_HEIGHT)
return true;
if(my_eat_snake.my_snake_body[0].iY < 0)
return true;
return false;
}5)对蛇身做了渐变色处理,使用HSV颜色转RGB方式
uint16_t convertHSVtoRGB565(float h, float s, float v)
{
int i;
float f, p, q, t;
int r, g, b;
uint16_t rgb565;
if (s == 0)
{
r = g = b = v * 255;
}
else
{
h /= 60;
i = (int)h;
f = h - i;
p = v * (1 - s);
q = v * (1 - s * f);
t = v * (1 - s * (1 - f));
switch (i)
{
case 0:
r = v * 255;
g = t * 255;
b = p * 255;
break;
case 1:
r = q * 255;
g = v * 255;
b = p * 255;
break;
case 2:
r = p * 255;
g = v * 255;
b = t * 255;
break;
case 3:
r = p * 255;
g = q * 255;
b = v * 255;
break;
case 4:
r = t * 255;
g = p * 255;
b = v * 255;
break;
default:
r = v * 255;
g = p * 255;
b = q * 255;
break;
}
}
rgb565 = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
return rgb565;
}6)主流程
void snake_run(){
static uint16_t ms_count = 0;
ms_count += 10;
my_snake_food.alivetime += 10;
if(ms_count >= my_eat_snake.snake_speed)
{
if(!is_game_over())
{
if(!snake_eat())
snake_move();
draw_snake();
if(my_snake_food.alivetime >= (rand()%15+20)*my_eat_snake.snake_speed)
{
clear_last_body(my_snake_food.food.iX,my_snake_food.food.iY);
new_food();
}
draw_snake_food();
draw_record_area();
}
else
{
//game over
my_eat_snake.snake_speed = 1000;
draw_image(0,0,W_WIDTH,W_HEIGHT,(unsigned char*)gImage_pic1);
LCD_DisplayString(0,5,"Press A to Start",16,GLCD_COLOR_MAGENTA);
}
ms_count = 0;
}
key_process();
DEV_Delay_ms(10);
}以上为本次DIY的代码。
我要赚赏金
