| |

Trying to load a sprite.

First of all, get some sprites. As I’m currently fixated with cats I bought from itch.io this set as a starting point https://seethingswarm.itch.io/catset. I don’t know why I am fixated with cats, I am the Philosophical Dog after all. But anyway.

Let’s choose some sprites. Running is good.

We need to convert them to 1 bit. I went with https://doodad.dev/dither-me-this/. The end result isn’t enormously pretty but it’s good enough to start with.

There’s a lot of research to be done in making this sort of thing better. But let’s see how we get on. The following code will load the cat_sheet image, make one sprite from it and display on the screen. It’s not moving, it doesn’t fit, there’s no animation.

import 'CoreLibs/graphics'
import 'CoreLibs/sprites'

local gfx <const> = playdate.graphics

local catSheet = gfx.image.new('images/cat_sheet')
local catSprite = gfx.sprite.new(catSheet)

print(catSheet, catSprite)
catSprite:moveTo(200, 120)
catSprite:add()

function playdate.update()
	gfx.sprite.update()
end

Can we animate him/her?

Er, I guess so. Hmm. Well it looks like we need to be looking at the graphics animator https://sdk.play.date/2.4.2/Inside%20Playdate.html#_animation but before that I need to address the issue that our image has got four sprites in it. https://sdk.play.date/2.4.2/Inside%20Playdate.html#C-graphics.imagetable is what we need, an image table and more specifically a sequential image table. From the docs:

Sequential image tables are useful as a way to load up sequential frames of animation. They are loaded from a sequence of files in your game’s source folder at compile time from filenames with the suffix -table-<sequenceNumber> before the file extension. Individual images in the sequence are accessible via imagetable:getImage(n). The images employed by a sequential image table are not required to be the same size, unlike the images used in a matrix image table.

Ah no. That’s not what we need, we need a Matrix image table. With that we can load just one file and tell it the width and height of each sprite. We’re creating a tilemap! That’s exciting, I’ve always wanted to do that.

Matrix image tables are great as sources of imagery for tilemap. They are loaded from a single file in your game’s source folder with the suffix -table-<w>-<h> before the file extension. The compiler splits the image into separate bitmaps of dimension w by h pixels that are accessible via imagetable:getImage(x,y).

So what are my individual image dimensions? 40×40 according to the website. I could have worked that out for myself as the image size is 160×40 :). Soooo I need to call it cat_sprite-table-40-40.png I think.

error: source/images/cat_sheet-table-40-40.png: image size 500x125 isn't a multiple of the cell size, 40x40

Appears my image got resized during the dithering. Hmmm – that would give me a sprite size of 125×31.25 ?! Looks like the redithering has resized it. Tried again and it’s given me 400×100 which is better, that’s four lots of 100×100 so cat_sheet-table-100-100.png, here we go.

Some time later …

That turned out to be a wild ride in which I learnt a lot but got no closer to the final goal. Because all I wanted to do was get the animation running I cut a load of corners.

This code will show my animated cat. It’s not “right” but it does fulfill my goal and, as a I said above, a learnt a lot about the processes involved in doing it right. I have a lot to learn 🙂

import "CoreLibs/graphics"

local gfx <const> = playdate.graphics

local catSheet = gfx.imagetable.new("images/cat_sheet")
assert(catSheet, "Failed to load cat_sheet")
local count = 1

function playdate.update()

	-- Animates the cat every five frames using our four images
	count += 1
	if count > 20 then
		count = 1
	end 
	image = math.ceil(count / 5)

    gfx.clear()

    local sprite = catSheet:getImage(image) -- Get the first image
	assert(sprite)
    sprite:draw(100, 100)

end

And here it is!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *