世嘉MD游戏开发【七】:绘制图片,drawImage

这一期讲绘制图片。

上一期讲的是绘制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;

    //设置调色板,把图片的调色板数据赋值给PAL0
    VDP_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

发布了17 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq272508839/article/details/103323856