How does sprite() load images?

This has been playing on my “programmer’s brain” for a bit: when we call sprite(“sprite:name”,0,0) when is the sprite loaded? I’m guessing it doesn’t re-load an image every frame… it must keep a reference? Is it more efficient for us to load an image, and pass that to the sprite() call, or is this handled magically?

Thanks!

It stores it in a cache which is cleared when memory starts to get low.

The reason I ask is that I’m setting up an animation system (flip-book style) that works something like this:

runAnim = Animation({"MyPack:RunFrame1", "MyPack:RunFrame2", "MyPack:RunFrame3"}, speed)

Then the animation cycles through drawing the frames in the draw method:

sprite(self.currFrame, x, y)

Can you see any problems with doing it this way? I just feel like lazy-loading things is, well, actually, I don’t know why I feel uneasy about it so I thought I’d ask :wink:

It should be okay. I believe another user (@VoiceOfTreason?) did this for his zombie game. If the sprites are small they should load quite fast. And once they are cached there is no additional loading.

Hey there,

I’be been playing around with animated sprites using imported sprite sheets.

I noticed that when updating my frames (i’m using mesh class but as you will see below, behavior is the same), drawing the art on an image using set context, then using mesh.texture = image is much much much faster than using mesh.texture = string (string being something like “MyPack:RunFrame1”).

For example, on my iPad 1, drawing 1000 animated sprites that rotate towards and follow my finger:
Using mesh.texture = image, i get around 12fps.
Using mesh.texture = string i get less than 1 fps.

Using just the sprite(string) function, doing this runs at around 2fps

function draw()
   for i=1, 1000 do
      sprite("RPG:fireball_1")
   end
end

Using sprite(image) function, this runs at around 25fps

function setup()
   img = image(64,64)
   setContext(img)
   sprite("RPG:fireball_1")
end

function draw()
   for i=1, 1000 do
      sprite(img)
   end
end

In my program, both methods look like they get cached in memory (start a bit slower on initial art display then it goes faster ones all frames ran once), but using string as texture source seems to generate image in the background or something like that, everytime it’s called.

edit- I reckon it’s faster to use a sprite sheet of size 512x512 (individual art size being 64x64) and specifying new mesh.textCoords on frameswitch, than using 64 sprites of size 64x64 and then switching the mesh.texture. Unfortunately that’s all I have for now, will try to regroup them into an atlas when I have the time.
Im curious though… Does displaying only a fraction of a 512x512 have the same speed as displaying it fully ?

Cheers,

Xavier

Switching using mesh.texCoords should be faster than changing mesh.texture. (Unless it’s computationally difficult to change texCoords — though it shouldn’t be.)

Thanks for the mini-benchmark on the sprite string performance. I will have to see what the bottleneck is. Probably the texture look-up.

For my Space Invaders example, I did it very simply and just did (essentially):

sprite(self.images[self.currentFrame])
self.currentFrame = self.currentFrame + 1

And performance was fine even with lots of sprites on screen. I imagine the ideal way to do this though would be a mesh using a spritesheet image and changing texCoords - that way, OpenGL doesn’t have to keep switching textures.

Hi !

When the image is loaded, is it loaded entirely or just according to the size we want ?

What I’m asking is if

for i=1,100 do
 sprite(myImg,0,0,50,50) 
end

has the same speed with a 50x50 image and with a 500x500 image ? I tried to compare them but I wasn’t able to notice any difference, and it surprised me !

Also, is

sprite(myImg,0,0,r,r)
r=r+1

reloading the image each time ?

@RyZum - as far as I know, if you have loaded a sprite into a variable with readImage then it only gets loaded that once, and stays in memory thereafter.

Thanks !

In my project, I only need to draw many small images on the screen (50x50), but I only have 500x500 images. So my question is : do I have to convert the images manually before (with an external program), or will codea handle it if I only use the function

sprite(my500x500Img,x,y,50,50)

@RyZum - you could “resize” them by creating a small image in memory and drawing your big image onto it, like so

img=image(50,50)
setContext(img) --draw onto our image
sprite("Documents:LargeImage",25,25,50) --draw and resize large image to 50 pixels
setContext() --stop drawing on our image
--now img is a 50x50 replica of the original

Thanks a lot !