首页IT科技谷歌小恐龙技巧(基于STM32的小游戏——谷歌小恐龙(Chrome Dino Game))

谷歌小恐龙技巧(基于STM32的小游戏——谷歌小恐龙(Chrome Dino Game))

时间2025-08-04 04:35:28分类IT科技浏览6053
导读: 前言:使用STM32的显示屏其实可以开发出许多...

        前言:使用STM32的显示屏其实可以开发出许多有趣的小项目               ,比如:多功能菜单                       ,小游戏等等               。其中       ,STM32F1XX由于Cortex-M3芯片的性能一般计算量与内存)        ,所以能够实现的小游戏不多                       ,较为常见的:贪吃蛇               ,俄罗斯方块        ,飞机大战等                       。本文将给大家实现一款较为新颖的小游戏——谷歌小恐龙(Chrome Dino Game)       。简单使用0.96寸OLED屏幕搭配STM32F1系列的MCU就可以实现                       ,硬件要求很低        。(本游戏代码基于HAL库实现               ,文末有代码开源

        实验硬件:STM32F103ZET6;0.96寸OLED;2个KEY按键

        硬件实物图:

        效果图:

引脚连接:

OLED模块:

VCC --> 3.3V

GND --> GND

SCL --> PB10

SDA --> PB11

KEY按键模块:

KEY0 --> PE3

KEY1 --> PE4

注意:这里按键直接采用了正点原子精英板上的固有按键,自己打板的话                       ,视情况下而定                       。

一                、谷歌小恐龙(Chrome Dino Game)简介

        谷歌小恐龙(Chrome Dino Game)顾名思义是由Google公司首创出来的小游戏               。其初始目的为在Google浏览器出现互联网信号丢失时                       ,排解用户等待联网信号时的无聊难受        。

        这个游戏的最大优点是它可以在没有互联网的情况下玩                       。这是Chrome浏览器中一款原始的无止境跑步游戏               。主角是一只可爱的霸王龙,它在古老的沙漠中小跑。当然               ,恐龙游戏有它的目的:避免仙人掌翼手龙                       。虽然游戏看起来很简单                       ,但并不需要很长时间就能变得很难       ,因为游戏的速度会随着你的进步而不断提高                       。

        本文就以谷歌小恐龙(Chrome Dino Game)游戏为原型               ,使用STM32于0.96寸OLED屏幕上尽可能地复现了谷歌小恐龙游戏。

谷歌小恐龙(Chrome Dino Game)实机效果:

 原游戏网址:谷歌小恐龙在线 - 免费玩谷歌小恐龙 (dino.zone)

二                      、OLED简介

        关于OLED的使用与原理不熟悉的笔者欢迎去笔者另一篇文章学习                       ,由于篇幅问题       ,这里就不过多讲诉               。

【强烈推荐】基于stm32的OLED各种显示实现(含动态图)_混分巨兽龙某某的博客-CSDN博客_oled显示stm32https://blog.csdn.net/black_sneak/article/details/125418537?spm=1001.2014.3001.5501

三       、KEY按键

        开发板上除了有经典的流水灯之外        ,还有一个必备的练习硬件--按键(key)                       。

        正常地独立按键KEY其实使用很简单                       ,就是基于GPIO引脚的读取操作       。唯一需要注意的点:按键按下去之后到底时低电平还是高电平               。

        笔者这里直接使用了正点原子精英版STM32上的按键KEY               ,按键原理图如下:

        考虑到本次小游戏只使用2个按键KEY        ,这里取KEY0KEY1                       。KEY0KEY1按下后为低电平有效       。(这里读者朋友可以根据实际情况去设置

四                、CubeMX配置

1                       、RCC配置外部高速晶振(精度更高)——HSE;

2       、SYS配置:Debug设置成Serial Wire否则可能导致芯片自锁);

 3        、I2C2配置:这里不直接使用CubeMX的I2C2                       ,使用GPIO模拟(PB10:CLK;PB11:SDA)

4                       、KEY按键配置:PE3与PE4设置为端口输入(开发板原理图)

5               、时钟树配置:

6        、工程配置 

五                       、代码讲解

5.1 OLED驱动代码

        此部分OLED的基本驱动函数               ,笔者使用的是I2C驱动的0.96寸OLED屏幕        。所以,首先需要使用GPIO模拟I2C通讯                       。随后                       ,使用I2C通讯去驱动OLED               。(此部分代码包含了屏幕驱动基础显示                       ,如果对OLED显示不太理解的朋友可以去看看上文提到的笔者的另一篇文章

oled.h:

#ifndef __OLED_H #define __OLED_H #include "main.h" #define u8 uint8_t #define u32 uint32_t #define OLED_CMD 0 //写命令 #define OLED_DATA 1 //写数据 #define OLED0561_ADD 0x78 // OLED I2C地址 #define COM 0x00 // OLED #define DAT 0x40 // OLED #define OLED_MODE 0 #define SIZE 8 #define XLevelL 0x00 #define XLevelH 0x10 #define Max_Column 128 #define Max_Row 64 #define Brightness 0xFF #define X_WIDTH 128 #define Y_WIDTH 64 //-----------------OLED IIC GPIO进行模拟---------------- #define OLED_SCLK_Clr() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET) //GPIO_ResetBits(GPIOB,GPIO_Pin_10)//SCL #define OLED_SCLK_Set() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET) //GPIO_SetBits(GPIOB,GPIO_Pin_10) #define OLED_SDIN_Clr() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET) // GPIO_ResetBits(GPIOB,GPIO_Pin_11)//SDA #define OLED_SDIN_Set() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET) // GPIO_SetBits(GPIOB,GPIO_Pin_11) //I2C GPIO模拟 void IIC_Start(); void IIC_Stop(); void IIC_WaitAck(); void IIC_WriteByte(unsigned char IIC_Byte); void IIC_WriteCommand(unsigned char IIC_Command); void IIC_WriteData(unsigned char IIC_Data); void OLED_WR_Byte(unsigned dat,unsigned cmd); //功能函数 void OLED_Init(void); void OLED_WR_Byte(unsigned dat,unsigned cmd); void OLED_FillPicture(unsigned char fill_Data); void OLED_SetPos(unsigned char x, unsigned char y); void OLED_DisplayOn(void); void OLED_DisplayOff(void); void OLED_Clear(void); void OLED_On(void); void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size); u32 oled_pow(u8 m,u8 n); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2); void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size); #endif

oled.c:

#include "oled.h" #include "asc.h" //字库(可以自己制作) #include "main.h" /********************GPIO 模拟I2C*******************/ //注意:这里没有直接使用HAL库中的模拟I2C /********************************************** //IIC Start **********************************************/ void IIC_Start() { OLED_SCLK_Set() ; OLED_SDIN_Set(); OLED_SDIN_Clr(); OLED_SCLK_Clr(); } /********************************************** //IIC Stop **********************************************/ void IIC_Stop() { OLED_SCLK_Set() ; OLED_SDIN_Clr(); OLED_SDIN_Set(); } void IIC_WaitAck() { OLED_SCLK_Set() ; OLED_SCLK_Clr(); } /********************************************** // IIC Write byte **********************************************/ void IIC_WriteByte(unsigned char IIC_Byte) { unsigned char i; unsigned char m,da; da=IIC_Byte; OLED_SCLK_Clr(); for(i=0;i<8;i++) { m=da; // OLED_SCLK_Clr(); m=m&0x80; if(m==0x80) {OLED_SDIN_Set();} else OLED_SDIN_Clr(); da=da<<1; OLED_SCLK_Set(); OLED_SCLK_Clr(); } } /********************************************** // IIC Write Command **********************************************/ void IIC_WriteCommand(unsigned char IIC_Command) { IIC_Start(); IIC_WriteByte(0x78); //Slave address,SA0=0 IIC_WaitAck(); IIC_WriteByte(0x00); //write command IIC_WaitAck(); IIC_WriteByte(IIC_Command); IIC_WaitAck(); IIC_Stop(); } /********************************************** // IIC Write Data **********************************************/ void IIC_WriteData(unsigned char IIC_Data) { IIC_Start(); IIC_WriteByte(0x78); //D/C#=0; R/W#=0 IIC_WaitAck(); IIC_WriteByte(0x40); //write data IIC_WaitAck(); IIC_WriteByte(IIC_Data); IIC_WaitAck(); IIC_Stop(); } void OLED_WR_Byte(unsigned dat,unsigned cmd) { if(cmd) { IIC_WriteData(dat); } else { IIC_WriteCommand(dat); } } void OLED_Init(void) { HAL_Delay(100); //这个延迟很重要 OLED_WR_Byte(0xAE,OLED_CMD);//--display off OLED_WR_Byte(0x00,OLED_CMD);//---set low column address OLED_WR_Byte(0x10,OLED_CMD);//---set high column address OLED_WR_Byte(0x40,OLED_CMD);//--set start line address OLED_WR_Byte(0xB0,OLED_CMD);//--set page address OLED_WR_Byte(0x81,OLED_CMD); // contract control OLED_WR_Byte(0xFF,OLED_CMD);//--128 OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64) OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset OLED_WR_Byte(0x00,OLED_CMD);// OLED_WR_Byte(0xD5,OLED_CMD);//set osc division OLED_WR_Byte(0x80,OLED_CMD);// OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off OLED_WR_Byte(0x05,OLED_CMD);// OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period OLED_WR_Byte(0xF1,OLED_CMD);// OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion OLED_WR_Byte(0x12,OLED_CMD);// OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh OLED_WR_Byte(0x30,OLED_CMD);// OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable OLED_WR_Byte(0x14,OLED_CMD);// OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel HAL_Delay(100); OLED_FillPicture(0x0); } /******************************************** // OLED_FillPicture ********************************************/ void OLED_FillPicture(unsigned char fill_Data) { unsigned char m,n; for(m=0;m<8;m++) { OLED_WR_Byte(0xb0+m,0); //page0-page1 OLED_WR_Byte(0x00,0); //low column start address OLED_WR_Byte(0x10,0); //high column start address for(n=0;n<128;n++) { OLED_WR_Byte(fill_Data,1); } } } //坐标设置 void OLED_SetPos(unsigned char x, unsigned char y) { OLED_WR_Byte(0xb0+y,OLED_CMD); OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD); OLED_WR_Byte((x&0x0f),OLED_CMD); } //开启OLED显示 void OLED_DisplayOn(void) { OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令 OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON } //关闭OLED显示 void OLED_DisplayOff(void) { OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令 OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF } //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!! void OLED_Clear(void) { u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7) OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址 OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); } //更新显示 } void OLED_On(void) { u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7) OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址 OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA); } //更新显示 } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size) { unsigned char c=0,i=0; c=chr- ;//得到偏移后的值 if(x>Max_Column-1){x=0;y=y+2;} if(Char_Size ==16) { OLED_SetPos(x,y); for(i=0;i<8;i++) OLED_WR_Byte(F8X16[c*16+i],OLED_DATA); OLED_SetPos(x,y+1); for(i=0;i<8;i++) OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA); } else { OLED_SetPos(x,y); for(i=0;i<6;i++) OLED_WR_Byte(F6x8[c][i],OLED_DATA); } } //m^n函数 u32 oled_pow(u8 m,u8 n) { u32 result=1; while(n--)result*=m; return result; } //显示2个数字 //x,y :起点坐标 //len :数字的位数 //size:字体大小 //mode:模式 0,填充模式;1,叠加模式 //num:数值(0~4294967295); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2) { u8 t,temp; u8 enshow=0; for(t=0;t<len;t++) { temp=(num/oled_pow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { // OLED_ShowChar(x+(size2/2)*t,y, ,size2); OLED_ShowChar(x+(size2/2)*t,y,0,size2); continue; }else enshow=1; } OLED_ShowChar(x+(size2/2)*t,y,temp+0,size2); } } //显示一个字符号串 void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size) { unsigned char j=0; while (chr[j]!=\0) { OLED_ShowChar(x,y,chr[j],Char_Size); x+=8; if(x>120){x=0;y+=2;} j++; } }

5.2 谷歌小恐龙游戏图形绘制代码

        该部分为整个项目代码的核心部分之一,任何一个游戏都是需要去绘制构建游戏的图形以及模型的        。好的游戏往往都具有很好的游戏模型精美UI               ,很多3A大作都具备这样的特性                       。

dinogame.h:

#ifndef __DINOGAME_H #define __DINOGAME_H void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]); void OLED_DrawBMPFast(const unsigned char BMP[]); void oled_drawbmp_block_clear(int bx, int by, int clear_size); void OLED_DrawGround(); void OLED_DrawCloud(); void OLED_DrawDino(); void OLED_DrawCactus(); int OLED_DrawCactusRandom(unsigned char ver, unsigned char reset); int OLED_DrawDinoJump(char reset); void OLED_DrawRestart(); void OLED_DrawCover(); #endif

dinogame.c代码:

#include "oled.h" #include "oledfont.h" #include "stdlib.h" /***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127                       ,y为页的范围0~7*****************/ void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]) { unsigned int j=0; unsigned char x,y; if(y1%8==0) y=y1/8; else y=y1/8+1; for(y=y0;y<y1;y++) { OLED_SetPos(x0,y); for(x=x0;x<x1;x++) { OLED_WR_Byte(BMP[j++],OLED_DATA); } } } // 快速绘制图像 void OLED_DrawBMPFast(const unsigned char BMP[]) { unsigned int j = 0; unsigned char x, y; for (y = 0; y < 8; y++) { OLED_SetPos(0, y); IIC_Start(); IIC_WriteByte(0x78); IIC_WaitAck(); IIC_WriteByte(0x40); IIC_WaitAck(); for (x = 0; x < 128; x++) { IIC_WriteByte(BMP[j++]); IIC_WaitAck(); } IIC_Stop(); } } void oled_drawbmp_block_clear(int bx, int by, int clear_size) { unsigned int i; OLED_SetPos(bx, by); IIC_Start(); IIC_WriteByte(0x78); IIC_WaitAck(); IIC_WriteByte(0x40); IIC_WaitAck(); for (i = 0; i < clear_size; i++) { if (bx + i>128) break; IIC_WriteByte(0x0); IIC_WaitAck(); } IIC_Stop(); } void OLED_DrawGround() { static unsigned int pos = 0; unsigned char speed = 5; unsigned int ground_length = sizeof(GROUND); unsigned char x; OLED_SetPos(0, 7); IIC_Start(); IIC_WriteByte(0x78); IIC_WaitAck(); IIC_WriteByte(0x40); IIC_WaitAck(); for (x = 0; x < 128; x++) { IIC_WriteByte(GROUND[(x+pos)%ground_length]); IIC_WaitAck(); } IIC_Stop(); pos = pos + speed; //if(pos>ground_length) pos=0; } // 绘制云朵 void OLED_DrawCloud() { static int pos = 128; static char height=0; char speed = 3; unsigned int i=0; int x; int start_x = 0; int length = sizeof(CLOUD); unsigned char byte; //if (pos + length <= -speed) pos = 128; if (pos + length <= -speed) { pos = 128; height = rand()%3; } if(pos < 0) { start_x = -pos; OLED_SetPos(0, 1+height); } else { OLED_SetPos(pos, 1+height); } IIC_Start(); IIC_WriteByte(0x78); IIC_WaitAck(); IIC_WriteByte(0x40); IIC_WaitAck(); for (x = start_x; x < length + speed; x++) { if (pos + x > 127) break; if (x < length) byte = CLOUD[x]; else byte = 0x0; IIC_WriteByte(byte); IIC_WaitAck(); } IIC_Stop(); pos = pos - speed; } // 绘制小恐龙 void OLED_DrawDino() { static unsigned char dino_dir = 0; unsigned int j=0; unsigned char x, y; unsigned char byte; dino_dir++; dino_dir = dino_dir%2; for(y=0; y<2; y++) { OLED_SetPos(16, 6+y); IIC_Start(); IIC_WriteByte(0x78); IIC_WaitAck(); IIC_WriteByte(0x40); IIC_WaitAck(); for (x = 0; x < 16; x++) { j = y*16 + x; byte = DINO[dino_dir][j]; IIC_WriteByte(byte); IIC_WaitAck(); } IIC_Stop(); } } // 绘制仙人掌障碍物 void OLED_DrawCactus() { char speed = 5; static int pos = 128; int start_x = 0; int length = sizeof(CACTUS_2)/2; unsigned int j=0; unsigned char x, y; unsigned char byte; if (pos + length <= 0) { oled_drawbmp_block_clear(0, 6, speed); pos = 128; } for(y=0; y<2; y++) { if(pos < 0) { start_x = -pos; OLED_SetPos(0, 6+y); } else { OLED_SetPos(pos, 6+y); } IIC_Start(); IIC_WriteByte(0x78); IIC_WaitAck(); IIC_WriteByte(0x40); IIC_WaitAck(); for (x = start_x; x < length; x++) { if (pos + x > 127) break; j = y*length + x; byte = CACTUS_2[j]; IIC_WriteByte(byte); IIC_WaitAck(); } IIC_Stop(); } oled_drawbmp_block_clear(pos + length, 6, speed); // 清除残影 pos = pos - speed; } // 绘制随机出现的仙人掌障碍物 int OLED_DrawCactusRandom(unsigned char ver, unsigned char reset) { char speed = 5; static int pos = 128; int start_x = 0; int length = 0; unsigned int i=0, j=0; unsigned char x, y; unsigned char byte; if (reset == 1) { pos = 128; oled_drawbmp_block_clear(0, 6, speed); return 128; } if (ver == 0) length = 8; //sizeof(CACTUS_1) / 2; else if (ver == 1) length = 16; //sizeof(CACTUS_2) / 2; else if (ver == 2 || ver == 3) length = 24; for(y=0; y<2; y++) { if(pos < 0) { start_x = -pos; OLED_SetPos(0, 6+y); } else { OLED_SetPos(pos, 6+y); } IIC_Start(); IIC_WriteByte(0x78); IIC_WaitAck(); IIC_WriteByte(0x40); IIC_WaitAck(); for (x = start_x; x < length; x++) { if (pos + x > 127) break; j = y*length + x; if (ver == 0) byte = CACTUS_1[j]; else if (ver == 1) byte = CACTUS_2[j]; else if(ver == 2) byte = CACTUS_3[j]; else byte = CACTUS_4[j]; IIC_WriteByte(byte); IIC_WaitAck(); } IIC_Stop(); } oled_drawbmp_block_clear(pos + length, 6, speed); pos = pos - speed; return pos + speed; } // 绘制跳跃小恐龙 int OLED_DrawDinoJump(char reset) { char speed_arr[] = {1, 1, 3, 3, 4, 4, 5, 6, 7}; static char speed_idx = sizeof(speed_arr)-1; static int height = 0; static char dir = 0; //char speed = 4; unsigned int j=0; unsigned char x, y; char offset = 0; unsigned char byte; if(reset == 1) { height = 0; dir = 0; speed_idx = sizeof(speed_arr)-1; return 0; } if (dir==0) { height += speed_arr[speed_idx]; speed_idx --; if (speed_idx<0) speed_idx = 0; } if (dir==1) { height -= speed_arr[speed_idx]; speed_idx ++; if (speed_idx>sizeof(speed_arr)-1) speed_idx = sizeof(speed_arr)-1; } if(height >= 31) { dir = 1; height = 31; } if(height <= 0) { dir = 0; height = 0; } if(height <= 7) offset = 0; else if(height <= 15) offset = 1; else if(height <= 23) offset = 2; else if(height <= 31) offset = 3; else offset = 4; for(y=0; y<3; y++) // 4 { OLED_SetPos(16, 5- offset + y); IIC_Start(); IIC_WriteByte(0x78); IIC_WaitAck(); IIC_WriteByte(0x40); IIC_WaitAck(); for (x = 0; x < 16; x++) // 32 { j = y*16 + x; // 32 byte = DINO_JUMP[height%8][j]; IIC_WriteByte(byte); IIC_WaitAck(); } IIC_Stop(); } if (dir == 0) oled_drawbmp_block_clear(16, 8- offset, 16); if (dir == 1) oled_drawbmp_block_clear(16, 4- offset, 16); return height; } // 绘制重启 void OLED_DrawRestart() { unsigned int j=0; unsigned char x, y; unsigned char byte; //OLED_SetPos(0, 0); for (y = 2; y < 5; y++) { OLED_SetPos(52, y); IIC_Start(); IIC_WriteByte(0x78); IIC_WaitAck(); IIC_WriteByte(0x40); IIC_WaitAck(); for (x = 0; x < 24; x++) { byte = RESTART[j++]; IIC_WriteByte(byte); IIC_WaitAck(); } IIC_Stop(); } OLED_ShowString(10, 3, "GAME", 16); OLED_ShowString(86, 3, "OVER", 16); } // 绘制封面 void OLED_DrawCover() { OLED_DrawBMPFast(COVER); }

        此部分函数主要是实现快速绘制出游戏所需要的模型组件       ,模型包括:游戏初始化封面               ,游戏结束封面                       ,小恐龙(跳跃的小恐龙)       ,沙漠地面        ,随机出现的仙人掌障碍物(1                       ,2               ,3个)        ,云朵等               。

注意:此部分绘制的属于动态化图片绘制                       ,所绘制的图片会自右向左移动。

        关于游戏模型基础组件               ,采用Img2Lcd2.9软件对图片进行取模,注意考虑到0.96寸的OLED屏幕大小有限                       ,取模图片尽可能小一点                       。

例子:

        取模小恐龙模组:

         Img2Lcd2.9软件如下操作取模:

        其余                       ,游戏图片模组依此法进行取模,注意图片取得的大小                       。

游戏图片取模库oledfont.h:

#ifndef __OLEDFONT_H #define __OLEDFONT_H //该文件主要为DinoGame的图像库 /************************************6*8???************************************/ const unsigned char GROUND[] = { 0xc8, 0xc8, 0xc8, 0x28, 0x28, 0x28, 0x8, 0xc8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x8, 0x8, 0xc8, 0xc8, 0xc8, 0x8, 0x38, 0x38, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x8, 0x48, 0x48, 0x48, 0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x38, 0x38, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x8, 0x28, 0x28, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x8, 0x8, 0x8, 0x8, 0x38, 0x38, 0x8, 0x68, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0xc8, 0xc8, 0x8, 0x9, 0x8, 0x8, 0x8, 0x8, 0x8, 0x38, 0x38, 0x8, 0x8, 0x28, 0x8, 0x9, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x8, 0x8, 0x9, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x68, 0x8, 0xc9, 0xc8, 0xc8, 0x8, 0x8, 0x8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x29, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x49, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x68, 0x8, 0x8, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x68, 0x8, 0x8, 0xc8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x28, 0x8, 0x8, 0x48, 0x8, 0x38, 0x38, 0x8, 0x8, 0x8, 0x8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x8, 0xc8, 0xc8, 0xc8, 0x28, 0x28, 0x28, 0x8, 0xc8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x48, 0x8, 0x8, 0xc8, 0xc8, 0xc8, 0x8, 0x38, 0x38, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x48, 0x48, 0x48, 0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0xc8, 0x8, 0x8, 0x8, 0xc, 0x6, 0x2, 0x42, 0x42, 0x6, 0xc, 0x8, 0x8, 0x8, 0x8, 0x38, 0x38, 0x8, 0x18, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x18, 0x8, 0x48, 0x8, 0x28, 0x28, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0x38, 0x38, 0x68, 0x68, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x68, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0xc8, 0xc8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x38, 0x38, 0x8, 0x8, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x68, 0x8, 0xc8, 0xc8, 0xc8, 0x8, 0x8, 0x8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0xc, 0x4, 0x6, 0x2, 0x2, 0x6, 0xc, 0x4c, 0x48, 0x8, 0x8, 0x8, 0xc, 0x4, 0x6, 0x2, 0x2, 0x6, 0xc, 0xc, 0x68, 0x68, 0x8, 0x28, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x68, 0x68, 0x68, 0x8, 0x8, 0xc8, 0xc8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x28, 0x28, 0x8, 0x8, 0x8, 0x8, 0x8, 0x28, 0x28, 0x28, 0x8, 0x8, 0x48, 0x28, 0x38, 0x38, 0x8, 0x8, 0x8, 0x8, 0xc8, 0x8, 0x8, }; const unsigned char CLOUD[] = { 0x80, 0xc0, 0xe0, 0x70, 0xb0, 0xb0, 0xb0, 0x98, 0x88, 0x8e, 0x83, 0x83, 0x83, 0x81, 0x81, 0x93, 0x8e, 0x8c, 0x88, 0x88, 0x98, 0xb0, 0xf0, 0xc0 }; const unsigned char DINO[2][32] = { 0xe0, 0x80, 0x0, 0x0, 0x0, 0x80, 0xc0, 0xe0, 0xfe, 0xff, 0xfd, 0xbf, 0xaf, 0x2f, 0x2f, 0xe, 0x3, 0x7, 0xf, 0x1e, 0xff, 0xbf, 0x1f, 0x1f, 0x3f, 0x2f, 0x7, 0x0, 0x1, 0x0, 0x0, 0x0, 0xe0, 0x80, 0x0, 0x0, 0x0, 0x80, 0xc0, 0xe0, 0xfe, 0xff, 0xfd, 0xbf, 0xaf, 0x2f, 0x2f, 0xe, 0x3, 0x7, 0xf, 0x1e, 0x3f, 0x7f, 0x5f, 0x3f, 0xff, 0x8f, 0x7, 0x0, 0x1, 0x0, 0x0, 0x0 }; const unsigned char DINO_JUMP[8][48] = // { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x80, 0x0, 0x0, 0x0, 0x80, 0xc0, 0xc0, 0xfe, 0xff, 0xfd, 0xbf, 0xaf, 0x2f, 0x2f, 0xe, 0x3, 0x7, 0xf, 0x1f, 0xff, 0xbf, 0x1f, 0x3f, 0xff, 0x8f, 0x7, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0, 0xf0, 0xc0, 0x80, 0x80, 0x80, 0xc0, 0xe0, 0xe0, 0xff, 0xff, 0xfe, 0x5f, 0xd7, 0x17, 0x17, 0x7, 0x1, 0x3, 0x7, 0xf, 0x7f, 0x5f, 0xf, 0x1f, 0x7f, 0x47, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xc0, 0x40, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0xf8, 0xe0, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0x2f, 0x6b, 0xb, 0xb, 0x3, 0x0, 0x1, 0x3, 0x7, 0x3f, 0x2f, 0x7, 0xf, 0x3f, 0x23, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xe0, 0xa0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0x7c, 0xf0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf8, 0xf8, 0xff, 0xff, 0xff, 0x17, 0x35, 0x5, 0x5, 0x1, 0x0, 0x0, 0x1, 0x3, 0x1f, 0x17, 0x3, 0x7, 0x1f, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xf0, 0xd0, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, 0x3e, 0x78, 0xf0, 0xf0, 0xf0, 0xf8, 0xfc, 0xfc, 0xff, 0xff, 0x7f, 0xb, 0x1a, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x1, 0xf, 0xb, 0x1, 0x3, 0xf, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xf8, 0xe8, 0xf8, 0x78, 0x78, 0x78, 0x70, 0x1f, 0x3c, 0x78, 0xf8, 0xf8, 0xfc, 0xfe, 0xfe, 0xff, 0x7f, 0x3f, 0x5, 0xd, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x5, 0x0, 0x1, 0x7, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0xfc, 0xf4, 0xfc, 0xbc, 0xbc, 0xbc, 0x38, 0xf, 0x1e, 0x3c, 0x7c, 0xfc, 0xfe, 0x7f, 0xff, 0xff, 0x3f, 0x1f, 0x2, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x2, 0x0, 0x0, 0x3, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0xfc, 0xfe, 0xfa, 0x7e, 0x5e, 0x5e, 0x5e, 0x1c, 0x7, 0xf, 0x1e, 0x3e, 0xfe, 0x7f, 0x3f, 0x7f, 0xff, 0x1f, 0xf, 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; const unsigned char CACTUS_1[] = { 0xf0, 0xf0, 0x0, 0xff, 0xff, 0x0, 0xf0, 0xf0, 0x3, 0x7, 0x86, 0xff, 0xff, 0x6, 0x3, 0x1 }; const unsigned char CACTUS_2[] = { 0xf0, 0xe0, 0x0, 0xff, 0xfe, 0x80, 0xfc, 0x0, 0x0, 0x7c, 0xc0, 0xfe, 0xff, 0x0, 0x80, 0xfc, 0x3, 0x7, 0x6, 0xff, 0xff, 0x1, 0x10, 0x90, 0x90, 0x90, 0x0, 0xff, 0xff, 0x3, 0x3, 0x1 }; const unsigned char CACTUS_3[] = { 0xf0, 0xe0, 0x0, 0xff, 0xfe, 0x80, 0xfc, 0x0, 0xfc, 0xfe, 0x0, 0xff, 0xff, 0x0, 0xf8, 0xf0, 0x0, 0xfe, 0x80, 0xfe, 0xff, 0xfe, 0x78, 0xfc, 0x13, 0x17, 0x6, 0xff, 0xff, 0x1, 0x10, 0x10, 0x13, 0x37, 0x4, 0xff, 0xff, 0x8, 0xf, 0x17, 0x10, 0x10, 0x1, 0xff, 0xff, 0x3, 0x13, 0x11 }; const unsigned char CACTUS_4[] = { 0xf0, 0xe0, 0x0, 0xff, 0xfe, 0x0, 0xf0, 0x0, 0xc0, 0x0, 0xff, 0xfe, 0x60, 0x3c, 0x80, 0x0, 0x0, 0x7c, 0xc0, 0xfe, 0xff, 0x0, 0xf0, 0xf8, 0x43, 0x47, 0x86, 0xff, 0xff, 0x26, 0xa3, 0xa0, 0x27, 0x4, 0xff, 0xff, 0x0, 0x8, 0xff, 0x88, 0x2f, 0x0, 0x0, 0xff, 0xff, 0x6, 0x23, 0x21 }; const unsigned char RESTART[] = { 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0x3f, 0x3f, 0xf, 0x1f, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x7e, 0x7e, 0x7e, 0x78, 0x7c, 0x7e, 0x7f, 0x7f, 0x7f, 0x7e, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, }; const unsigned char COVER[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x0, 0x0, 0xf0, 0xf0, 0xc0, 0xc0, 0xf0, 0xf0, 0x0, 0x0, 0xf0, 0xf0, 0xb0, 0xb0, 0x70, 0x60, 0x0, 0x0, 0xe0, 0xf0, 0x30, 0x30, 0xf0, 0xe0, 0x0, 0x0, 0xf0, 0xf0, 0x30, 0xf0, 0xf0, 0x30, 0xf0, 0xe0, 0x0, 0xe0, 0xe0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80,

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
vuetorrent(谈谈 Vue toRef 和 reactive) win10查看开机启动(Windows10如何显示启动/关机的详细信息)