#95515 - Rogmatic - Sun Jul 30, 2006 12:42 am
I'm trying to code a very simple side-scrolling shooter, so far all I've coded is the player's 'ship' sprite, and the ability to move that sprite using the arrow keys.
However, I've come across a very frustrating bug while coding the player's shots.
It's set to fire a shot only if a) there are less than 10 shots on the screen already and b) if it's been 10 iterations of the main loop since the last shot.
I've set it to turn off the shot sprite if it reaches the far side of the screen or if there are 10 shots 'in play', however, whenever a shot is 'turned off', all other shots on the screen stop moving.
I've spent the last 3 or 4 hours trying to fix this, hopefully you guys will see something I'm not.
Here's the code:
Note: I'm using the include files that come with the PERN project source code.
Thanks in advance.
However, I've come across a very frustrating bug while coding the player's shots.
It's set to fire a shot only if a) there are less than 10 shots on the screen already and b) if it's been 10 iterations of the main loop since the last shot.
I've set it to turn off the shot sprite if it reaches the far side of the screen or if there are 10 shots 'in play', however, whenever a shot is 'turned off', all other shots on the screen stop moving.
I've spent the last 3 or 4 hours trying to fix this, hopefully you guys will see something I'm not.
Here's the code:
Code: |
#include "gba.h" #include "player.h" #include "playershot.h" OAMEntry OAMCopy[128]; int PlayerShotOffset; int PlayerShots; int Delay; int NextShot; void PlayerShoot(); typedef struct { int x,y; OAMEntry* oam; int gfxID; }Sprite; Sprite player; Sprite playershot[9]; void WaitForVblank(void) { while(! (REG_DISPSTAT & DISPSTAT_VB)); while(REG_DISPSTAT & DISPSTAT_VB); } void InitOAM(void) { int i; for(i = 0; i < 128; i++) OAMCopy[i].attribute[0] = SPRITE_OFF; } void UpdateOAM(void) { int i; for(i = 0; i < 128 * sizeof(OAMEntry) / 4; i++) ((u32*)OAMMem)[i] = ((u32*)OAMCopy)[i]; } void GetInput(void) { if(!(REG_KEYS & KEY_UP)) if(player.y > 2) player.y = player.y - 3; if(!(REG_KEYS & KEY_DOWN)) if(player.y < (158 - 16)) player.y = player.y + 3; if(!(REG_KEYS & KEY_LEFT)) if(player.x > 2) player.x = player.x - 3; if(!(REG_KEYS & KEY_RIGHT)) if(player.x < (238 - 16)) player.x = player.x + 3; if(!(REG_KEYS & KEY_A)) if((PlayerShots <= 10) && (Delay <= 0)) PlayerShoot(); } void PlayerShoot(void) { if(PlayerShots >= 10) { playershot[PlayerShots - 1].oam->attribute[0] |= SPRITE_OFF; PlayerShots--; NextShot = 0; } PlayerShots++; playershot[NextShot].x = player.x + 20; playershot[NextShot].y = player.y + 4; playershot[NextShot].oam->attribute[0] ^= SPRITE_OFF; NextShot++; Delay = 10; } void MoveShots(void) { int i; for(i = 0; i <= PlayerShots; i++) { if(playershot[i].x >= 240) { PlayerShots--; playershot[i].oam->attribute[0] |= SPRITE_OFF; NextShot = 0; } playershot[i].x = playershot[i].x + 4; } } void MoveSprite(Sprite* sp) { sp->oam->attribute[1] &= 0xFE00; sp->oam->attribute[1] |= (sp->x & 0x01FF); sp->oam->attribute[0] &= 0xFF00; sp->oam->attribute[0] |= (sp->y & 0x00FF); } int main(void) { int i; Delay = 0; SetMode(MODE_0 | OBJ_ENABLE | OBJ_MAP_1D); InitOAM(); player.oam = &OAMCopy[11]; player.x = 10; player.y = 10; player.gfxID = 11; player.oam->attribute[0] = COLOR_256 | SQUARE; player.oam->attribute[1] = SIZE_16; player.oam->attribute[2] = player.gfxID; for(i = 0; i < 9; i++) { playershot[i].oam = &OAMCopy[i]; playershot[i].x = 0; playershot[i].y = 0; playershot[i].gfxID = 0; playershot[i].oam->attribute[0] = COLOR_256 | SQUARE | SPRITE_OFF; playershot[i].oam->attribute[1] = SIZE_8; playershot[i].oam->attribute[2] = playershot[i].gfxID; } PlayerShots = 0; NextShot = 0; PlayerShotOffset = playershot[0].gfxID * 8 * 4 / 2; for(i = 0; i < 16 * 16 / 2; i++) { OBJ_GFXMem[player.gfxID * 16 + i] = playerData[i]; OBJ_GFXMem[PlayerShotOffset + i] = playershotData[i]; } for(i = 0; i < 256; i++) OBJPaletteMem[i] = playerPalette[i]; while(1) { GetInput(); MoveShots(); MoveSprite(&player); for(i = 0; i <= PlayerShots; i++) MoveSprite(&playershot[i]); WaitForVblank(); UpdateOAM(); Delay--; } } |
Note: I'm using the include files that come with the PERN project source code.
Thanks in advance.