1961|2

183

帖子

12

TA的资源

一粒金砂(高级)

楼主
 

【平头哥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)。

这次就到这里。休息,休息一下。

 

 

最新回复

nmg
真没想到你游戏图片素材竟然是用excel画出来的,太意外了  详情 回复 发表于 2022-6-5 12:45
点赞 关注
 
 

回复
举报

5260

帖子

239

TA的资源

管理员

沙发
 

真没想到你游戏图片素材竟然是用excel画出来的,太意外了

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

开始做了个html的画图工具,但是后来改用一维数组了。不想费时间再改工具,就没换。  详情 回复 发表于 2022-6-5 20:28
 
 
 

回复

183

帖子

12

TA的资源

一粒金砂(高级)

板凳
 
nmg 发表于 2022-6-5 12:45 真没想到你游戏图片素材竟然是用excel画出来的,太意外了

开始做了个html的画图工具,但是后来改用一维数组了。不想费时间再改工具,就没换。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表