一、功能简介
本项目使用Proteus8仿真STM32单片机控制器,使用按键、IIC OLED模块等。
主要功能:
系统运行后,OLED显示第一关推箱子游戏界面,通过KEY1、KEY2、KEY3和KEY44个按键控制玩家上、下、左和右移动方向。每将箱子全部移动到目的地,则进入下一关地图,默认项目中设计了4种地图,用户可根据配套上位机软件生成游戏地图。
二、软件设计
/*
作者:嗨小易(QQ技术交流群:570487280)
*/
//按键消息处理
void key_event(void)
{
u8 i=0,k=0;
//获取玩家的位置
for(i=0;i<MAP_ROW;i++)
{
for(k=0;k<MAP_COL;k++)
{
if(map[glevel][i][k]==PLAYER || map[glevel][i][k]==PLAYER+DEST)
goto end;
}
}
end:
//方向键 上下左右
switch(gkey_value)
{
case KEY1_PRESS:
//能不能够移动 玩家前面是空地,直接移动
if(map[glevel][i-1][k]==SPACE || map[glevel][i-1][k]==DEST)
{
map[glevel][i-1][k]+=PLAYER;
map[glevel][i][k]-=PLAYER;
}
//前面是箱子,还要判断箱子的前面是什么
else if(map[glevel][i-1][k]==BOX || map[glevel][i-1][k]==BOX+DEST)
{
if(map[glevel][i-2][k]==SPACE || map[glevel][i-2][k]==DEST)
{
//把箱子移动到前面位置
map[glevel][i-2][k]+=BOX;
//让原来箱子的位置,减去箱子,然后加上玩家
map[glevel][i-1][k]=map[glevel][i-1][k]-BOX+PLAYER;
//让玩家在原来的位置消失
map[glevel][i][k]-=PLAYER;
}
}
OLED_Clear_Gram();
break;
case KEY3_PRESS:
//能不能够移动 玩家前面是空地,直接移动
if(map[glevel][i+1][k]==SPACE || map[glevel][i+1][k]==DEST)
{
map[glevel][i+1][k]+=PLAYER;
map[glevel][i][k]-=PLAYER;
}
//前面是箱子,还要判断箱子的前面是什么
else if(map[glevel][i+1][k]==BOX || map[glevel][i+1][k]==BOX+DEST)
{
if(map[glevel][i+2][k]==SPACE || map[glevel][i+2][k]==DEST)
{
//把箱子移动到前面位置
map[glevel][i+2][k]+=BOX;
//让原来箱子的位置,减去箱子,然后加上玩家
map[glevel][i+1][k]=map[glevel][i+1][k]-BOX+PLAYER;
//让玩家在原来的位置消失
map[glevel][i][k]-=PLAYER;
}
}
OLED_Clear_Gram();
break;
case KEY2_PRESS:
//能不能够移动 玩家前面是空地,直接移动
if(map[glevel][i][k-1]==SPACE || map[glevel][i][k-1]==DEST)
{
map[glevel][i][k-1]+=PLAYER;
map[glevel][i][k]-=PLAYER;
}
//前面是箱子,还要判断箱子的前面是什么
else if(map[glevel][i][k-1]==BOX || map[glevel][i][k-1]==BOX+DEST)
{
if(map[glevel][i][k-2]==SPACE || map[glevel][i][k-2]==DEST)
{
//把箱子移动到前面位置
map[glevel][i][k-2]+=BOX;
//让原来箱子的位置,减去箱子,然后加上玩家
map[glevel][i][k-1]=map[glevel][i][k-1]-BOX+PLAYER;
//让玩家在原来的位置消失
map[glevel][i][k]-=PLAYER;
}
}
OLED_Clear_Gram();
break;
case KEY4_PRESS:
//能不能够移动 玩家前面是空地,直接移动
if(map[glevel][i][k+1]==SPACE || map[glevel][i][k+1]==DEST)
{
map[glevel][i][k+1]+=PLAYER;
map[glevel][i][k]-=PLAYER;
}
//前面是箱子,还要判断箱子的前面是什么
else if(map[glevel][i][k+1]==BOX || map[glevel][i][k+1]==BOX+DEST)
{
if(map[glevel][i][k+2]==SPACE || map[glevel][i][k+2]==DEST)
{
//把箱子移动到前面位置
map[glevel][i][k+2]+=BOX;
//让原来箱子的位置,减去箱子,然后加上玩家
map[glevel][i][k+1]=map[glevel][i][k+1]-BOX+PLAYER;
//让玩家在原来的位置消失
map[glevel][i][k]-=PLAYER;
}
}
OLED_Clear_Gram();
break;
}
gkey_value=0;
}
//游戏过关判定
//返回1过关,0未过关
u8 game_pass(void)
{
u8 i=0,k=0;
for(i=0;i<MAP_ROW;i++)
{
for(k=0;k<MAP_COL;k++)
{
if(map[glevel][i][k]==BOX)
return 0;
}
}
return 1;
}
//应用控制系统
void appdemo_show(void)
{
KEY_Init();
OLED_Init();
My_EXTI_Init();
while(1)
{
//游戏过关
if(game_pass())
{
glevel++;
if(glevel>GAME_CENSOR)
{
//游戏通过
OLED_Clear();
OLED_ShowString(10,10,"Game Pass",16);
OLED_ShowString(10,30,"Reset Start",16);
OLED_Refresh_Gram();
while(1);
}
}
OLED_ShowFontHZ(X_WIDTH-40,10,13,16,1);//第
OLED_ShowNum(X_WIDTH-24,10,glevel+1,1,16);
OLED_ShowFontHZ(X_WIDTH-16,10,14,16,1);//关
// gkey_value=KEY_Scan(0);
game_draw();//游戏界面绘制
key_event();//按键消息处理
}
}
三、实验现象
B站演示视频:https://space.bilibili.com/444388619
联系作者
视频地址:https://space.bilibili.com/444388619/video
专注于51单片机、STM32、国产32、DSP、Proteus、arduino、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。