2.6 小程序贪吃蛇
按照测试计划,完成贪吃蛇小程序,在GD32E503V-EVAL开发板上运行。
2.6.1 贪吃蛇需求说明
贪吃蛇需求如下:
(1) 触摸屏显示蛇身、蛇头、食物等
(2) 蛇身、舌头通过触摸屏控制光标行进方向
(3) 食物能随机产生,遇到蛇头被吃掉
(4) 蛇吃到食物,蛇身增长食物的长度
(5) 蛇的移动速度能够设定以及其他设置功能
2.6.2 贪吃蛇设计说明
1) 显示界面
设置一个二维地图,定义(x,y),二维数组显示图像位置信息。
定义蛇身、蛇头、食物、墙的显示方式,蛇身显示为“X”,蛇头显示为“H”,墙显示为“#”,食物显示为“*”。
/******************************************************************************
* Function: map creation
* void creatmap(char map[MAP_ROW][MAP_COLUMN])
******************************************************************************/
void creatmap(char map[6][20])
{
for (int i = 0; i < MAP_COLUMN; ++i) /* Wall created in bottom and top site*/
{
map[0] = wall;
map[MAP_ROW-1] = wall;
}
for (int i = 1; i < MAP_ROW-1; ++i) /* Wall created in left and right site*/
{
map[0] = wall;
map[MAP_COLUMN-1] = wall;
}
for (int i = 1; i < MAP_ROW-1; ++i) /* Blank area used to display snake and food*/
{
for (int j = 1; j < MAP_COLUMN-1; ++j)
map[j] = ' ';
}
}
/******************************************************************************
* Function: snake body creation
* void creatsnake(int snake[MAP_ROW][MAP_COLUMN])
******************************************************************************/
void creatsnake(int snake[6][20])
{
for (int i = 1; i < snake_initiallength; ++i)
{
snake[1] = body;
++body;
}
}
/******************************************************************************
* Function: image displayed
* void displaymap(char map[MAP_ROW][MAP_COLUMN],int snake[MAP_ROW][MAP_COLUMN])
******************************************************************************/
void displaymap(char map[6][20],int snake[6][20])
{
/*snake中,0表空闲位置,-1表食物,正数表蛇*/
for (int i = 1; i < MAP_ROW-1; ++i)
{
for (int j = 1; j < MAP_COLUMN-1; ++j)
{
if (snake[j] == 0)map[j] = ' ';
else map[j] = snake_body;
}
}
map[head_x][head_y] = snake_head;
map[food_x][food_y] = food;
for (uint16_t i = 0; i < MAP_ROW; i++)
{
for (uint16_t j = 0; j < MAP_COLUMN; j++)
{
lcd_char_display((a1+8*j), b3+i*16, map[j], char_format);
}
}
}
2) 控制蛇的移动
蛇的移动,利用触摸屏虚拟按键“↑”“↓”“←”“→”实现,蛇按照惯性移动。
int a;
switch(button_id){
case 0: direction = FLAG_UP;break;
case 1: direction = FLAG_DOWN;break;
case 2: direction = FLAG_LEFT;break;
case 3: direction = FLAG_RIGHT;break;
default:
break;
}
switch(direction){
case 0:snake[head_x][head_y] = body; body++; head_x--; break;
case 1:snake[head_x][head_y] = body; body++; head_x++; break;
case 2:snake[head_x][head_y] = body; body++; head_y--; break;
case 3:snake[head_x][head_y] = body; body++; head_y++; break;
default:
break;
}
if (snake[head_x][head_y] != -1)
{
a = snake[tail_x][tail_y];
snake[tail_x][tail_y] = 0;
if (tail_x + 1 < MAP_ROW - 1 && snake[tail_x + 1][tail_y] == a+1)
tail_x = tail_x + 1;
else
if (tail_x - 1 > 0 && snake[tail_x - 1][tail_y] == a + 1)
tail_x = tail_x - 1;
else
if (tail_y + 1 < MAP_COLUMN - 1 && snake[tail_x][tail_y + 1] == a + 1)
tail_y = tail_y + 1;
else
if (tail_y - 1 > 0 && snake[tail_x][tail_y - 1] == a + 1)
tail_y = tail_y - 1;
}
else
{
creatfood(snake);
}
num[0]=num[1]=num[2]=num[3]=0;
count=0;
}
b = judge(map);
3) 食物放置
用随机数函数来放置食物的坐标。如果食物没吃掉,不用调用随机数函数;否则重新生成。
/******************************************************************************
* Function: food creation
* void creatfood(int snake[MAP_ROW][MAP_COLUMN])
******************************************************************************/
void creatfood(int snake[6][20])
{
while (snake[food_x][food_y] != 0)
{
food_x = rand() % 6 ;
food_y = rand() % 20 ;
}
snake[food_x][food_y] = -1; /* The food is displayed with "-1" */
}
4) 蛇吃到食物变化
蛇头“吃”到食物,旧的食物消失,新的食物显示;
蛇身生长。
5) 设置菜单
控制按键显示
2.6.3 贪吃蛇程序编写
为了开发速度,在GD32E503V-EVAL开发板demo程序“16_EXMC_TouchScreen”基础上作开发。
1) 调试并测试“16_EXMC_TouchScreen”程序
Shot JP12(2,3) for SPI0 function
“16_EXMC_TouchScreen”程序通过“External momory controller(EXMC)”接口控制触摸屏
2) 程序主体
#include <stdlib.h>
#include <time.h>
uint16_t MAP_ROW = 6; /* map row*/
uint16_t MAP_COLUMN = 20; /* map COLUMN*/
char snake_head = 'H';
char snake_body = 'X';
char wall = '#';
char food = '*';
char map_string[6][20]={"####################",
"# #",
"# XH #",
"# * #",
"# #",
"####################"};
char gameover_string[1][10]={"GAME OVER!"};
uint16_t snake_initiallength = 5;
uint16_t body = 1;
uint8_t direction = 3;//蛇移动方向
int tail_x = 1, tail_y = 1;//蛇尾坐标
int head_x = 1, head_y = 5;//初始蛇头位置
int food_x = 1, food_y = 1;//食物位置
void snake_init(void); /* snake app initiation */
void creatmap(char map[6][20]);
void creatsnake(int snake[6][20]);
void creatfood(int snake[6][20]);
void displaymap(char map[6][20],int snake[6][20]);
int judge(char map[6][20]);
/* main*/
uint8_t led_string[4][4]={"UPPE","DOWN","LEFT","RGHT"};
uint8_t button_id = 3;
enum eFLAG{
FLAG_UP = 0,
FLAG_DOWN = 1,
FLAG_LEFT = 2,
FLAG_RIGHT = 3
}direction;
snake_init();
char map[6][20]={0};
int snake[6][20]={0};
creatmap(map);
delay_1ms(100);
creatsnake(snake);
delay_1ms(100);
creatfood(snake);
delay_1ms(100);
while(1){
displaymap(map,snake);
/* get the position of touch on LCD screen */
if(SUCCESS == touch_scan()){
count++;
if(0x8989 == device_code){
/* SSD1289 */
get_touch_area(touch_coordinate_x_get(touch_ad_x),(LCD_Y - touch_coordinate_y_get(touch_ad_y)),num);
}else if((0x9320 == device_code) || (0x9300 == device_code)){
/* ILI9320 */
get_touch_area(LCD_X - touch_coordinate_x_get(touch_ad_x),(LCD_Y - touch_coordinate_y_get(touch_ad_y)),num);
}
}
/* generate response to the touch(turn on LED and change picture )*/
if(count==20){
button_id = find_max(num);
turn_on_led(button_id);
//change_picture(button_id);
int a;
switch(button_id){
case 0: direction = FLAG_UP;break;
case 1: direction = FLAG_DOWN;break;
case 2: direction = FLAG_LEFT;break;
case 3: direction = FLAG_RIGHT;break;
default:
break;
}
switch(direction){
case 0:snake[head_x][head_y] = body; body++; head_x--; break;
case 1:snake[head_x][head_y] = body; body++; head_x++; break;
case 2:snake[head_x][head_y] = body; body++; head_y--; break;
case 3:snake[head_x][head_y] = body; body++; head_y++; break;
default:
break;
}
if (snake[head_x][head_y] != -1)
{
a = snake[tail_x][tail_y];
snake[tail_x][tail_y] = 0;
if (tail_x + 1 < MAP_ROW - 1 && snake[tail_x + 1][tail_y] == a+1)
tail_x = tail_x + 1;
else
if (tail_x - 1 > 0 && snake[tail_x - 1][tail_y] == a + 1)
tail_x = tail_x - 1;
else
if (tail_y + 1 < MAP_COLUMN - 1 && snake[tail_x][tail_y + 1] == a + 1)
tail_y = tail_y + 1;
else
if (tail_y - 1 > 0 && snake[tail_x][tail_y - 1] == a + 1)
tail_y = tail_y - 1;
}
else
{
creatfood(snake);
}
num[0]=num[1]=num[2]=num[3]=0;
count=0;
}
b = judge(map);
}
2.6.4 贪吃蛇程序运行
目前程序运行正常!撞墙程序需要调整一下。其他运行正常
|