实验原理:
1、 OLED通过SPI2显示游戏画面(使用了某商家驱动,包括oled.c、oled.h、oledfont.h)
2、 矩阵键盘实现按键事件判断(只用矩阵键盘行2、行3)3、贪吃蛇游戏的原理是普通的贪吃蛇游戏的算法
实验设计:
OLED按照下图连
蛇的最大长度为36个方块
蛇由方块(8×8像素,填充部分为6×6像素)组成,撑满围墙内需要36块食物为一个方块(8×8像素,填充部分为2×2像素)
关于这个的贪吃蛇游戏的规则:
初始长度为3,方向为右商家给的驱动没有图片显示,于是写了个简单粗暴的图片显示函数,定义在oled.c里,顺便在oled.h中声明(图片取模后就存在一个数组里。。。我放在了oledfont.h里)
//画图
void OLED_PIC1616(const unsigned char pic[][16]){
int i,j,k,temp;
for(i=0;i<64;i++){
for(j=0;j<16;j++){
temp=pic[i][j];
for(k=0;k<8;k++){
OLED_DrawPoint(j*8+k,i,temp&0x80); //写好的设置单个像素是否填充的函数
temp=temp<<1;
}
}
}
}
图片取模方式如下(至于阴码、阳码,根据具体的效果来选):
原图(阳码):
显示效果:
3、写代码测试
修复了一些bug
/* USER CODE BEGIN Includes */
#include "oled.h"
#include
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
extern const unsigned char pic1[][16]; //title图片
extern const unsigned char pic2[][16]; //lose图片
extern const unsigned char pic3[][16]; //win图片
const uint16_t gpio[]={GPIO_PIN_4,GPIO_PIN_5,GPIO_PIN_6,GPIO_PIN_7};
const char key5[]={'d','s','a','o'}; //d:right a:left w:up s:down o:ok
uint8_t scene=0; //0:title 1:help 2:game
uint8_t select=0; //0:run game 1:run help
uint8_t length=3; //蛇的长度
//以下坐标都是方块左上角坐标
uint8_t head_x=32; //头部方块x坐标
uint8_t head_y=24; //头部方块y坐标
uint8_t snake_x[36]={32,24,16}; //身体方块x坐标
uint8_t snake_y[36]={24,24,24}; //身体方块y坐标
uint8_t direction='d'; //方向
uint8_t food=1;//判断食物存在
uint8_t food_x;//食物x坐标
uint8_t food_y;//食物y坐标
char score[3];//分数(长度)【用于打印】
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void draw_food(void);
void draw_score(void);
void generateFood(void);
void snake_init(void);
uint8_t game(void);
void init_title(void);
/* USER CODE END PFP */
/* USER CODE BEGIN 2 */
__HAL_SPI_ENABLE(&hspi2);
OLED_Init();//初始化OLED
srand(1);
init_title();
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */
if(scene==2){
uint8_t flag;
snake_init();
while(1){ //游戏循环
HAL_Delay(1000);
flag=game();
if(flag==0){
OLED_PIC1616(pic2);
HAL_Delay(5000);
init_title();
scene=0;
break;
}
else if(flag==2){
OLED_PIC1616(pic3);
HAL_Delay(5000);
init_title();
scene=0;
break;
}
}
}
}
/* USER CODE END 3 */
/* USER CODE BEGIN 4 */
//画出标题界面
void init_title(void){
OLED_Clear();
OLED_PIC1616(pic1);
OLED_ShowString(64,4,"play",16);
OLED_ShowString(64,24,"help",16);
OLED_ShowString(104,20*select+4,"<-",16);
}
//画食物
void draw_food(void){
OLED_Fill(food_x+3,food_y+3,food_x+5,food_y+5,1);
}
//写分数
void draw_score(void){
sprintf(score,"%d",length);
OLED_ShowString(64,24,score,16);
}
//生成食物坐标
void generateFood(void){
int i;
do{
food_x=8*(rand()%6)+8;
food_y=8*(rand()%6)+8;
for(i=0;i=0;i--){
snake_x[i+1]=snake_x[i];
snake_y[i+1]=snake_y[i];
}
snake_x[0]=head_x;
snake_y[0]=head_y;
//撞身判断
for(i=1;i
实验成果:
基本实现了游戏功能,然而这个游戏还是有bug的(比如长按按键可以暂停、可以快速掉头进行自杀),暂时没改。