I would make an entity type to hold any additional and live data...
Type t_entity
group
mode
img
Endtype
Dim ent[4000] as t_entity
Like group to set the type of sprite, mode to set the live state, and parent to store which sprite fired a bullet, or effect etc. Then the array is created with 4000 indexes.
Then I'd make a custom CreateSprite function...
Function ext_CreateSprite(sprID,image,group)
CreateSprite(sprID,image)
ent[sprID].group=group
ent[sprID].mode=1
ent[sprID].img=image
Endfunction
So now there's an array called ent, which holds the sprite group, and any other variables that you need.
Theres a couple of tricks you can pull with this as well. Like, if you have 100 bullets, you could use a tiled sprite sheet with each different bullet on it, then set the frame to suit the bullet. When you might usually delete or hide a bullet sprite (after it hits something), you could hide it and set it's mode to 0. Then, the next time you need a bullet sprite, step through the bullet section of that array for modes that equal 0 - set it's mode to 1, show it, and set it's frame to suit the new bullet.
So you could have a recycle function, like this:
Function FetchSprite(img)
fetch=1
while ent[fetch].img<>img or ent[fetch].mode<>0
inc fetch
if fetch>3999 then exitfunction
endwhile
Enfunction fetch
That would check through all the sprites for the first sprite that matches the image and is dead (mode=0). There are lots of optimisations that you can do - like have a specific range of sprites that are bullets, say sprites 100 to 200. Once you 'fetch' a sprite, set the frame to whatever you need, show it, and set its mode to live again (mode=1). It might be an idea to use an array, with an index for each sprite group, say group 0 is the player, group 1 is bullets, group 2 is enemies, group 3 is for effects. Then have a counter for each group, like a range of sprites...
Type t_spritegroup
start finish current
Endtype
Dim groupsprite[10] as t_spritegroup
So you would set groupsprite[1].start to 2, and groupsprite[1].finish to 100, and have the .current variable reset to the .start value when it goes over the .finish value. Doing this would keep the recursion checks down to a minimum when spawning a sprite, as it would only need to check the relevant group.
So that fetch function might have a version that uses the group to filter out the sprite search...
Function FetchSpriteByGroup(group)
fetch=groupsprite[group].current
kill=groupsprite[group].finish-groupsprite[group].start
while ent[fetch].group<>group or ent[fetch].mode<>0
inc fetch
if fetch>groupsprite[group].finish then fetch=groupsprite[group].start
dec kill
if kill<0 then exitfunction -1
endwhile
groupsprite[group].current=fetch
Enfunction fetch
This is what I would do at least, say I was writing an arcade game with lots of bullets, or lots of enemies or collectables even - I think it's worth doing when you have more than a dozen or so sprites to manage.
I hope I've made sense.

I got a fever, and the only prescription, is more memes.
