|
|
|
|
|
|
|
Nintendo
DS Development Tutorial :: Day 7 :: BGs 2
|
|
|
|
Well, after yesterday's mildly overwhelming code, I
decided to do something simple, yet powerful, for today. If you
look at the image at the below, you may think, "what's the big deal?"
What you are looking at is actually three background layers and a
sprite.
Parallax Scrolling
If you've done any video game programming, then you probably know what
parallax scrolling is. If not, then I'm sure you've seen the
technique used in numerous games, even if you don't know what it is.
Basically it's a method of scrolling different backgrounds at
different speeds used in 2D gaming to give the illusion of 3D.
Usually, the backgrounds farther away scroll at a slower speed
than those that are closest to the user. In this case, the sky
(BG3) doesn't scroll at all; the mountain (BG2) scrolls slowly; and the
grass (BG1) scrolls quickly. Today's tutorial covers horizontal
parallax scrolling. I'm planning on covering vertical
parallax scrolling (think space fighting game) in Day 9.
NOTE:
On 09/08/2005, PA_Lib 0.50a was released. It now comes with functions for parallax scrolling. This
tutorial has been updated to reflect the new functions.
|
|
|
// Includes #include <PA9.h> // Include for PA_Lib
// Graphics Includes // *** Backgrounds *** // gfx2gba -fsrc -m -pBackgrounds.pal -t8 BG*.bmp #include "gfx/BG1.map.c" // Grass
#include "gfx/BG1.raw.c" #include "gfx/BG2.map.c" // Mountain
#include "gfx/BG2.raw.c" #include "gfx/BG3.map.c" // Sky
#include "gfx/BG3.raw.c" #include "gfx/Backgrounds.pal.c" // *** Sprites *** // gfx2gba -D -fsrc -pSprites.pal -t8 Cloud.bmp #include "gfx/Cloud.raw.c" #include "gfx/Sprites.pal.c"
// Function: main() int main(int argc, char ** argv) { // Variables s16 Cloud_X = 100; // Sprite X coordinate u16 Cloud_Y = 35; // Sprite Y coordinate u32 scroll = 0; // Amount of parallax scroll
PA_Init(); // Initializes PA_Lib PA_InitVBL(); // Initializes a standard VBL
//PA_LoadSplash(); // PA_Lib splash screen
// Load Palettes PA_LoadPal(PAL_BG0, Backgrounds_Palette); // Backgrounds PA_LoadPal(PAL_SPRITE0, Sprites_Palette); // Sprites
// Load Backgrounds PA_LoadSimpleBg(0, 3, BG3_Tiles, BG3_Map, BG_256X256, 0, 1); // Sky PA_LoadSimpleBg(0, 2, BG2_Tiles, BG2_Map, BG_256X256, 0, 1); // Mtn PA_LoadSimpleBg(0, 1, BG1_Tiles, BG1_Map, BG_256X256, 0, 1); // Grs
// Setup horizontal parallax scrolling for backgrounds PA_InitParallaxX(0, 0, 512, 128, 0);
// Load Sprite PA_CreateSpriteEx(0,0,(void*)Cloud_Bitmap,OBJ_SIZE_64X64, 1,0,0,0,0,0,3,0,Cloud_X,Cloud_Y);
// Infinite loop to keep the program running while (1) { // Increment scroll amount (scroll < 512) ? ++scroll : scroll=0;
// Horizontally parallax scroll backgrounds PA_ParallaxScrollX(0, scroll);
// Scroll the cloud to the right PA_SetSpriteXY(0,0,Cloud_X+=2,Cloud_Y);
// Move cloud to the left side after it goes off the right side if(Cloud_X > 254) Cloud_X = -63;
PA_WaitForVBL(); }
return 0; } // End of main()
|
|
|
|
Code
Explanation
PA_LoadSimpleBg(...);
The first thing you should notice here is the second parameter I am
using to load the backgrounds. The higher the priority, the closer the
image is to the viewer. So, the sky is farthest away, so it gets
the lowest priority which is 3. The mountain is on top of the
sky, so it gets 2. The grass is in front of the mountain, so it
is set to 1. If I wanted something in front of the grass, it
would have to be set to 0.
PA_InitParallaxX(...);
This is used to initialize parallax scrolling and choose the speeds for each background.
screen - 0 or 1
bg0 - speed of scroll. 0 = none, 128 is slow, 256 is normal, 512 is fast
bg1 - speed of scroll. 0 = none, 128 is slow, 256 is normal, 512 is fast
bg2 - speed of scroll. 0 = none, 128 is slow, 256 is normal, 512 is fast
bg3 - speed of scroll. 0 = none, 128 is slow, 256 is normal, 512 is fast
PA_CreateSpriteEx(...);
If you looked carefully, you would have seen that this is a slightly
different function than what we've used up to this point for creating a
sprite. It adds the following parameters:
obj_mode - Object mode (normal, transparent, window).
Not functional
yet, please leave to 0 for now.
mosaic - Mosaic. Not functional yet, please leave to 0 for now.
hflip - Horizontal flip on or off.
vflip - Vertical flip.
prio - Sprite priority regarding backgrounds : in front of which background to show it (0-3)
dblsize - Double the sprite size. Activate if you are going to rotate and zoom in on the sprite.
All we care about for today's tutorial is the sprite
priority. Remember, the lower the number, the higher the priority. We want it to be behind the mountain (priority 2) but
in front of the sky (priority 3). If a sprite's priority is lower
than a background's priority, then the sprite goes behind the
background. If a sprite's priority is the same as or higher than a background,
then the sprite goes on top of the background. Therefore, we set the sprite's priority to 3.
(scroll < 512) ? ++scroll : scroll=0;
Hopefully you know what this line means. Just in case you don't,
I'll give you a quick explanation. First of all, read it like this if (scroll < 512) { ++scroll } else { scroll=0 }.
Makes sense? The reason I chose 512 is because that is
the speed of the fastest parallax scrolling background. See PA_InitParallaxX() in the code to see what I mean. If I had used another number the scroll would not have been seamless.
PA_ParallaxScrollX(0, scroll);
So now we've come to the function that actually does the scrolling.
You simply pass it the screen that has the backgrounds you
want to scroll and the amount of scroll. You should note
that this will scroll the backgrounds to the left. If you
want them to scroll to the right instead, you have to use a negative
value. Check out Day 9 to see how to do something like this.
One final note, I still didn't explain what parallax scrolling a background does
exactly. Well, it "scrolls" the background by the offset you pass
it. So, if you pass it an offset of 10, then the first 10 columns
from the image get moved to the end, and the rest "scroll" to the left.
The best way to understand this is to fire up the demo on your
DS, or in the iDeaS emulator, and see what it looks like.
Okay, I think that's enough for today. You should definitely play
around with this example and see what modifications you can make to it.
How about adding a second sprite (cloud?) that floats in front of
the mountain? Good Luck!
|
|
|
|
Download
Day7_BGs_2
|
|
|
|
Screenshot

|
|
|
|
Last Update: 10/31/2005
|
|
|
|
|
|
|
|
|
|