Image Implementation Questions

My questions were answered, (thank you again v much @Nic )

I just wanted to add this for posterity, in case someone comes poking through curious about image drawing vs sprite drawing (or maybe @matt will find interesting in their benchmarking work), in the kinds of scenarios I described above (lots of removals, or lots of movement on many sprites). I dug up a small little test which exercises the latter (movement). Raw numbers aren't particularly important (since nothing else is going on, e.g. its not in a real game), rather the scaling properties was the focus here.

Tested on device, on newest firmware.

  • at 50 images ( sprites = 47fps, images=48fps),
  • at 100 images ( sprites = 37fps, images=48fps), ~30% faster
  • at 150 images ( sprites = 27fps, images=36fps), ~33% faster
  • at 200 images ( sprites = 20fps, images=29fps), ~45% faster
  • at 250 images ( sprites = 18fps, images=27fps), ~50% faster

image used:
image-1

import "CoreLibs/graphics"
import "CoreLibs/animation"
import "CoreLibs/sprites"
import "CoreLibs/timer"
import "CoreLibs/utilities/sampler"

gfx = playdate.graphics
snd = playdate.sound
dsp = playdate.display

gfx.setColor(gfx.kColorWhite)
dsp.setRefreshRate(0)

num_sprites = 250

images = {}
x_min = 10
x_max = 300
y_ = 30
x_ = 10
for i=1,num_sprites do 
    table.insert(images, {gfx.image.new("image-1.png"), x_, y_, 1})
    x_ = x_+3
    y_ = y_+1
end

sprites = {}

local image = gfx.image.new("image-1.png")
y_ = 30
x_ = 10
for i=1,num_sprites do 
    local sp = gfx.sprite.new(image)
    sp:add()
    sp:moveTo(x_, y_)
    table.insert(sprites, sp)
    x_ = x_+3
    y_ = y_+1
    sp.dir = 1
end

for i=1,num_sprites do
    assert(images[i][4] == sprites[i].dir)
    assert(images[i][3] == sprites[i].y)
    assert(images[i][2] == sprites[i].x)
end

local use_sprites = true
function playdate:update()
    gfx.clear()
    if playdate.buttonJustPressed(playdate.kButtonA) then
        use_sprites = not use_sprites 
    end

    if use_sprites == true then
        for i=1,#sprites do
            local spr = sprites[i]
            spr:moveTo(spr.x+10*spr.dir, spr.y)
            if spr.x >= x_max then
                spr.dir = -1
            elseif spr.x <= x_min then
                spr.dir = 1
            end
        end

	    gfx.setColor(gfx.kColorBlack)
        --sample("drawing", function() 
        gfx.sprite.update()
        --end)

	    gfx.setLineWidth(0.5)
        gfx.drawLine(0, 220, 400, 220, 2.0)
        gfx.drawText("sprite mode", 0, 0)
        playdate.drawFPS(340, 225)
    else
        for i=1,#images do
            local img = images[i]
            img[2] = img[2]+10*img[4]
            if img[2] >= x_max then
                img[4] = -1
            elseif img[2] <= x_min then
                img[4] = 1
            end
        end
 
        --sample("drawing", function() 
        for i=1,#images do
            local img = images[i]
            img[1]:draw(img[2], img[3])
        end
        --end)

        gfx.setLineWidth(0.5)
        gfx.drawLine(0, 220, 400, 220, 2.0)
        gfx.drawText("image mode", 0, 0)
        playdate.drawFPS(340, 225)
    end
end
5 Likes