The normal 2D hardware in the DS is capable of displaying 128 sprites on each screen or engine, for a total of 256 different sprites on both.
Each sprite can be horizontal or vertical, can be moved across the screen, can be animated (by updating the image used), can become partly transparent, or even become a patchwork!
Sprite rotation and zooming is also possible, but with a special catch: you cannot set a rotation / zoom setting for each sprite, but instead you must assign the sprite one of the 32 “rotsets” available. Therefore, all the sprites can rotate, zoom, or both, but only in 32 different ways at once. Several sprites can share the same rotset, and will be rotated and/or enlarged in the same way.
Thanks to Bennyboo for the image.
So the max is 256 pixels wide and 192 pixels high. Given that the first pixel is the number 0, not 1, it means 0-255 and 0-191, as shown in the diagram.
In addition, the position of a sprite is limited to certain values. X can only be between 0 and 511, and Y between 0 and 255. That means putting a sprite at the position X = 512 is equivalent to putting it in position X = 0! That is called sprite wrapping.
The Sprites can have 3 different color modes:
16 color palettes, with a total of 16 different screen palettes. This is widely used in GBA, but disappeared in DS. 16 colour sprites can use all 16 palettes, meaning if you decide to, you can choose different colour palettes for sprites, so you create different looking sprites by only using one sprite, just by changing the palette. Each tile of a 16 colour takes up 32 bytes.
256 color palettes with a total of 16 types of palettes per screen. 256 color pallets use twice the memory of 16 color.
16-bit sprites do not use palettes. These sprites take up much more video ram than the rest.
In the end 256 color sprites are recommended in terms of color possibilities and video ram usage.
The DS can handle quite a few different sprite sizes, but are limited to specific sizes due to the hardware. The chart below illustrates the sprite sizes the DS hardware can handle.
| 8 | 16 | 32 | 64 | |
|---|---|---|---|---|
| 8 | 8×8 | 16×8 | 32×8 | |
| 16 | 8×16 | 16×16 | 32×16 | |
| 32 | 8×32 | 16×32 | 32×32 | 64×32 |
| 64 | 32×64 | 64×64 |
To use sprites of odd proportions, simply put them in a sprite with the size that closest reflects the actual sprite size. For example, if you have a 48×48 pixel sprite, you would place it in a 64×64 box within your paint program of choice, and set the unused area the transparent color of choice.
If you have a round sprite, like a Frisbee, you wouldn't want the square border to show. In order for the background to be 'removed', set it as the transparent color. There can only be 1 transparent color per sprite.
Here are some common colors used for transparency:
| R | G | B | |
|---|---|---|---|
| Magenta | 255 | 0 | 255 |
| Black-red | 1 | 0 | 0 |
| Off Black | 1 | 1 | 1 |
| Off White | 254 | 254 | 254 |
For sprite conversion, please refer to the Using PAGfx section.
The following examples are updated from the latest palib release.
This example can be found in: palib\examples\Sprites\Basics\CreateSprite
#include <PA9.h> // PAGfx Include #include "all_gfx.h" int main(void){ PA_Init(); //PAlib inits PA_LoadSpritePal(0, // Screen 0, // Palette number (void*)sprite0_Pal); // Palette name PA_CreateSprite(0, // Screen 0, // Sprite number (void*)vaisseau_Sprite, // Sprite name OBJ_SIZE_32X32, // Sprite size 1, // 256 color mode 0, // Sprite palette number 50, 50); // X and Y position on the screen while(1) // Infinite loops { } return 0; } }
Everything is pretty clear here. If you are having trouble please refer to the template guide in the installation section.
// PAGfxConverter Include #include "all_gfx.h"
This includes all the graphics that have been converted, the bin files must be in the data folder, or another folder defined in the makefile to be included. The all_gfx.h file must be in the source folder or includes folder where all the .c files can include it.
PA_LoadSpritePal(0, // Screen 0, // Palette number (void*)sprite0_Pal); // Palette name
This loads a palette on the bottom screen in the first palette number of 16 (0-15). Forgetting to load a palette will cause the sprite to load invisible, or with wonky colors if you forget to delete an old palette.
PA_CreateSprite(0, // Screen 0, // Sprite number (void*)vaisseau_Sprite, // Sprite name OBJ_SIZE_32X32, // Sprite size 1, // 256 color mode 0, // Sprite palette number 50, 50); // X and Y position on the screen
Everything is self explanatory here.
And that is it, the sprite will load up.
For a 16color sprite, you would use the following:
The palette:
PA_LoadSprite16cPal(0, // Screen 0, // Palette number (void*)sprite0_Pal); // Palette name
And for creating the sprite:
PA_CreateSprite(0, // Screen 0, // Sprite number (void*)vaisseau_Sprite, // Sprite name OBJ_SIZE_32X32, // Sprite size 0, // 16 color mode 0, // Sprite palette number 50, 50); // X and Y position on the screen
Note the color mode is set to 0 for 16 colors. If the mode is set wrong, you may have sprite corruption.
Moving sprites are important for game play.
This example can be found in palib\examples\Sprites\Movement\MoveSprites
for (i = 0; i < 16; i++) PA_CreateSprite(0, i,(void*)vaisseau_Sprite, OBJ_SIZE_32X32,1, 0, i << 4, i << 3); // This loads sprites a bit everywhere
This loads a few sprites on the screen. If you are unsure of the for loop and what « or » are, please refer to your favorite C or C++ tutorial.
while(1) { // Use the MoveSprite function on all sprites... for (i = 0; i < 16; i++) PA_MoveSprite(i); // The MoveSprite function checks if you are touching a sprite, and moves it around if* // *you are... Pretty nice if you have multiple sprites around PA_WaitForVBL(); }
PA_MoveSprite is used for stylus movement of sprites. It automatically sets which ever sprite is selected and moves it to the stylus coordinates. Again a for loop is used to loop through all the created sprites to check which ones to move.
PA_SetSpriteXY(screen, sprite, x, y);
This is a fairly important function. Just put in the screen, the sprite number of the sprite to move, and then a new position (x and y), then the sprite is moved to the new position. Positions are based on the sprites top left corner so setting a 32×32 sprite at 240,176 will only show the top left 16×16 of the sprite. On another note, you can also use PA_SetSpriteX(screen,sprite,x) and PA_SetSpriteY(screen,sprite,y) if you do not want to set the x and y positions at the same time.
There are 2 more functions available : PA_GetSpriteX(screen, sprite) and PA_GetSpriteY(screen, sprite) which return the sprite's coordinates in the PAlib sprite system. The first thing you'll notice is that these values will always range between 0 and 511 for X, 0 and 255 for Y, because these are hardware limits.
If a sprite is moved off screen, it will eventually wrap around. At X position of 512, the x position will be set to 0, and a negative x position will wrap to 511. Y values work similarly but do not have the same distance to wrap
These functions are debug only and are not recomended for use. It is better to keep track of your sprites positions through variables you have created.
Now we can move sprites using the keys on the DS now that we understand the SetSprite functions. This example can be found at: palib\examples\Sprites\Movement\MoveSpritewithKeys
Only the important lines will be covered.
s32 x = 0; s32 y = 0; // sprite position...
These two variables are used to keep track of the X and Y position of the sprite we are moving.
x += Pad.Held.Right - Pad.Held.Left; y += Pad.Held.Down - Pad.Held.Up;
When Pad.Held.Right is held, it is given a value of 1, Pad.Held.Left is 0 as it is not true. So it ends up looking like this:
x += Pad.Held.Right - Pad.Held.Left; -> x += 1 - 0;
This moves the sprite 1 pixel per frame. To give you an idea of speed, the DS runs at 60 frames per second, 256/60 = 4.22 seconds for a sprite to cross the screen horizontally at one pixel per frame.
You could also do the following:
if (Pad.Held.Right) x = x + 1;
How ever it is not as efficient and requires more typing to achieve a similar effect to that of the first example.
The same idea applies for moving up and down.
Now that we are manipulating the x and y position of a sprite, we need to update its location on the screen:
PA_SetSpriteXY(0, // screen 0, // sprite x, // x position y); // y...
The movement can be manipulated to move at different speeds rather than just 1 pixel per frame.
x += (Pad.Held.Right - Pad.Held.Left) * speed; y += (Pad.Held.Down - Pad.Held.Up) * speed;
Speed can be set to any integer of your needs. Since Pad.Held.Right-Pad.Held.Left = 1, the equation is 1*speed. Setting speed to 6 for example will move the sprite at 6 pixels per frame.
Stylus movement works similar to moving sprites using the keys.
PA_SetSpriteXY(screen,sprite number,Stylus.X,Stylus.Y);
Instead of manipulating x and y variables with keys, we set the sprite to the Stylus' coordinates.
There are two functions for detecting if the Stylus is touching a sprite, PA_SpriteTouched and PA_SpriteTouchedPix.
*PA_SpriteTouched just checks if a sprite is touched, including transparent areas.
*PA_SpriteTouchedPix checks if only the non-transparent areas are touched on a sprite.
Other then that they work exactly the same.
The example can be found in: palib\examples\Sprites\Basics\SpriteTouched
u8 i = 0; for (i = 0; i < 8; i++) PA_CreateSprite(0, i,(void*)mollusk_Sprite, OBJ_SIZE_32X32,1, 0, i << 5, i << 4); PA_OutputSimpleText(1, 0, 10, "Please touch a sprite"); while(1) { // Now we'll test every sprite to see if we touch it... for (i = 0; i < 8; i++) { if (PA_SpriteTouched(i)) PA_OutputText(1, 0, 15, "Sprite %d ", i); // If we touch the sprite, returns 1... } PA_WaitForVBL(); }
PA_SpriteTouched(sprite) is a simple function that returns 0 if touched and 1 if it is touched. There is a slight problem though because the function doesn't detect if the stylus is on screen and is touching. So to prevent unwanted results:
if(Stylus.Held && PA_SpriteTouched(sprite))
Sprites can be rotated and zoomed using the hardware. However, there are limitations. There are only 32 Rotation sets (rotsets) per screen. That means you can only have up to 32 different rotations for all sprites. Multiple sprites can use the same rotset. All sprites within a rotset will be controlled exactly the same as each other, so rotating one sprite within a rotset rotates them all.
We'll start with Sprite Rotations. The example is Sprite_Rotation.
// Activate rotations for that sprite PA_SetSpriteRotEnable(0,// screen 0,// sprite number 0);// rotset number. You have 32 rotsets (0-31) per screen. 2 sprites with* // *the same rotset will be zoomed/rotated the same way... u16 angle = 0; // Rotation angle... while(1) { ++angle; // change the angle angle &= 511; // limit the range to 0-511. works only with 1, 3, 7, 15, 31, etc... (2^n - 1) // Fast function for rotations without zoom... PA_SetRotsetNoZoom(0, //screen 0, // rotset angle); // angle, from 0 to 511 PA_WaitForVBL(); // Synch }
First off, you create a sprite, just as usual, with its palette and all. Then, you need to activate the sprite in rotation/zoom mode and give him a rotset (from 0 to 31), which is done with PA_SetSpriteRotEnable(screen, sprite, rotset). Once this is done, the sprite is ready to rotate ! When you want to stop rotating it, you can use PA_SetSpriteRotDisable(screen, sprite).
The few lines of code directly following aren't too important, it's just declaring a variable for the angle, and adding 1 'degree' to it each turn… There is, though, a major thing to know about the angle. It's not a 360° angle, but ranges from 0 to 511, and it's counterclockwise. Why ? Because that's what is best for the DS, and it's much faster that way than with normal angles.
So what's the angle &= 511; all about ? You'll have a more complete tutorial on the & operation in the math tutorial coming up. All you need to know is that it limits the variables range to that value, but only takes 2^n - 1 numbers : 1, 3? 7, 15, 31, 63, 127, 255, 511, etc. So it limits the variable's range to 0-511, which is exactly our angle's limits ! What happens if the value goes over 511 ? It goes back to 0, and so on. So 512 will give 0, 513 will give 1, etc. This is also true for negative values, -1 giving… 511.
Next comes the important function, PA_SetRotsetNoZoom(screen, rotset, angle); . Never forget that here, you are manipulating the rotset (0-31) and not the sprite, that's why you don't use the sprite number anymore. You just give the screen, the rotset, and the angle (0-511) as arguments, and PA_SetRotsetNoZoom will rotate the sprite just like you want !
As this example has an angle to which 1 is added every frame, you can compile the example and see on hardware how it turns.
Last thing : the sprite is rotated from it's central point.
Now that we have seen how to rotate a sprite, we'll see how to zoom it. It's fairly easy, once again, and the example, Sprite_Zoom, is really similar to the one we've just seen.
u16 zoom = 256; // Zoom. 256 means no zoom, 512 is twice as small, 128 is twice as big.... while(1) { zoom -= Pad.Held.Up - Pad.Held.Down; // Change the zoom according to the keys... // Fast function for zoom without rotations... PA_SetRotsetNoAngle(0, //screen 0, // rotset zoom, zoom); // Horizontal and vertical zoom. You can have a sprite* // *streched out if you want, with the zoom only for x or y axis....
First off, you have the zoom variable… Why is it set to 256 ? Because… 256 means NO zoom. The DS zoom works the following way :
To make it simple, the base zoom is 256, smaller values give a bigger sprite, and bigger values give a smaller sprite. Here, the zoom is modified by the Pad Up and Down keys, so you can check for yourself the result.
Now, let's check the important zoom function : PA_SetRotsetNoAngle(screen, rotset, zoomx, zoomy);. Why are there 2 zoom values ? Because you can zoom your sprite independently on the X and Y axis if you want ! Even though most of the time you'll want to zoom it the same way on both axis, it can be good to have different zooms, thus creating different effects
The sprite is zoomed from the central point, just like for the rotations…
If you're smart (or if you were careful when reading this tutorial and the Zoom example in PAlib), you should have 2 questions, which are in fact pretty much the same :
Well, first : if your sprite is too big, everything beyond the sprite frame (like 32×32, for example), will just be cut off ! Ok, this is very limiting, but hey, Nintendo thought of everything !
And that's where question 2, PA_SetSpriteDblsize(screen, sprite, enable/disable) comes in. If you double-size a sprite, it won't actually zoom it to 200%, but rather double its frame size. So a 32×32 sprite becomes a 64×64 (with the 32×32 image in its center), and a 64×64 becomes 128×128.
Now that you know this, you see how to go beyond the sprite size limit if you want to zoom your sprite a little more. You have to consider one last thing, though : if you double the canvas size, and since the sprite position is the top left corner… it changes the sprite's center on the screen. So if you place 2 sprites at the exact same coordinates, but one double-sized and one normal, you'll see they're not placed the same way.
These 2 examples just taught you how to rotate or zoom, but in fact you can do both at the same time if you need to. The PAlib example is the Sprite_RotZoom one, and it's very much like the other ones, once again, but contains both the angle and zoom variables. Look at the example to see the code.
The only function this time around, is PA_SetRotset(screen, rotset, angle, zoomx, zoomy);. It's just like a combination of the 2 preceding functions, nothing terrible !
Sprite flipping is really simple. There are just 2 functions to flip a sprite :
That's all there is to it. 1 sets the flip on, 0 removes the flip, that's it. You can flip horizontally, vertically, or both at the same time.
Note, you cannot flip a rotsprite, it resets the rotation.
The Mosaic is an easy effect to use. It was used in Super Mario Bros, for example, and changes the way the sprite looks by replacing single pixels by squares of a given size (from 1×1 blocks to 15×15 pixel blocks). What's so good about that? It can be used for transition effect on sprites, a sort of blurring effect, etc.
The DS and PAlib offer you a very simple control over the Mosaic effect. Once you have created a sprite, you can activate the effect for a given sprite using PA_SetSpriteMosaic(Screen, Sprite, Mosaic on/off (1/0));.
Once this is done, you can easily change the mosaic values, horizontally and vertically (so you could have like 1×8 pixel blocks if you want) using the following function : PA_SetSpriteMosaicXY(screen, horizontal block size, vertical size…);
You can control each sprite to activate or deactivate the mosaic effect, but the mosaic block level is the same for all activated sprites on a given screen. So you can't have one sprite with a certain mosaic, and another with a different one.
Transparency, or Alpha-Blending, can be nice in a game or application. It looks great and professional and isn't hard to do.
PAlib uses the DS's hardware for alpha blending. There is one limitation however, all sprites share the same alpha blending level, you cannot individually set some sprites too have more alpha blending then another.
The code is fairly easy to understand, and you have an Alpha-blending example in the sprite examples…
PA_SetSpriteMode(0, // Screen 0, // Sprite 1); // Alphablending s16 alpha = 7; // Transparency level // Enable the alpha-blending PA_EnableSpecialFx(0, // Screen SFX_ALPHA, // Alpha blending mode 0, // Nothing SFX_BG0 | SFX_BG1 | SFX_BG2 | SFX_BG3 | SFX_BD); // Everything normal while(1) // Infinite loops { alpha += Pad.Newpress.Up - Pad.Newpress.Down; PA_SetSFXAlpha(0, // Screen alpha, // Alpha level, 0-15 15); // Leave this to 15 PA_WaitForVBL(); }
PA_SetSpriteMode(screen, sprite, mode); is used to enable alpha blending on a sprite. Be sure to check out the documentation for info on the other available modes. The next step is to set up the DS's special effects system using PA_EnableSpecialFx(Screen, SFX_ALPHA (Alpha blending mode), 0 (leave to 0 for now), SFX_BG0 | SFX_BG1 | SFX_BG2 | SFX_BG3 | SFX_BD);.
*Screen should be fairly obvious by now
*SFX_Alpha is the mode we are activating effects for
*the next argument where the 0 is, is the target for the effects to activate on. Due to setting the Sprite mode for alpha blending we do not need to set any target here.
*SFX_BG0, etc, are the targets to be seen through the effect, here we see bg layers 0 -3 and the backdrop meaning all backgrounds will show through the sprite.
PA_SetSFXAlpha(screen, alpha level (0-15), normal level (leave to 15));
*The first alpha level is how much of the sprite to show, adjusting it according to your needs will make the sprite fade
*The second alpha level value is how much of the targets(backgrounds) to appear through the sprite.
A value of 0,16, would make the sprite completely invisible, 16,0 would make the sprite completely solid.
Note, you cannot see sprites through alpha blended sprites.
Frames are useful for animations and sprite states. To use sprites with frames, each frame must be organized in a vertical sprite strip.
This example will show you how to change a sprites frame based on key presses and can be found in: palib\examples\Sprites\Animations\Frames
PA_CreateSprite(0, 0,(void*)frames_Sprite, OBJ_SIZE_16X32,1, 0, 128-16, 64); while(1) { if (Pad.Held.Up) PA_SetSpriteAnim(0, 0, 0); // screen, sprite, frame if (Pad.Held.Down) PA_SetSpriteAnim(0, 0, 2); // screen, sprite, frame if (Pad.Held.Left) PA_SetSpriteAnim(0, 0, 3); // screen, sprite, frame if (Pad.Held.Right) PA_SetSpriteAnim(0, 0, 1); // screen, sprite, frame PA_WaitForVBL(); }
PA_SetSpriteAnim(screen, sprite, frame number); is used the change the frame, everything is pretty straight forward here.
Note
*Only the current frame is loaded in the vram, the rest are stored in the main ram until needed
Sprite animations are simple, your sprite must be organized in frames like the example above for animations to work properly.
The sprite animation example can be found in: palib\examples\Sprites\Animations\SpriteAnim2
Here is the main difference between frames and animations:
PA_StartSpriteAnim(0, // screen 0, // sprite number 0, // first frame is 0 6, // last frame is 6, since we have 7 frames... 5); // Speed, set to 5 frames per second
Sprites animated with this function will loop indefinitely.
PA_StartSpriteAnim(screen, sprite, first frame, last frame, speed) Starts the animation from the first frame to last at the given speed in frames per second. One thing to note, using this function in a loop will continuously restart the animation making it appear to not animate.
You can use PA_StopSpriteAnim(screen, sprite) to stop the animation, or PA_PauseSpriteAnim(screen, sprite, pause (1 to pause, 0 to unpause)) to pause/unpause the animation.
This section basically covers animations with different frames. The example can be found in: palib\examples\Sprites\Animations\SpriteAnim
The image here is similar to the frames example, but has more frames for animation in other directions. There are only 3 directions here because we can use the DS's hardware to flip the sprite for the 4th direction.
while(1) { // Animation code... if(Pad.Newpress.Up) PA_StartSpriteAnim(0, 0, 0, 3, 6); if(Pad.Newpress.Down) PA_StartSpriteAnim(0, 0, 8, 11, 6); if(Pad.Newpress.Right) { PA_StartSpriteAnim(0, 0, 4, 7, 6); PA_SetSpriteHflip(0, 0, 0); } if(Pad.Newpress.Left) { PA_StartSpriteAnim(0, 0, 4, 7, 6); PA_SetSpriteHflip(0, 0, 1); } if(!((Pad.Held.Left)||(Pad.Held.Up)||(Pad.Held.Down)||(Pad.Held.Right))) PA_SpriteAnimPause(0, 0, 1); // Moving Code y += Pad.Held.Down - Pad.Held.Up; x += Pad.Held.Right - Pad.Held.Left; PA_SetSpriteXY(0, 0, x, y); PA_WaitForVBL(); }
As you can see, each button press starts an animation from different frames for the different directions.
if(Pad.Newpress.Right) { PA_StartSpriteAnim(0, 0, 4, 7, 6); PA_SetSpriteHflip(0, 0, 0); }
Due to there only being 3 directions of animation in the sprite strip, we use the hardware to flip the sprite for moving left and right.
if(!((Pad.Held.Left)||(Pad.Held.Up)||(Pad.Held.Down)||(Pad.Held.Right))) PA_SpriteAnimPause(0, 0, 1);
Finally we have this which pauses the animation when no pads are held.
Extended animations are just functions with extended control over animations. They work exactly like the regular animation functions but have two extra parameters.
// First animation will be normal PA_StartSpriteAnim(0, // screen 0, // sprite number 0, // first frame is 0 3, // last frame is 3, since we have 4 frames... 5); // Speed, set to 5 frames per second // Extended animations for the rest PA_StartSpriteAnimEx(0, 1, 0, 3, 5, ANIM_ONESHOT); // just play it once... PA_StartSpriteAnimEx(0, 2, 0, 3, 5, ANIM_UPDOWN, -1); // back and forth, infinite number of times PA_StartSpriteAnimEx(0, 3, 0, 3, 5, ANIM_LOOP, 5); // Play it 5 times
The ANIM_ONESHOT is used to play an animation just once, when it ends it returns back to the first frame. To animate once and stay on the last frame, you can use the ANIM_UPDOWN animation type and have it run for just 1 cycle.
Depth and priorities are used to control which sprites overlap what, like people overlapping buildings or sprites appearing under backgrounds.
PA_SetSpritePrio(screen, sprite, priority); can set the priority of any given sprite
*Sprites with a lower sprite priority appear over top anything with a higher priority.
In this basic priority mode there are 4 levels of priority, one for each BG layer. A sprite with a priority of 1 will appear behind BG layer 0 and in front of BG layers 1,2 and 3.
PA_InitSpriteExtPrio(on(1)/off(0)); An extended priority system can be initialized to offer 256 levels of priority on both screens.
PA_SetSpriteExtPrio(screen, sprite,priority); This is used to change the extended priority of a sprite
Both systems can be used at once,using the PA_SetSpritePrio(screen, sprite, priority); you can change which bg layer and PA_SetSpriteExtPrio(screen, sprite,priority); to change its priority on that bg layer.
Eg. A sprite with normal priority 2 and extended priority of 3, will appear below a sprite with a normal priority of 0 and extended priority of 200
Dual sprites are just macros that cover sprite functions for both screens. Essentially a Dual sprite is a sprite which is created on both screens, when the sprite is on one screen, the sprite on the other is hidden.
These macros make it easy to make both screens seem like 1 in terms of sprite usage. Rather than being limited to a 256×192 screen, you have 256×384 plain with 0,0 being the top left on the top screen, and 256,384 being bottom right of the bottom screen.
Creating and manipulating these sprites are exactly the same as the normal sprite functions however have the prefix Dual in their function names. Screen values do not apply as they use both screens.
Eg.
PA_DualCreateSprite(…)
PA_DualSetSpriteXY(sprite, x, y)
The space between the two screens can pose a problem for some. You can define the space between the two screens in terms of pixels. The default has it at 48 pixels, but you can change it with PA_SetScreenSpace(space in pixels).
Note Sprites smaller than the screen space will be hidden until they reach the other screen, in some cases it might be best to not use a screen space at all.
Examples with dual sprites can be found in: palib\examples\Sprites\Basics\DualSprite
grammar errors and some unneeded information
I guess there's a small part that was missing here : how the sprite system works… Knowing this will help you decide how to organize your graphics and optimize your code…
What is a sprite ? It's not just a single entity, but a mixture of several things :
In 2D programming, it is usually referred to an 2D image or animation. The Nintendo DS has dedicated 2D hardware which makes it very easy to use these.
1. The image, in 'raw format', which is your Name_Sprite array, converted using PAGfx or gfx2gba, grit or anything else… That's basically the graphics, which will be copied in the VRAM (Video Ram), in a specific part reserved for sprites (1 part for top screen, 1 part for bottom screen). Several sprites can share the same graphic, but as it has only 1 copy in that case, animating 1 sprite will change the graphics in the VRAM and thus animate all sprites the same way…
2. The sprite palette, which is shared for all the sprites. PAlib, by default, has 16 palettes for the sprite, so you could have 16 sprites with different palettes, or 10 with the first and other with the 15 others, etc… But in lots of cases (especially when you start out), you just use a single palette for all the sprites…
3. The DS knows all about the sprites thanks to the OAM (Object Attribute Memory), which is a place in memory to handle all the sprites. This is a huge array containing the basic info for all sprites, one by one… (numbered 0 to 127, 2 copies existing, one for each screen…). The infos are like : X and Y position, shape/size (square/rectangle, 8 pixels wide or more…), horizontal or vertical flips, etc… One important info : rotation/zoom on/off, and Rotset number (0 to 31).
4. The rotset contains how the sprite using that rotset will be zoomed/rotated. As there are only 32, you cannot have 128 sprites rotated 128 different ways :/ So only 32 sprites are available to be affine transformed. Seems like a limit, but in fact it doesn't matter that much, you can most of the time find a decent solution : several sprites can share the same rotset if needed to be rotated/zoomed identically… And you won't find that you would have more than 32 sprites anyway for most projects.
AJ
grammar errors, needs a rewrite
Q1. My sprite doesn't show up !!
Q2. My sprite has a background behind it!