硬件平臺(tái):STM32核心板、OLED顯示(SPI接口)、按鍵
實(shí)現(xiàn)功能:
1.繪制蛇身,通過隨機(jī)數(shù)生成食物;
2.按鍵控制運(yùn)動(dòng)方向,完成上下左右控制和加速控制;
3.游戲結(jié)束判斷:當(dāng)蛇頭碰到上下左右墻壁或者碰到蛇身則游戲結(jié)束,可按任意鍵重新開始;
4.得分統(tǒng)計(jì),每吃到一顆食物則+1積分,知道游戲結(jié)束;
實(shí)現(xiàn)原理:
1.完成按鍵驅(qū)動(dòng),用戶控制蛇行動(dòng)方向;
2.完成OLED驅(qū)動(dòng),實(shí)時(shí)刷新蛇行動(dòng)軌跡和食物位置;
3.創(chuàng)建蛇身結(jié)構(gòu)體信息,設(shè)置初始蛇身長度,每吃到一個(gè)食物結(jié)構(gòu)體成員+1,蛇身變長,可通過鏈表實(shí)現(xiàn)或結(jié)構(gòu)體數(shù)組實(shí)現(xiàn);
實(shí)物效果:
1.設(shè)置初始蛇身和生成實(shí)物
2.按鍵控制運(yùn)動(dòng)方向
3.游戲結(jié)束提示和得分統(tǒng)計(jì)
軟件設(shè)計(jì):
1.OLED底層畫點(diǎn)函數(shù)實(shí)現(xiàn),用戶繪制蛇身和食物
static u8 oled_gram[8][128];//屏幕緩沖區(qū)
void OLED_DrawPoint(u8 x,u8 y,u8 c)
{
u8 page=y/8;//y坐標(biāo)值在第幾頁
u8 line=y%8;//在當(dāng)前頁的第幾行上
if(c)oled_gram[page][x]|=1<;>
2.蛇身繪制,每個(gè)蛇身節(jié)點(diǎn)為4*4矩形填充
/*繪制貪吃蛇單個(gè)節(jié)點(diǎn)*/
static void OLED_DrawSnake(u8 x,u8 y,u8 c)
{
u16 i;
u8 x0=x;
for(i=0;i<4*4;i++)
{
OLED_DrawPoint(x0,y,c);
x0++;
if(x0-x==4)
{
x0=x;
y++;
}
}
}
3.繪制貪吃蛇整個(gè)蛇身,遍歷結(jié)構(gòu)體數(shù)組。
//保存節(jié)點(diǎn)坐標(biāo)結(jié)果體
struct SNAKE
{
u8 x;//節(jié)點(diǎn)x坐標(biāo)
u8 y;//節(jié)點(diǎn)y坐標(biāo)
};
struct SNAKE snake_info[50];//蛇節(jié)點(diǎn)最多50個(gè)
static u8 node_cnt=0;//蛇身長度
}
/*繪制蛇身節(jié)點(diǎn)個(gè)數(shù)
struct SNAKE *buff --保存蛇身節(jié)點(diǎn)結(jié)構(gòu)體指針
cnt --蛇身節(jié)點(diǎn)個(gè)數(shù)
c -- 1為繪制,0為取消繪制
*/
static void OLED_DrawSnakebody(struct SNAKE *buff,u8 cnt,u8 c)
{
u8 i=0;
for(i=0;i;i++)>
4.食物坐標(biāo)判斷,計(jì)算是否吃到食物
/**************判斷實(shí)物位置***************
**
**判斷新生成的實(shí)物x坐標(biāo)是否落在蛇身上
**形參:u8 x --實(shí)物光標(biāo)位置
** cnt --蛇身節(jié)點(diǎn)個(gè)數(shù)
**返回值:1 --落在蛇身上,0 -- 沒有
*******************************************/
static u8 OLED_GetSnakeFoodX(u8 x,u8 cnt)
{
u8 i=0;
for(i=0;i;i++)>
5.移動(dòng)蛇身
/*******************動(dòng)態(tài)移動(dòng)蛇身********************************/
static void Snake_Move(u8 x,u8 y)
{
u8 i=0;
OLED_DrawSnake(snake_info[0].x,snake_info[0].y,0);//清除蛇尾
for(i=0;i;i++)>
6.開始游戲,控制移動(dòng)方向,生成實(shí)物,判斷游戲是否結(jié)束,得分統(tǒng)計(jì)
/*******************控制方向,判斷游戲是否結(jié)束********************/
u8 SnakeGameStart(void)
{
u8 x=10;
u8 y=30;
u8 food_x,food_y;
u8 stat=0;
char buff[20];
OLED_DrawRectangle(0, 0, 127, 63);//繪制矩形
OLED_DrawRectangle(1, 1, 126, 62);//繪制矩形
//創(chuàng)建蛇身1
snake_info[node_cnt].x=x;
snake_info[node_cnt].y=y;
node_cnt++;
//創(chuàng)建蛇身2
snake_info[node_cnt].x=x+5;
snake_info[node_cnt].y=y;
//保存蛇頭坐標(biāo)
x=snake_info[node_cnt].x;
y=snake_info[node_cnt].y;
node_cnt++;
OLED_DrawSnakebody(snake_info,node_cnt,1);//繪制蛇身
//生成實(shí)物坐標(biāo)
food_x=((rand()%115)/5)*5+5;
food_y=((rand()%50)/5)*5+5;
OLED_DrawSnake(food_x,food_y,1);//繪制實(shí)物
OLED_Refresh();//更新數(shù)據(jù)到屏幕
while(1)
{
if(snake_info[node_cnt-1].x>=125 || snake_info[node_cnt-1].y>=60)//判斷是否撞墻
{
snprintf(buff,sizeof(buff),"Mark:%d",node_cnt-2);
OLED_DisplayStr(36,8,8,16,buff);//字符串顯示
OLED_DisplayStr(10,28,12,24,"Game over");//字符串顯示
OLED_Refresh();//更新數(shù)據(jù)到屏幕
key_val=0;
node_cnt=0;//清空節(jié)點(diǎn)
break;//游戲結(jié)束
}
if(snake_info[node_cnt-1].x==food_x && snake_info[node_cnt-1].y==food_y)//判斷是否吃到食物
{
if(stat&1<<0 || stat&1<<1)//向上或向下時(shí)y+5
{
snake_info[node_cnt].x=food_x;
snake_info[node_cnt].y=food_y+5;
}
else //向左或向右時(shí)x+5
{
snake_info[node_cnt].x=food_x+5;
snake_info[node_cnt].y=food_y;
}
node_cnt++;
while(1)//保證重新生成的實(shí)物不再蛇身上
{
food_x=((rand()%115)/5)*5+5;
if(OLED_GetSnakeFoodX(food_x,node_cnt)==0)break;
}
while(1)
{
food_y=((rand()%50)/5)*5+5;
if(OLED_GetSnakeFoodY(food_y,node_cnt)==0)break;
}
OLED_DrawSnake(food_x,food_y,1);
OLED_Refresh();//更新數(shù)據(jù)到屏幕
}
switch(key_val)
{
case UP://上
stat&=~(0x3<<2);//清除左右標(biāo)志
if(stat&1<<1){}//向下時(shí)不能直接向上
else
{
stat|=1<<0;//向上
y-=5;
Snake_Move(x,y);
}
break;
case DOWM://下
stat&=~(0x3<<2);//清除左右標(biāo)志
if(stat&1<<0){}//在向上時(shí)不能直接向下
else
{
stat|=1<<1;//向下標(biāo)志位
y+=5;
Snake_Move(x,y);
}
break;
case LEFT://左
stat&=~(0x3<<0);//清除上下標(biāo)志
if(stat&1<<3){}//向右時(shí)不能直接向左
else
{
stat|=1<<2;//向左
x-=5;
Snake_Move(x,y);
}
break;
case RIGHT://右
stat&=~(0x3<<0);//清除上下標(biāo)志
if(stat&1<<2){}//向左時(shí)不能直接向右
else
{
stat|=1<<3;
x+=5;
Snake_Move(x,y);
}
break;
}
OLED_Refresh();//更新數(shù)據(jù)到屏幕
Delay_Ms(300);
}
return 0;
}
7.主函數(shù),硬件初始化,生成隨機(jī)數(shù)種子,進(jìn)入游戲
int main()
{
LED_Init();//LED初始化
USARTx_Init(USART1,115200,72);
TIMx_Init(TIM2,72,20000);//定時(shí)器輔助串口1接收,計(jì)數(shù)一個(gè)周期時(shí)間為20ms
KEY_Init();//按鍵初始化
EXTI_Init();
Beep_Init();//蜂鳴器初始化
OLED_Init();
srand(1);//生成隨機(jī)數(shù)種子
AA:
SnakeGameStart();
while(1)
{
if(key_val)//按任意鍵繼續(xù)游戲
{
OLED_ClearGram();//清空緩沖區(qū)
OLED_Refresh();//更新數(shù)據(jù)到屏幕
key_val=0;
goto AA;
}
}
}
審核編輯:湯梓紅
-
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
356046 -
游戲
+關(guān)注
關(guān)注
2文章
742瀏覽量
26317 -
核心板
+關(guān)注
關(guān)注
5文章
1014瀏覽量
29771
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論