How Do I Update An Image Table On A Sprite That Is Already In The World?

I can successfully assign an image table to a sprite when the game starts but I am having trouble understanding how to update an image table. For example, suppose a sprite has plain clothes and picks up a suit of armor from somewhere. I now want that sprite to reference the image table for "sprite in armor" instead of "sprite in plain clothes" when it walks. Suppose I have an armor checkbox in my Playdate system menu and I want the user to be able to check the box on and off and when they do the sprite will jump back-and-forth between wearing plain clothes and wearing armor. How would I go about doing this? Here is how I assigned the initial image table:

playerImage = gfx.imagetable.new("Images/Square/player")
local playerInstance = Player(200, 130, playerImage)
playerInstance:add()

Any tips would be appreciated. My other menu items work fine (background, etc.) but I can't figure out how to switch to a different image table for a player that is already active and in the world. I see a setImage in the SDK documentation but I am not sure if that is the correct path forward.

(disclaimer: I am not a SDK sprite expert, though I have written a sidescroller using the SDK sprite library)

A sprite can have an assigned image, that is set with sprite:setImage. AFAIK you can't assign an image table to a sprite (meaning, there is no sprite:setImageTable method).

So I'm assuming that your 'image' in your sprite class ("I can successfully assign an image table to a sprite") is actually an image table, and when your player is doing things (like 'walking') you're picking frames out of that stored image table per-frame with and index into that table... walking that backwards, when you instantiate your player:

local playerInstance = Player(200, 130, playerImage)

you're setting a class member (I'll call it 'currentImageTable') in your class 'init' to 'playerImage':

:
self.currentImageTable = playerImage
:

and that in your sprite 'update' method you're doing some sort of thing like:

:
self:setImage(self.currentImageTable:getImage(someIndex)))
:

If that's the case, to do what you're asking I'd suggest you have two different image tables:

playerImage = gfx.imagetable.new("Images/Square/player")
playerImageArmored = gfx.imagetable.new("Images/Square/playerArmored")

(Important: and that these image tables match frame-for-frame with each other in regards to animation intent (frames 1 and 2 for each table are idle, frames, 3 through 6 are running, etc. etc.).

Then what you'd need to do is at the appropriate time re-assign the currentImageTable...

function Player:wearArmor()
self.currentImageTable = playerImageArmored
end

function Player:removeArmor()
self.currentImageTable = playerImage
end

and at that point things would 'just work'.

There are many ways to do this, this is just one approach... it depends on how you've got your code/classes set up, internal state tracking, etc.

tl;dr - re-assign your current animation image table via a variable that can point to different instantiated image tables

4 Likes

Thanks, great explanation. I was able to figure it out with your outline, I appreciate it.

1 Like