SDK 1.9.3 - Linux
Hi all,
I am creating a game in which I require a lot of similar sprites. Ideally, I would create a single original sprite with all it's properties and attributes pre-set, then when a similar sprite is needed, copy the original into a new sprite and making any changes where necessary instead of recreating the whole sprite completely from scratch.
Lucky for me, the documentation does show a copy method for a sprite, but it has wording I didn't expect:
[M] playdate.graphics.sprite:copy()
Returns a copy of the caller.
Is it a typo? Should it say "Returns a copy of the sprite?". Other copy methods in the documentation seems to have consistency, so is this one somehow different?
In any case I attempted to use it and it seemed to work as expected.
However when attempting to change the newly copied sprite's image as part of an animation, I start to see some issues.
To demonstrate, here is some working test code:
function setup()
imgs = {}
imagTbl = gfx.imagetable.new("body")
for i = 1, #imagTbl do
imgs[i] = imagTbl[i]
end
sprite1 = gfx.sprite.new(imgs[1])
sprite1:setCollideRect(0, 0, sprite1:getSize())
sprite1:moveTo(50, 50)
sprite1:add()
sprite2 = gfx.sprite.new(imgs[1])
sprite2:setCollideRect(0, 0, sprite2:getSize())
sprite2:moveTo(75, 50)
sprite2:add()
aniTimer = playdate.timer.new(500)
aniTimer.repeats = true
aniTimer.timerEndedCallback = function ()
if sprite1:getImage() == imgs[1] then
sprite1:setImage(imgs[2])
sprite2:setImage(imgs[2])
else
sprite1:setImage(imgs[1])
sprite2:setImage(imgs[1])
end
end
end
Here I simply create 2 sprites each with a set image (from an image table consisting of 2 different images for animation), set collide bounds (for easier demonstration) and set location. I have also created an animation timer that will change the images of both sprites every half a second.
The working code looks something like this:
Now if I change the sprite creation from a sprite .new([image])
to a sprite :copy()
like so:
sprite2 = sprite1:copy()
I then get something like this:
As you can see the second sprite is there, but it's bounds have offset to the sprites centre and also the original image from the sprite is replaced with a blank image (I'm assuming this is nil
or something like that).
This happens every time a different image is being set to the sprite. I know this because if I comment out the animation timer completely, the second sprite will be showing on screen alongside the first, albeit not animating.
I see this oddity in my game too where sprites that are copied and don't have their images changed worked perfectly fine, but the second they do, they exhibit the same behaviour as explained above.
Now I have created other posts on this forum and others have graciously pointed out that I have either misunderstood what a given method is doing or that I didn't read the documentation correctly of which I'm happy to be told the same again.
I do understand that this is clearly something to do with the :copy()
method as it is the clear outlier, but even with the strangely worded documentation, I still don't quite understand what is going on and why the change of it's image makes it behave this way.
Short of implementing my own copy method in my game (or being confident enough to say that this is some sort of a bug), I was wondering if anyone had any insight that might help me get to the bottom of this?
For reference here is the same code packaged up for you, including the image table file.
example.zip (881 Bytes)
Thanks in advance