前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gameboy游戏开发-精灵入门

Gameboy游戏开发-精灵入门

作者头像
海哥@开发
发布2022-04-06 14:55:50
4310
发布2022-04-06 14:55:50
举报
文章被收录于专栏:海哥聊技术海哥聊技术

上一节课我们展示了一个最简单的人物在屏幕内移动的例子,但人物移动时并没有配合的动画,这次我们来个高级版本的。在GB内我们管所有移动的物体都叫做精灵(Sprite)。组成精灵的瓦块(Tile)是一个8x8的像素组合。每个瓦块是一堆0或1位的组合,如果手工画这个肯定会疯掉。我们可以使用Gameboy Tile Designer(以下简称gbtd)来进行瓦块的绘画。

GBTD的使用

gbtd是个免费的绿色程序下载回来即可使用,macOS的用户可以通过wine来进行使用。运行GBTD后首先我们点击View选择Tile size,8x16。这里要做下解释GB的标准瓦块大小为8x8像素,但精灵特殊可以支持8x16的像素。GB的性能一个屏幕最多支持256个独立瓦块,GBC支持512个。大多游戏内一个主角都会使用掉16x16的像素来进行展示,也就是要同时控制4个瓦块,同屏幕精灵多了性能就会下降,所以我们要尽量使用8x16的精灵。

这个截图是一个我已经做好的Mario的瓦块文件,前两个坐标的是mario静止时的状态,后几个下标是mario跑起来时的瓦块。我在附录里会把这个文件放出来,大家可以直接使用。接下来我们要导出gbdk可以用的.c文件。选择File->Export to->文件类型选择gbdk,filename我们使用mario.c,Label是我们数组变量的名字,我们也写上Mario。From会导出的瓦块下标,我们写入从0到9导出10个瓦块。

导出后会生成一个mario.c的文件,我们打开看一下这就是我们后续要用到的瓦块。

代码语言:javascript
复制
unsigned char mario[] =
{
  0x07,0x07,0x0F,0x0F,0x01,0x0E,0x0B,0x14,
  0x09,0x16,0x07,0x18,0x07,0x00,0x02,0x0F,
  0x02,0x1F,0x03,0x3F,0x37,0x0D,0x3F,0x07,
  0x3F,0x0F,0x0E,0x0E,0x00,0x1C,0x00,0x3C,
  0xC0,0xC0,0xF8,0xF8,0xA0,0x40,0xB8,0x40,
  0xDC,0x20,0x80,0x78,0xF0,0x00,0x00,0xC0,
  0x40,0xF8,0xC0,0xFC,0xEC,0xB0,0xFC,0xE0,
  0xFC,0xF0,0x70,0x70,0x00,0x38,0x00,0x3C,
  0x07,0x07,0x0F,0x1F,0x00,0x3F,0x6D,0x12,
  0x6C,0x13,0x37,0x08,0x1C,0x1F,0x3E,0x31,
  0x2E,0x31,0x3E,0x39,0x1F,0x1F,0x11,0x1F,
  0x00,0x0F,0x0C,0x5F,0x02,0x7E,0x00,0x3C,
  0xC0,0xC0,0xF0,0xF0,0xA0,0x40,0xF8,0x00,
  0xCC,0x30,0xE0,0x18,0x70,0xC0,0xC0,0xF8,
  0x00,0xF8,0x00,0xF8,0x00,0xF0,0xE0,0xE0,
  0xE0,0xE0,0x40,0xC0,0x00,0x00,0x00,0x00,
  0x07,0x07,0x0F,0x0F,0x01,0x0E,0x0B,0x14,
  0x09,0x16,0x07,0x18,0x07,0x00,0x02,0x07,
  0x01,0x1F,0x03,0x1F,0x01,0x1F,0x13,0x1C,
  0x0B,0x0C,0x07,0x07,0x00,0x03,0x00,0x03,
  0xC0,0xC0,0xF8,0xF8,0xA0,0x40,0xB8,0x40,
  0xDC,0x20,0x80,0x78,0xF0,0x00,0x00,0xC0,
  0x80,0xE0,0xE0,0x60,0xF0,0xF0,0xF0,0x70,
  0xE0,0xE0,0x00,0xE0,0x00,0xF0,0x00,0x80,
  0x03,0x03,0x07,0x07,0x00,0x07,0x05,0x0A,
  0x04,0x0B,0x03,0x0C,0x03,0x00,0x00,0x07,
  0x08,0x07,0x1C,0x07,0x07,0x1F,0x0F,0x1F,
  0x0E,0x3E,0x00,0x21,0x00,0x01,0x00,0x00,
  0xE0,0xE0,0xFC,0xFC,0xD0,0x20,0xDC,0x20,
  0xEE,0x10,0xC0,0x3C,0xF8,0x00,0x48,0xE0,
  0x1C,0xE0,0x18,0xE0,0xF0,0xF0,0xF0,0xF0,
  0xE0,0xE0,0x00,0xC0,0x00,0xE0,0x00,0x00,
  0x07,0x07,0x0F,0x0F,0x01,0x0E,0x0B,0x14,
  0x09,0x16,0x07,0x18,0x07,0x00,0x03,0x3F,
  0xC3,0x3F,0xE2,0x0E,0xCF,0x0F,0x1F,0x1F,
  0x3F,0x3F,0x1C,0x7C,0x00,0x70,0x00,0x38,
  0xC0,0xC0,0xF8,0xF8,0xA0,0x40,0xB8,0x40,
  0xDC,0x20,0x80,0x78,0xF0,0x00,0x00,0xC0,
  0x8E,0xF0,0xE6,0xF8,0xE0,0xE4,0xF0,0xFC,
  0xF0,0xFC,0x70,0x7C,0x00,0x00,0x00,0x00
};

导入精灵到我们的程序中

我们打开上节课的main.c文件,把这次的mario.c文件导入进来,并修改暂时的瓦块看一下效果。

代码语言:javascript
复制
#include <gb/gb.h>
#include <stdio.h>
//导入新文件进来
#include "mario.c"


void main()
{
    //使用mario数组来展示数据,并且修改导入的下标大小,按8x8计算,我们需要导入20个瓦块进来。
    set_sprite_data(0, 20, mario);
    set_sprite_tile(0, 0);
    move_sprite(0, 20, 20);
    SHOW_SPRITES;
    while (1)
    {
        if(joypad()==J_RIGHT)
        {
            scroll_sprite(0, 2, 0);
        }
        if(joypad()==J_LEFT)
        {
            scroll_sprite(0, -2, 0);
        }
        delay(50);
    }
    
}

保存文件make运行。可以看到结果在游戏界面内只显示了马里奥的左上角,其他并没有显示,但在调试程序中可以看到其它的瓦块也已经加载进来了。

这是因为我们还没有告诉gbdk我们的精灵要按8x16来显示,以及我们要组成我们的马里奥还要同时显示两组瓦块,我们再次修改程序试一试。

代码语言:javascript
复制
#include <gb/gb.h>
#include <stdio.h>
#include "mario.c"


void main()
{
    //设置精灵为8x16
    SPRITES_8x16;
    set_sprite_data(0, 20, mario);
    set_sprite_tile(0, 0);
    move_sprite(0, 20, 20);
    //设置精灵1,从下标2开始
    set_sprite_tile(1, 2);
    //移动右半部分到正确的位置
    move_sprite(1,20+8, 20);
    SHOW_SPRITES;
    while (1)
    {
        if(joypad()==J_RIGHT)
        {
            //每次移动要两个精灵同时移动,否则马里奥会分体。这也是刚说的为什么如果使用大像素人物尽量使用8x16的精灵
            scroll_sprite(0, 2, 0);
            scroll_sprite(1, 2, 0);
        }
        if(joypad()==J_LEFT)
        {
            scroll_sprite(0, -2, 0);
            scroll_sprite(1, -2, 0);
        }
        delay(50);
    }
    
}

make我们来实验下效果。

目前我们的马里奥还是在屏幕上硬飘,没有跑起来怎么办?

马里奥跑起来吧

让马里奥跑起来其实要做的就是不停的切动画,边看代码边看注释。

代码语言:javascript
复制
#include <gb/gb.h>
#include <stdio.h>
#include "mario.c"
//设置一个全局变量循环动画
UINT8 run_index = 0;

void main()
{
    SPRITES_8x16;
    set_sprite_data(0, 20, mario);
    set_sprite_tile(0, 0);
    move_sprite(0, 20, 20);
    set_sprite_tile(1, 2);
    move_sprite(1,20+8, 20);
    SHOW_SPRITES;
    while (1)
    {
        if(joypad()==J_RIGHT)
        {
            //每次动态修改要展示的瓦块下标
            set_sprite_tile(0, (run_index+4)*2);
            set_sprite_tile(1, (run_index+4)*2+2);

            scroll_sprite(0, 2, 0);
            scroll_sprite(1, 2, 0);
            //当循环到达上限时重置到0
            if(run_index==4)
            {
                run_index = 0;
            }
            else
            {
                run_index+=2;
            }
            
        }
        else if(joypad()==J_LEFT)
        {
            set_sprite_tile(0, (run_index+4)*2);
            set_sprite_tile(1, (run_index+4)*2+2);

            scroll_sprite(0, -2, 0);
            scroll_sprite(1, -2, 0);

            if(run_index==4)
            {
                run_index = 0;
            }
            else
            {
                run_index+=2;
            }
        }
        else 
        {
            //当人物静止时恢复静止状体
            set_sprite_tile(0, 0);
            set_sprite_tile(1, 2);
        }
        delay(80);
    }
    
}

make运行,这次我们烧录到卡带用真机试试效果。

http://mpvideo.qpic.cn/0bf2r4aacaaaryaemtzzibpfbd6daghqaaia.f10002.mp4?dis_k=4cf7b0e24321d194045f90302240fece&dis_t=1649228089&vid=wxv_1194869345692958721&format_id=10002&support_redirect=0&mmversion=false

可以看到我们的马里奥奔跑起来了,但是向左跑的时候人物并没有转向。最笨的方法是编辑瓦块的时候再做3针向左的动画出来,但这样会大量占用我们宝贵的存储空间。怎么办?

下一课我们会讲解精灵进阶,如何实现两个方向的跑动,又不需要重复画瓦块。并会产生一个方便使用的Role类,来操作复杂的精灵。同时我们还会讲解GBC上的上色方案“调色板”。

附注

  • 程序中用到的马里奥文件
    • (http://blog.guohai.org/doc-pic/2020-02/mario.gbr)
  • 为了剪短文章的长度,每次示例代码只有新增部分有注释,实际开发中请写清所有注释。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海哥聊技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • GBTD的使用
  • 导入精灵到我们的程序中
  • 马里奥跑起来吧
  • 附注
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档