|
Title: Advanced Sprite Usage Post by: sylus101 on May 29, 2007, 06:58:26 PM Hello my fellow DSLua-ers. In the very recent past, I began writing DSLua scripts and ran into an immediate and frustrating problem, the 128kb limit of sprite data that can be loaded at any one time.
Thus follows the obvious issue: "How the hell do I get all these framestrips loaded and on screen at the same time??" At first I, was able to load a certain amount in a certain order, with the first frame empty so it was transparent and I ended up displaying/hiding things a lot. This just couldn't work as I needed more than 128kb worth of sprites available before I had half of what I wanted on screen. I learned about the FrameStrip:FreeAll() function which sustained things for awhile, but I found I still needed more memory available. In the RPG I'm working on, I went to stage after stage of frustration and modification to conform to a limitation that kept changing for me, but at the very least became clearer and clearer as time went on. What I was working with was quite a bit worth of graphics. The main character in the game is a 64 x 128 sprite most of the time, and sometimes another 64 X 64 sprite that has to appear, not to mention the monster being fought and whatever sword slashing graphics I needed. I trimmed an trimmed but the inevitable conclusion was that I needed a way to show one animation, unload it, load a new one and continue on. The solution hit me! I created much shorter framestrips, loaded a temporary single frame framestrip on-top/underneath it, unloaded the original, loaded the continuation, then unloaded the temporary frame. This sounds like a lot of work but the end result was very pleasing. I have 16 different animations and memory to spare. This worked fine until.... I started working on a graphic for a sword slash. As soon as I started with it, I found that as I was loading and unloading things, they weren't exactly going back in the dominance level I'd had them before. Sword slashes appeared half behind goblns, half on top of the main character... as you can imagine with everything that lead up to this, hysteria ensued. When I calmed down, I set out to truly understand how DSLua handled sprite dominance. I read that PALib could actually assign it, but I had no time to learn C/C++. I created 3 demos with 4 colored squares and had button presses load and unload them. One demo actually freed the framestrips when a sprite was freed, the other did not. The last used only 2 framestrips with 2 colors on each one. The first revelation, was that it didn't matter in any of the scenarios whether you had fully freed framestrips or not. The order was the only thing that really made a difference. This was good news. After a handful of tests, I had it! This isn't that easy to explain, but here it goes. I'll be coming back with edits and possible a post on my webspace with something clearer. Initial loading order has the first loaded on top and each new sprite is under it. Order FREED is really the key. As you free sprites and EITHER load in new ones OR reload sprites you had before... they will fill in in reverse order from when they were freed. Once available freed slots are filled, newly loaded sprites will be on the very bottom. First a simple example: I have sprites a, b, c, and d. I load them in that order so a is on top and each is under the other in that order. If I free c, then load c, it remains in it's position. If I free c, then load a new sprite e, the order will now be a, b, e, d. If I load c back in after that, it will be a, b, e, d, c. Now, how I really fixed my problem, was setting up a filler sprite. If I knew I was going to be doing a lot of loading and unloading, but when I needed something to definitely stay on bottom (like my goblin), I would load in a several filler sprites between the main character and him. As I swapped in and out animations, I freed and loaded filler sprites along with it. That way, the other things that needed to appear in between didn't end up on bottom or places they just didn't belong. Here's another example. I have sprites a1, a2, and m1. What I've really l loaded was a1, a2, f1,f2, and m1 where the f sprites are filler, or more like place holders than anything else. Just a single transparent frame, as small as you want. An attack starts. I unload filler in reverse order, f2:Free() ; f1:Free(), then load in the transition sprites as described above, Sprite.Create = t1, t2 (I'm shortening this and will come back later). So now, I have this dominance level, left to right, top (or foremost) to bottom: a1,a2,t1,t2,m1 a1 and a2 are the same as t1 and t2 so at this point, you don't see any difference. In the end, you shouldn't see any sign of the transition at all. That's the whole idea. Now I free the a's, a2:Free() ; a1:Free(), free their framestrip completely to free up memory, and load in the replacement, we'll say b1 and b2. Now we have b1,b2,t1,t2,m1. Everyone with me? I unload the transition graphics, t2:Free() ; t1:Free(), free their framestrip completely and load in a sword slash graphic (defining the entire thing, raw file and all) in it's place (totally transparent at first). Now we have something like b1,b2,s1,s2,m1. The animation continues, the sword slash graphics frames are set so they appear and everything is in the right order and memory is saved. Title: Re: Advanced Sprite Usage Post by: daltonlaffs on May 30, 2007, 07:48:56 AM 0.0 0.0 0.0 0.0 0.0 0.0 0.0
You may have just found the one thing that can save my, and many others', projects. I was wondering how the sprite ordering could be done, and looks like you found it! Now, for the usefulness... let's see if I can piece together a sprite system that keeps this rule in mind and is then capable of handling all the freeing and holding for you. *Drinks 8 cups of coffee and gets back to the keyboard* |