【平头哥RVB2601创意应用开发】掌上游戏机(2)对眼儿画图记
[复制链接]
本帖最后由 nemon 于 2022-6-5 12:16 编辑
先说我想做的这个游戏吧。
在遥远的上世纪,最早的电子游戏是PinPong,后来是任天堂8位机、街机的时代(表抬杠,偶知道“小霸王其乐无穷”滴)。
我觉得游戏是真正和硬件同时跑起来的,曾经有过多少人升级电脑只为打游戏啊……
智能手机的出现,让游戏更加普及,游戏时间更加碎片化。2014年2月越南的独立游戏开发者Dong Nguyen所的作品《flappy bird》突然暴红。
游戏中玩家需要控制一只小鸟,跨越由各种不同长度水管所组成的障碍。这个游戏只要一种控制方式,就是点一下就能让小鸟上升一点。而下降,全靠时间推移,小鸟下落。
看到没,只要1个按键啊,就是他了!
做游戏先要解决素材问题,好在这只鸟的像素风格玉照还挺多,主要是把翅膀抠出来,回头做成动画。
于是用excel来画图,把单元格设成条件格式:0是浅灰,1是纯黑,2是泛绿,分别表示白、黑、透明。(哇咔咔,偶的位图一开始就支持透明色,听上去很高级呢)。
再加上地面、水管(分头部和管体),配上欢迎页、结束页,图片素材就够了。
长时间盯着屏幕,一个像素一个像素的的画,太费眼了。可是也没有办法,因为还有更艰巨的任务——文字。
把官方Demo都过了一遍,感觉lvgl干这个活有点大材小用外加浪费存储资源。于是决定自己来实现。
由于官方例程有oled的驱动(这个也要改,后边再说),所以首先关注在位图和字体的定义——
/*========= 华丽的分割线又出现了,去喝点水吧,下面的内容太干了 ========*/
位图头文件Image.h很简单:
#ifndef _APP_IMAGE_H_
#define _APP_IMAGE_H_
/* */
#include <stdint.h>
#define IMAGE_POT(img,x,y) ( img->data [ y * ( img->width) +x])//
typedef enum IMAGE_COLOR{
WHITE=0, // 白色
BLACK=1, // 黑色
HYALINE=2, // 透明色
REVERSE=3 // 反转色
}color;
typedef struct IMAGE{
uint8_t width;
uint8_t height;
uint8_t *data;
}bit_map;
bit_map* image_create_function(uint8_t height,uint8_t width,uint8_t* data);
void image_destory_function(bit_map *img);
bit_map* image_right2left_function(bit_map* img);
bit_map* image_bottom2top_function(bit_map* img);
bit_map* image_rotate180_function(bit_map* img);
bit_map* image_right90_function(bit_map* img);
bit_map* image_turnleft90_function(bit_map* img);
/* */
#endif
枚举类型IMAGE_COLOR前面介绍过了,注释也写的清楚,就不多说了。
结构体IMAGE包含3个子元素:位图宽,位图高,数据数组。此处为了简化多维数组处理,数据用了一维数组,于是就定义了一个宏 IMAGE_POT,用于将二维的表示法转为一维的定义。
各API说明:
image_create_function 用数据创建位图,如果只提供了大小,可以创建空白图片。
image_destory_function 销毁位图,主要作用是释放位图占用的内存。C语言,不能自动destory,得手动。
下面的5个作用分别是:水平翻转、垂直翻转、旋转180度、右转90度、左转90度。
写了这么多,后来发现,由于本人实在太抠,根本不建新图片,也不做图像处理,所以真正用上的,竟然只是枚举、结构体、宏处理这3个定义。
字体的重点不大一样。虽然也是图片。但是因为字体是在打印之前,需要从“字库”里被检索出来。因此头文件Font.h是这样的:
#ifndef _APP_FONT_H_
#define _APP_FONT_H_
#include "Image.h"
bit_map* font_get_char_function(char c);
#endif
很简单吧,就是传一个字符进来,然后返回对应的点阵位图。所以Font.c很重要:
#include "Font.h"
const static uint8_t _font_char_0[32] = {
0,0,0,0,
0,1,1,1,
0,1,0,1,
0,1,0,1,
0,1,0,1,
0,1,0,1,
0,1,0,1,
0,1,1,1
};
const static uint8_t _font_char_1[]={
0,0,0,0,
0,0,0,1,
0,0,1,1,
0,0,0,1,
0,0,0,1,
0,0,0,1,
0,0,0,1,
0,0,0,1
};
/* * * *
此处作者略去370行
* * * */
const static uint8_t _font_char_QUOTATION[]= {
0,0,0,0,
0,1,0,1,
0,1,0,1,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
};
const static bit_map _font_char_images[]={
{ 4 ,8 ,(uint8_t*)(_font_char_0)},
{ 4 ,8 ,(uint8_t*)(_font_char_1)},
{ 4 ,8 ,(uint8_t*)(_font_char_2)},
{ 4 ,8 ,(uint8_t*)(_font_char_3)},
{ 4 ,8 ,(uint8_t*)(_font_char_4)},
{ 4 ,8 ,(uint8_t*)(_font_char_5)},
{ 4 ,8 ,(uint8_t*)(_font_char_6)},
{ 4 ,8 ,(uint8_t*)(_font_char_7)},
{ 4 ,8 ,(uint8_t*)(_font_char_8)},
{ 4 ,8 ,(uint8_t*)(_font_char_9)},
{ 4 ,8 ,(uint8_t*)(_font_char_A)},
{ 4 ,8 ,(uint8_t*)(_font_char_B)},
{ 4 ,8 ,(uint8_t*)(_font_char_C)},
{ 4 ,8 ,(uint8_t*)(_font_char_D)},
{ 4 ,8 ,(uint8_t*)(_font_char_E)},
{ 4 ,8 ,(uint8_t*)(_font_char_F)},
{ 4 ,8 ,(uint8_t*)(_font_char_G)},
{ 4 ,8 ,(uint8_t*)(_font_char_H)},
{ 4 ,8 ,(uint8_t*)(_font_char_I)},
{ 4 ,8 ,(uint8_t*)(_font_char_J)},
{ 4 ,8 ,(uint8_t*)(_font_char_K)},
{ 4 ,8 ,(uint8_t*)(_font_char_L)},
{ 6 ,8 ,(uint8_t*)(_font_char_M)},
{ 6 ,8 ,(uint8_t*)(_font_char_N)},
{ 4 ,8 ,(uint8_t*)(_font_char_O)},
{ 4 ,8 ,(uint8_t*)(_font_char_P)},
{ 4 ,8 ,(uint8_t*)(_font_char_Q)},
{ 4 ,8 ,(uint8_t*)(_font_char_R)},
{ 4 ,8 ,(uint8_t*)(_font_char_S)},
{ 4 ,8 ,(uint8_t*)(_font_char_T)},
{ 4 ,8 ,(uint8_t*)(_font_char_U)},
{ 4 ,8 ,(uint8_t*)(_font_char_V)},
{ 6 ,8 ,(uint8_t*)(_font_char_W)},
{ 4 ,8 ,(uint8_t*)(_font_char_X)},
{ 4 ,8 ,(uint8_t*)(_font_char_Y)},
{ 4 ,8 ,(uint8_t*)(_font_char_Z)},
{ 2 ,8 ,(uint8_t*)(_font_char_blank) },
{ 4 ,8 ,(uint8_t*)(_font_char_comma) },
{ 4 ,8 ,(uint8_t*)(_font_char_QUOTATION) }
};
bit_map* font_get_char_function(char c){
if(c>='0' && c<='9'){
return ((bit_map*)(_font_char_images)) + c-'0';
}else if(c>='a' && c<='z'){
return ((bit_map*)(_font_char_images)) + c-'a'+10 ;
}else if(c>='A' && c<='Z'){
return ((bit_map*)(_font_char_images)) + c-'A'+10 ;
}else{
switch(c){
case ' ':
//return (bit_map*)&(_font_char_images[36]);
return ((bit_map*)(_font_char_images)) + 36 ;
break;
case ',':
//return (bit_map*)&(_font_char_images[37]);
return ((bit_map*)(_font_char_images)) + 37 ;
break;
case '"':
//return (bit_map*)&(_font_char_images[38]);
return ((bit_map*)(_font_char_images)) + 38 ;
break;
default:
return (bit_map*)0;
}
}
return (bit_map*)0;
}
也没啥技巧,用数组_font_char_images存储位图,然后根据输入的char来判断是第几个字符,用数组指针_font_char_images加上序号获得位图指针return(如果没找到就返回空指针0)。
这次就到这里。休息,休息一下。
|