antirez / load81

SDL based Lua programming environment for kids similar to Codea
BSD 2-Clause "Simplified" License
647 stars 64 forks source link

add png sprite support using SDL_Image #46

Closed ghost closed 12 years ago

ghost commented 12 years ago

This patch adds support for png sprites using SDL_Image.

seclorum commented 12 years ago

Awesome!

seclorum commented 12 years ago

I think its cool to follow Codea, up to a point. But are we looking for compatibility, or is it just that it is a safe model to follow? I don't know how important compatibility is .. I suppose we're doing the old "this BASIC is mostly like the other BASIC" dance of the 80's a bit here ..

For sound, though, I think Codea isn't the way to go. We could do something really, really nice - Codea sort of isn't a great sound environment.

ghost commented 12 years ago

I think you're reading a bunch into this. I like the sprite feature and needed some place to start and the Codea API seemed like a good place to start. Disclaimer: I don't have Codea so I'm not entirely sure if this is compatible or not since they don't publish their API online. I'm some what indifferent to the API and have the bindings for both approaches so it's trivial to change. I suppose this is antirez's call.

I can say from using this API my 7 yr old seems to be able to understand it very easily.

seclorum commented 12 years ago

Could be I'm reading more into it than I should, but I just wonder if we're following Codea because its a good example or because there is a plethora of Codea-based code out there we can also run ..

Either way I'm really sure its great to have PNG loading onboard, and sprites. ;)

antirez commented 12 years ago

Hello, I think the API is just perfect, I experimented it with my son but in general even for more expert programmers, it is very cool to just say the name of the sprite and the coordinates without manage resources. I don't like an API like:

foo = sprite.load("foo.jpg");
drawSprint(foo,100,200);

It is complex without a good reason.

As for resource management, probably if we'll incur into problems the simplest thing to do is that once a given number of sprites are in memory and a new one is loaded, a random one is deleted (or we may want to use some kind of LRU approximation). For instance what I would do using a technique I use for Redis is that every time sprint() is called we update a unix time stamp "last_traced" in the Lua table, and when there are already too may sprites we sample three random ones and delete the one with the smallest last_traced (the least recently traced one).

Merging this patch as it looks very good and simple, but I think we should allow for sprint rotation as well in the immediate future:

sprite(name,x,y,[angle]);

If the last argument is not specified the API acts exactly as it is doing right now. I think that SDL_gfx has a function to rotate the sprite if needed.

With rotation a lot of things in the gaming area gets possible.

Thanks, Salvatore

ghost commented 12 years ago

There are rotozoom functions. I'll look at it today.

antirez commented 12 years ago

thanks already doing it myself, it's pretty trivial apparently. Very cool to have sprites!

ghost commented 12 years ago

Yes. I think just rotozoomSurface and then blit.

antirez commented 12 years ago

I just pushed support for rotation but somewhat it has spurious pixels in certain runs. Not sure why...

For now I'm refactoring the code in order to put the SDL-specific code inside framebuffer.c so that conceptually we still have a single file with all the arch-specific stuff.

antirez commented 12 years ago

Refactoring finished, now apparently the first run of the program is always fun, the next runs will show strange pixels. Maybe we don't reinitialize stuff enough.

ghost commented 12 years ago

Instead of: angle = (argc == 4) ? lua_tonumber(L,4) : 0;

you can use: angle = luaL_optnumber(L, 4, 0);

ghost commented 12 years ago

Did you try without antialiasing (last parameter smooth = 0)? We probably don't want that anyways I think that will have issues with transparency.?

antirez commented 12 years ago

It was exactly an issue with antialiasing, thanks, however without antialiasing the rendering is a lot poorer so I'm adding this as an optional parameter for sprite() as well, with default off. Sounds good?

antirez commented 12 years ago

Done, it seems like that providing user with the control and a sane default is the best pick.

rlane commented 12 years ago

I think there's a good use for a sprite object that you could pass to sprite() in lieu of a filename. Rendering to an image can be used for many cool effects. I'm not sure what the best API for this would be - we could either pass the surface ("sprite" seems inappropriate for a full-screen image) to every drawing primitive in an optional parameter, or we could go the OpenGL way and have a bindSurface() function that redirects all subsequent drawing operations.

This is obviously a somewhat advanced API but I think that's ok as long as it doesn't make the basic APIs more complicated. Ideally a novice programmer could copy somebody else's function for doing a full-screen blur without needing to understand it.

antirez commented 12 years ago

@rlane Maybe the OpenGL-alike method could work well:

createCanvas("foo",width,height)

selectCanvas("foo")
ellipse(100,100,200,200) -- This will draw in "foo", so will not be visible in the screen
selectCanvas("screen") -- Back drawing to the screen

Then you have something like traceCanvas("foo",x,y) that will draw it to the screen.

There are other priorities but definitely something to take in mind. p.s. also we may have something like:

createCanvasFromImage("foo","foobar.jpg")

That's interesting because allows to do things like analyzing images and other more advanced tasks that may be useful to prototype real applications.

seclorum commented 12 years ago

This indexing will be good for when SVG support gets added, then you can create objects in SVG, and render them by name ("id='pacman'") .. come to think of it, SVG support would be doable with SDL_svg, I suppose ..