这一期讲绘制图片。
上一期讲的是绘制tile,还要用那个不怎么好用的工具导出数组数据,很繁琐,这次就不用那个蹩脚的工具了,随便一个图片用photoshop处理一下就可以了,对于图片的要求有这么几点:
1.图片分辨率必须是8的整数倍,像8,16,32这样的都可以,9,10,12,31这样的就不行了,编译会报错。
2.图片的颜色数不能超过16,超过16也会编译报错,一个普通图片怎么用ps处理成16种颜色呢,看下图:
还有一个很重要的细节说一下:
SGDK一共有4组调色板,每组有16种颜色,看过前面一期的应该都知道了,如果图片用ps索引颜色后不足16种颜色,可以手动把剩下的空颜色设置成别的颜色补齐16种,要不然可能会出现不可预知的问题,比如文字不会显示出来,因为文字用到的颜色默认是最后一个颜色,所以下图中的情况应该是尽量避免的:
不让有空颜色我们怎么弄透明度呢,默认第一个颜色是背景色,所以只要用第一个颜色画过的地方都会是透明的。
图片处理完之后保存为pic.png格式,放到工程目录下的res文件夹备用。
我的图片和调色板如下图所示:
在res文件夹里空白地方鼠标右键新建一个txt文档,重命名为picture.res,名字大家自己随便写,后缀是.res就可以,当然不能有中文出现,用记事本打开res文件,里面写如下代码:
IMAGE pic "pic.png" 0
写完保存。
这个文件就相当于声明了一些变量,IMAGE代表变量的类型,还有其他类型,比如SPRITE,WAV等等,pic是变量的名字,在代码中用到这个资源的时候就可以写pic,"pic.png"是路径,res文件夹就是根目录(不是工程根目录,只是资源根目录),如果这个图片在res/picture文件夹里,那么这个路径应该写作:"picture/pic.png",最后这个0意思就是压缩级别,0是不压缩,详情见SGDK/bin目录下的rescomp.txt文档或者SGDK自带的范例。
然后用vscode打开工程,在src文件夹里新建main.c,代码如下:
#include <genesis.h>
#include <vdp.h>
#include "picture.h" //res目录中的picture.res会自动生成picture.h文件int main()
{//在屏幕上2,0位置绘制文字VDP_drawText("Draw Image", 2, 0);/*声明一个unsigned short类型的变量index,TILE_USERINDEX是一个系统常量,它的值是16,意思是VRAM(显存)中的第16个tile块这个位置。一般都从第16个开始用,前面15个或许有其他用途,但是暂时我没发现前15个位置不能用,我看好多代码里都是空出前15个位置,貌似是把前15个tile留着给背景用,我觉得这都是游戏制作者自己的设计,哪几个位置给背景哪几个位置给精灵都是设计好的,我们自己也可以设计自己的位置,如果你要从1开始用也可以,目前我没发现有啥不妥,但是0这个位置尽量不要用。*/u16 index = TILE_USERINDEX;//设置调色板,把图片的调色板数据赋值给PAL0VDP_setPalette(PAL0, pic.palette->data);/*先来解释一下TILE_ATTR_FULL这个函数,这个函数的意思是编码tile的属性给tilemap数据,第一个参数PAL0是第一个调色板,第二个参数0是优先级是0,优先级高的则会显示在上面,优先级低的就显示在优先级高的下面,也就是显示层级,第三个参数FALSE是垂直轴镜像,这里就不镜像了,所以是FALSE,第四个参数FALSE是水平轴镜像第五个参数上面已经解释过了,就是显存中tile块的位置VDP_drawImageEx:第一个参数是卷轴,世嘉MD有两层卷轴,一个PLAN_A,一个PLAN_B,这俩卷轴喜欢哪个用哪个第二个参数是const Image*,是一个图片类型的指针,那么很自然的就要传一个地址进去第三个参数略第四五个参数是网格坐标,8x8为一个单位第六个参数是要不要加载调色板,这里一般都是不加载调色板的,因为调色板我们前面都手工设置过了第七个参数是CPU绘制还是DMA绘制VDP_drawImageEx有一个返回值,是unsigned short类型的,也就是u16类型,当内存不足够加载图片的时候就会返回FALSE,也就是0,返回值不是0那就是加载成功了*/VDP_drawImageEx(PLAN_A, &pic, TILE_ATTR_FULL(PAL0, 0, FALSE, FALSE, index), 0, 1, FALSE, CPU);//每次用了index这个值的时候得知道用了多少个tile,不然下次用的时候你也不知道用到哪个位置了,乱写可不行,写的那个位置要是已经有了tile,//那么已经有的那个tile就会被覆盖,这就不行了,全乱套了,numTile这个值的意思是:这个图片有几个不重复的tile块组成,不一定是按分辨率算出来的tile块,注意是不重复的tile块index += pic.tileset->numTile;while (1){VDP_waitVSync();}return 0;
}
编译,得到rom.bin,用模拟器运行效果如下:
这个图是街机游戏街头霸王Alpha3里面的科迪,科迪的调色板是20色,MD只支持16色,索引后就丢失了4种颜色,所以有些失真,但总体效果还可以。
未完待续。。。
复古游戏开发群:879063892