#20426 - tethered - Tue May 11, 2004 4:59 am
hello,
before i post i just want to say thanks for all your assistance thus far. this forum is an invaluable resource to anyone who is curious about developing on the gba console, and, quite frankly, i couldn't have gotten as far as i have in such a short time period without your help. thanks!
with that said... i've created a multiple layer, parallax scrolling background in tile mode 0, text bg 0. originally, you could scroll up, down, left, right, and all of the diagonals in between by pressing the corresponding d-pad button. i've decided to take it a step further now by adding some basic physics.
the intention is to allow the user to "steer" by pressing left and right (i.e., they press left, and it decreases the angle of direction, they press right, and it increases the angle of direction). and then when the user presses up, it should provide forward motion in the direction that you are facing. for now, to keep things simple, as i dont have much experience with sprites, i'm moving just the background around. eventually, i would like to have a ship sprite in the center of the screen that rotates to reflect the angle, but thats something i will do in a later session.
anyway, i've gotten the basic formula down...
the velocity is a constant 3 units per loop iteration, the direction vector is represented as an angle ranging from 0 - 359, and to calculate the x and y components of the velocity based on the direction vector, i'm using sine and cosine, respectively.
here's the full source:
for the most part this seems to work. there is some slow down but that's not an issue at this point (i was kind of expecting it and i'm aware that you can pre-calculate the sine and cosine values). also, i'm aware that a lot of the other source isn't exactly the most efficient. as i said in an earlier thread, clarity is more important than optimization right now. the problem i'm running into, however, is that when you first begin to turn to the left it immediately jerks over to the right, and at various points around the rotation it jerks in different directions.
here is the compiled GBA rom:
http://cemmel.com/gbadev/demos/direction_and_motion.gba
i suspect it has something to do w/ my if statements that i'm using to roll over from 359 to 0, and 0 to 359, but i can't seem to make any real sense of it.
if anyone has any experience, please comment and let me know what i'm doing wrong.
thanks,
chuck
before i post i just want to say thanks for all your assistance thus far. this forum is an invaluable resource to anyone who is curious about developing on the gba console, and, quite frankly, i couldn't have gotten as far as i have in such a short time period without your help. thanks!
with that said... i've created a multiple layer, parallax scrolling background in tile mode 0, text bg 0. originally, you could scroll up, down, left, right, and all of the diagonals in between by pressing the corresponding d-pad button. i've decided to take it a step further now by adding some basic physics.
the intention is to allow the user to "steer" by pressing left and right (i.e., they press left, and it decreases the angle of direction, they press right, and it increases the angle of direction). and then when the user presses up, it should provide forward motion in the direction that you are facing. for now, to keep things simple, as i dont have much experience with sprites, i'm moving just the background around. eventually, i would like to have a ship sprite in the center of the screen that rotates to reflect the angle, but thats something i will do in a later session.
anyway, i've gotten the basic formula down...
the velocity is a constant 3 units per loop iteration, the direction vector is represented as an angle ranging from 0 - 359, and to calculate the x and y components of the velocity based on the direction vector, i'm using sine and cosine, respectively.
here's the full source:
Code: |
#include "math.h"
#include "gba.h" #include "master.pal.c" #include "lvl1bg0.raw.c" #include "lvl1bg0.map.c" #include "lvl1bg1.raw.c" #include "lvl1bg1.map.c" void SetVideoMode(void); void LoadPalette(void); void LoadBackground(void); int main() { float f_x = 0, f_y = 0; float f_velocity = 3; float f_angle = 0; float f_x_displacement = 0, f_y_displacement = 0; SetVideoMode(); LoadPalette(); // vdraw . . . while (REG_VCOUNT < 160); LoadBackground(); while(1) { f_x_displacement = 0; f_y_displacement = 0; // When LEFT is pressed, the ship should rotate to the left, thus // decrease angle by the specified rate... When it reaches 0, // roll over to 359... if(keyDown(KEY_LEFT)) { f_angle = f_angle - .05; if (f_angle < 0) f_angle = 359; } // When RIGHT is pressed, the ship should rotate to the right, thus // increase the angle by the specified rate... When it reaches 359, // roll over to 0... if(keyDown(KEY_RIGHT)) { f_angle = f_angle + .05; if (f_angle > 359) f_angle = 0; } // When UP is pressed, the ship should move at the specified velocity // in the direction it is facing... sin(angle) * velocity calculates // the displacement of the x component, and cos(angle) * velocity // calculates the displacement of the y component if(keyDown(KEY_UP)) { f_x_displacement = f_x_displacement + sin(f_angle) * f_velocity; f_y_displacement = f_y_displacement + cos(f_angle) * f_velocity; } // vdraw . . . while (REG_VCOUNT < 160); // update x and y coordinates for background f_x = f_x + f_x_displacement; f_y = f_y - f_y_displacement; // inverted :) REG_BG0HOFS = f_x; REG_BG0VOFS = f_y; REG_BG1HOFS = (f_x / 2) + 100; // 100 == offset REG_BG1VOFS = (f_y / 2) + 100; REG_BG2HOFS = f_x / 7.5; REG_BG2VOFS = f_y / 7.5; // wait for vblank . . . while (REG_VCOUNT >= 160); } return 0; } void SetVideoMode(void) { // set video mode SetMode(MODE_0 | BG0_ENABLE | BG1_ENABLE | BG2_ENABLE); } void LoadPalette(void) { int i; // load palette data for (i = 0; i < 256; i++) BG_PaletteMem[i] = master_Palette[i]; } void LoadBackground(void) { u16* ScreenBB0 = (u16*)ScreenBaseBlock(0); u16* ScreenBB1 = (u16*)ScreenBaseBlock(1); u16* CharBB1 = (u16*) CharBaseBlock(1); u16* CharBB2 = (u16*) CharBaseBlock(2); int i; // set bg control register REG_BG0CNT = BG_COLOR_256 | TEXTBG_SIZE_256x256 | (0 << SCREEN_SHIFT) | (1 << CHAR_SHIFT); REG_BG1CNT = BG_COLOR_256 | TEXTBG_SIZE_256x256 | (0 << SCREEN_SHIFT) | (1 << CHAR_SHIFT); REG_BG2CNT = BG_COLOR_256 | TEXTBG_SIZE_256x256 | (1 << SCREEN_SHIFT) | (2 << CHAR_SHIFT); // load map data // ------------- // layer 0 for (i = 0; i < 1024; i++) ScreenBB0[i] = lvl1bg0_Map[i]; // layer 1 for (i = 0; i < 1024; i++) ScreenBB1[i] = lvl1bg1_Map[i]; // load tile data // -------------- // layer 0 for (i = 0; i < (23 * 64) / 2; i++) CharBB1[i] = ((u16*) lvl1bg0_Tiles)[i]; // layer 1 for (i = 0; i < (232 * 64) / 2; i++) CharBB2[i] = ((u16*) lvl1bg1_Tiles)[i]; } |
for the most part this seems to work. there is some slow down but that's not an issue at this point (i was kind of expecting it and i'm aware that you can pre-calculate the sine and cosine values). also, i'm aware that a lot of the other source isn't exactly the most efficient. as i said in an earlier thread, clarity is more important than optimization right now. the problem i'm running into, however, is that when you first begin to turn to the left it immediately jerks over to the right, and at various points around the rotation it jerks in different directions.
here is the compiled GBA rom:
http://cemmel.com/gbadev/demos/direction_and_motion.gba
i suspect it has something to do w/ my if statements that i'm using to roll over from 359 to 0, and 0 to 359, but i can't seem to make any real sense of it.
if anyone has any experience, please comment and let me know what i'm doing wrong.
thanks,
chuck