谷歌小恐龙技巧(基于STM32的小游戏——谷歌小恐龙(Chrome Dino Game))
前言:使用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 ,这里取KEY0和KEY1 。KEY0和KEY1按下后为低电平有效 。(这里读者朋友可以根据实际情况去设置)
四 、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); #endifoled.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(); #endifdinogame.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版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!