Nintendo DS


Introduction


Version History

Day 1
Environment Setup

Links

WiFiMe

PA_Lib

Linux

Emulators

Downloads

Demos




NDS Magic Key MK2/MK3

   Hosted by
FrogNet


Document made with Nvu

 

Nintendo DS Development Tutorial :: Day 11 :: Sprites #4

 

Okay, now that we've covered the mosaic effect, let's learn some other neat things you can do to sprites: rotate and zoom.

The pig sprite for today's tutorial came from Reiner's Tilesets.  One thing to note here.  The pig sprite is actually a 32x32 pixel sprite but I created a 64x64 pixel sprite and put the pig in the middle. The reason I did this is because if you zoom in on a sprite, any more than would fit in the size you declared it will not be shown.  Confused?  Yeah, it's a little hard to explain.  Basically if you 2x zoom in on the sprite, you will only see half of it.  The rest gets lost.

 

// Includes
#include <PA9.h> // Include for PA_Lib
// Graphics Includes
// --- Sprites ---
// gfx2gba -D -fsrc -pSprites.pal -t8 SpaceShip.bmp
#include "gfx/Pig.raw.c"
#include "gfx/Sprites.pal.c"

// Global Variables
u8 Sprite1_X = 31; // X position of Sprite 1
u8 Sprite1_Y = 63; // Y position of Sprite 1
u8 Sprite2_X = 159; // X position of Sprite 2
u8 Sprite2_Y = 63; // Y position of Sprite 2
u8 Sprite3_X = 31; // X position of Sprite 3
u8 Sprite3_Y = 63; // Y position of Sprite 3
u8 Sprite4_X = 159; // X position of Sprite 4
u8 Sprite4_Y = 63; // Y position of Sprite 4
u16 Rotate = 0; // Rotation angle (0-512)
u16 Zoom_X = 128; // Amount to zoom horizontally
u16 Zoom_Y = 128; // Amount to zoom vertically
bool increment = true; // Used to zoom in or out

// Function: main()
int main(int argc, char ** argv)
{
PA_Init(); // Initializes PA_Lib
PA_InitVBL(); // Initializes a standard VBL

//PA_LoadSplash(); // PA_Lib splash screen

// Setup text system and write labels to the screens
PA_InitText(0, 0);
PA_InitText(1, 0);
PA_SetTextCol(0, 31, 31, 31);
PA_SetTextCol(1, 31, 31, 31);
PA_OutputSimpleText(1, 3, 7, "Sprite #1");
PA_OutputSimpleText(1, 5, 15, "Plain");
PA_OutputSimpleText(1, 19, 7, "Sprite #2");
PA_OutputSimpleText(1, 21, 15,"Rotate");
PA_OutputSimpleText(0, 3, 7, "Sprite #3");
PA_OutputSimpleText(0, 6, 15, "Zoom");
PA_OutputSimpleText(0, 19, 7, "Sprite #4");
PA_OutputSimpleText(0, 17, 15,"Rotate + Zoom");

// Load palettes
PA_LoadPal(PAL_SPRITE0, Sprites_Palette);
PA_LoadPal(PAL_SPRITE1, Sprites_Palette);

// Load sprites
PA_CreateSprite(1,0,(void*)Pig_Bitmap,OBJ_SIZE_64X64,
1,0,Sprite1_X,Sprite1_Y); // Sprite 1
PA_CreateSpriteEx(1,1,(void*)Pig_Bitmap,OBJ_SIZE_64X64,
1,0,0,0,0,0,0,0,Sprite2_X,Sprite2_Y); // Sprite 2
PA_CreateSpriteEx(0,0,(void*)Pig_Bitmap,OBJ_SIZE_64X64,
1,0,0,0,0,0,0,0,Sprite3_X,Sprite3_Y); // Sprite 3
PA_CreateSpriteEx(0,1,(void*)Pig_Bitmap,OBJ_SIZE_64X64,
1,0,0,0,0,0,0,0,Sprite4_X,Sprite4_Y); // Sprite 4

// Enable rotate & zoom
PA_SetSpriteRotEnable(1,1,0); // Sprite 2
PA_SetSpriteRotEnable(0,0,0); // Sprite 3
PA_SetSpriteRotEnable(0,1,1); // Sprite 4

// *** Set initial rotate & zoom amounts ***
PA_SetRotset(1,0,Rotate,256,256); // Sprite 2
PA_SetRotset(0,0,0,Zoom_X,Zoom_Y); // Sprite 3
PA_SetRotset(0,1,Rotate,Zoom_X,Zoom_Y); // Sprite 4

// Infinite loop to keep the program running
while (1)
{
// Increment Rotate angle
(Rotate<512) ? ++Rotate : Rotate=0;

// De/Increase Zoom amount
if (increment) {
Zoom_Y = (Zoom_X += 4);
if (Zoom_X == 512) increment=false;
} else {
Zoom_Y = (Zoom_X -= 4);
if (Zoom_X == 128) increment=true;
}

// Rotate and/or zoom sprites
PA_SetRotset(1,0,Rotate,256,256); // Sprite 2
PA_SetRotset(0,0,0,Zoom_X,Zoom_Y); // Sprite 3
PA_SetRotset(0,1,Rotate,Zoom_X,Zoom_Y); // Sprite 4

PA_WaitForVBL();
}

return 0;
} // End of main()

 

Code Explanation

u16 Rotate = 0;
This will be used in the PA_SetRotset() function later.  The main thing to remember is that the rotation angle goes from 0 - 512 (not 360!).

u16 Zoom_X = 128;  u16 Zoom_Y = 128;
This will also be used in the PA_SetRotset() function later.  The key here is that 128 = 2x zoom, 256 = no zoom, and 512 = 1/2 zoom.

PA_SetSpriteRotEnable();
This is used to setup the rotation for a sprite.  Its parameters are
    screen - 0 or 1
    sprite - slot of sprite you want to rotate
    rotset- rotation set to assign a sprite.  There can be from 0-31 rotsets per screen.  You can assign multiple sprites to the same rotset if you plan on rotating/zooming them identically.  You should notice that sprite 2 is on screen 1, in slot 1, and assigned rotset 0.  Sprite 3 is on screen 0, in slot 0, and assigned rotset 0.  Sprite 4 is on screen 0, in slot 1, and assigned rotset 1.  Sprite 1, of course, doesn't get rotated or zoomed, so that's why it's not included here.


(Rotate<512) ? ++Rotate : Rotate=0;
I used this type of command in a previous tutorial, so I hope you know it by now.  Basically I am incrementing the rotation angle variable from 0-512 (and around and around again).

if (increment) {...}
This section of code just increments the zoom variables from 0-512 (by 4 each time) and then back down to 0 (where it starts over again).  This gives you the effect of zooming in and then back out of a sprite.

PA_SetRotset(1,0,Rotate,256,256);              // Sprite 2
PA_SetRotset(0,0,0,Zoom_X,Zoom_Y);         // Sprite 3
PA_SetRotset(0,1,Rotate,Zoom_X,Zoom_Y); // Sprite 4
This is where all of the work of the program is taking place.  Hopefully you are able to run the demo on hardware so you can see what is going on - that will make this much easier to understand!  The parameters are as follows:
    screen - 0 or 1
    rotset - rotset you want to change. See PA_SetSpriteRotEnable() above.
    angle - rotation angle, can be from 0 - 512 (not 0 - 360!)
    zoomx - horizontal zoom, 128 is 2x, 256 is no zoom, and 512 is 1/2 zoom
    zoomy - vertical zoom, 128 is 2x, 256 is no zoom, and 512 is 1/2 zoom

That's it!  It's just that easy... well, pretty much.  One note, the first set of calls to PA_SetRotset() were included because the default setting for rotate/zoom were not set in PA_Lib and therefore you would get a weird graphical glitch if you called this function more than one VBL later than PA_SetSpriteRotEnable().  This behavior will be changed in the next version of PA_Lib.

 

Download

Day11_Sprites_4

 

Screenshot

Day1_Hello_World

 

Last Update: 10/31/2005

 

Google
 
Web aaronrogers.com/nintendods

 

<<

HOME

>>