Table of Contents

Importing and Drawing Sprites

The SDK makes it easy to bring images into your game after you've exported them, particularly from Aseprite. This page will go into a bit more detail on how to incorporate the image files into your project and then how to load and draw them in your code.

Warning: when exporting BMP images from GIMP, make sure to check “Do not write color space information” in the Compatibility options.

Import

The 2MB Cartridges have 128 banks of 16KB each, and the SDK scripts are designed to assign image assets to these banks based on the contents of the assets folder. Each subfolder of assets comprises one of the cartridge banks. Files dropped directly into the assets folder are ignored by the import scripts.

After adding files to folders inside assets, run

make import

For example, in the games/tanks branch of the SDK there are three assets folders: “font”, “gfx”, and “music”. For these folders the import script outputs

[ 'bios8.bmp' ]
[
  'countdown.bmp',
  'countdown.json',
  'exlposion.bmp',
  'exlposion.json',
  'green_tank.bmp',
  'green_tank.json',
  'ground.bmp',
  'title.bmp'
]
[ 'tank_intro.mid' ]

In addition these files will be created in src/gen/assets with names based on the subfolders.

Drawing

Drawing sprites on the GameTank is a two-step process. Before a sprite can be drawn it must be loaded into Sprite RAM. Once it is loaded into one of the sprite banks, it can be drawn either by specifying a rectangular portion of a sprite bank, or by an index into frame data exported by Aseprite.

The function load_spritesheet takes a pointer to compressed sprite data, the ROM bank number where that data resides, and a sprite bank number to extract the image to. However, you don't actually need to specify the pointer or ROM bank directly.

The generated header files, eg. src/gen/gfx if you created a “gfx” folder, provide convenience macros that contain the location of each image file.

//Near top of file
#include "../gen/assets/gfx.h"
...
//During your init process
load_spritesheet(&ASSET__gfx__ship_bmp, 0); //Stores the ship graphics in sprite bank 0
load_spritesheet(&ASSET__gfx__bug_bmp, 1); //Stores the bug graphics in sprite bank 1

Drawing by rectangle

Once your graphics are loaded into a sprite bank, you can draw them with draw_sprite

draw_sprite(X,Y,W,H,GX,GY,RAMBANK);

X and Y indicate coordinates on the screen. W and H are the width and height. GX and GY are the coordinates in the source image which you'd use to pick a tile or frame of animation from a sheet. RAMBANK is the bank number that you earlier specified to load_spritesheet.

draw_sprite is part of the queued drawing API, so you can consecutively call other queued drawing functions and they'll be proeccessed one at a time, in order.

When there's no more drawing or computation to do for the current frame, use await_draw_queue(), sleep(1), and flip_pages() to present your frame to the TV!

Drawing by frame number

If you've exported a packed sprite sheet alongside JSON frame data, you can use draw_sprite_frame. This function can not only select the rectangle in your sprite sheet from a frame number, it also centers your sprite on the canvas center used in Aseprite and had a parameter for flipping horizontally and/or vertically.

void draw_sprite_frame(
    const Frame *sprite_table,
    char sprite_table_bank,
    char x, char y,
    char frame,
    char flip,
    char bank);

Referring to the JSON data is similar to referring to the sprite data in load_spritesheet and combines the first two arguments into one macro.

draw_sprite_frame(&ASSET__gfx__ship_json, ship_x, ship_y, anim_frame, SPRITE_FLIP_NONE, 0);