Just a small update. I have updated the methods used to draw sprites, and have successfully duplicated the 4bit palettes to get some random colors, but now i have run into a small problem.
(i now the picture is small, but all that is needed to see is that the tiles on the bottom are cut off, and that some sprites are on the top of the bottom screen which shouldnt be there, explained later)
When i was using the old way, my tiles worked fine, but now as seen in the picture, the tiles are misaligned. Also for some reason, there are some artifacts that show up on the top of the bottom screen for some reason which arent meant to be there. I dont know where or how that has occured, and hopefully someone can point it out to me in the following piece of
programming.
Note. i have edited out the misc pieces of code that dont relate to the balloons of the gfx settigns.
Essentially what happens, is a bunch of balloons is made at the start of each wave underneath the bottom screen. They then rise and the goal is to pop all of the balloons before they rise off the screen. If they arent poped, they go off the bottom screen, and rise above the top screen before disappearing. The game concept all works fine, it is just the tiles that are misaligned now that is the problem.
Code: Select all
// main.cpp
void setupGraphics() // function to setup the gfx engine
{
oamInit(&oamMain, SpriteMapping_1D_64, false );
oamInit(&oamSub, SpriteMapping_1D_64, false);
oamClear(&oamMain,0,127);
oamClear(&oamSub,0,127);
lcdMainOnBottom(); // switch main / sub engine on screens
vramSetBankF( VRAM_F_MAIN_SPRITE ); // set VRAM Bank F to use sprites
vramSetBankC( VRAM_C_SUB_BG );
vramSetBankI( VRAM_I_SUB_SPRITE );
videoSetMode( MODE_0_2D | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D_LAYOUT ); //
videoSetModeSub( MODE_0_2D | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D_LAYOUT ); //
consoleInit(&topScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true);
consoleSelect(&topScreen);
dmaCopy(gfx_balloonPal, SPRITE_PALETTE, gfx_balloonPalLen);
dmaCopy(gfx_balloonPal, SPRITE_PALETTE_SUB, gfx_balloonPalLen);
int n;
for(n = 1; n < 16; n++)
{
SPRITE_PALETTE[(n*16)+1] = RGB15(rand()%32,rand()%32,rand()%32);
SPRITE_PALETTE[(n*16)+2] = SPRITE_PALETTE[(n*16)+1];
SPRITE_PALETTE_SUB[(n*16)+1] = SPRITE_PALETTE[(n*16)+1];
SPRITE_PALETTE_SUB[(n*16)+2] = SPRITE_PALETTE[(n*16)+1];
}
for( n = 0; n < MAX_NUM_OF_BALLOONS; n++) // assign a sprite index to each balloon instance for rendering
{
balloonArray[n].setSpriteIndex(sprite_count);
balloonArray[n].initialize((u8*)gfx_balloonTiles);
balloonArray[n].setX(50 << 8);
balloonArray[n].setY(250 << 8);
sprite_count++;
}
}
void resetGame() // function to reset the variables ingame
{
...
oamClear(&oamMain,0,127);
oamClear(&oamSub,0,127);
...
}
void startWave() // function to start the next wave
{
int n;
for( n = 0; n < BALLOONS_PER_WAVE*wave; n++)
{
balloonArray[n].setX(((rand() % 224) + 16) << 8); // assign a random x location
balloonArray[n].setY(((rand() % 100*wave) + 195) << 8); // assign a random y location underneath
balloonArray[n].resetActive(); // reset balloon to active
balloonArray[n].setOnBottom();
}
}
void updateLogic() // function to update game logic
{
...
int m;
for( m = 0; m < BALLOONS_PER_WAVE*wave; m++) // for each balloon that is active in the wave
if(balloonArray[m].isActive())
balloonArray[m].update(); // change its location
}
void updateGraphics() // function to update the sprites onscreen
{
consoleClear(); // clears the console
int n;
for(n = 0; n < BALLOONS_PER_WAVE*wave; n++)
balloonArray[n].render();
displayMessage();
oamUpdate(&oamMain);
oamUpdate(&oamSub);
}
void resetVariables() // function to reset variables at the start
{
...
oamClear(&oamMain,0,127);
oamClear(&oamSub,0,127);
...
}
int main() // main loop
{
setupGraphics();
resetVariables();
while(1) // game loop
{
updateLogic();
processInput();
swiWaitForVBlank(); // wait for verticle refresh (60 fps)
updateGraphics();
}
return 0;
}
Code: Select all
//balloon.cpp && balloon.h
class Balloon
{
public:
Balloon();
~Balloon() {}
void initialize(u8* gfx);
void render();
void update();
void resetActive() {active = true;}
void switchActive() {active = false;}
void setX(int newX) {x = newX;}
void setY(int newY) {y = newY;}
void setSpriteIndex(u8 num) {sprite_index = num;}
void setOnTop() {onBottomScreen = false;}
void setOnBottom() {onBottomScreen = true;}
bool isActive() {return active;}
bool isTouched(touchPosition);
bool isOnBottomScreen() {return onBottomScreen;}
private:
u16* sprite_gfx_mem;
u16* sprite_gfx_mem_sub;
u8* frame_gfx;
u8 sprite_index;
SpriteSize size;
SpriteColorFormat format;
int rotationIndex;
int paletteAlpha;
int x;
int y;
bool active;
bool onBottomScreen;
};
const int yvel 144 // velocity of the balloons rising
Balloon::Balloon()
{
size = SpriteSize_32x32;
format = SpriteColorFormat_16Color;
rotationIndex = -1;
active = true;
onBottomScreen = true;
}
void Balloon::initialize(u8* new_gfx)
{
sprite_gfx_mem = oamAllocateGfx(&oamMain,SpriteSize_32x32, SpriteColorFormat_16Color);
sprite_gfx_mem_sub = oamAllocateGfx(&oamSub,SpriteSize_32x32, SpriteColorFormat_16Color);
frame_gfx = (u8*)new_gfx;
paletteAlpha = rand()%16;
dmaCopy(frame_gfx, sprite_gfx_mem, 32*32);
dmaCopy(frame_gfx, sprite_gfx_mem_sub, 32*32);
}
void Balloon::render()
{
int renx, reny;
renx = ((x - (16<<8)) >> 8); // using fixed point arithmatic
reny = ((y - (16<<8)) >> 8);
if(onBottomScreen)
oamSet( &oamMain, sprite_index, renx, reny,
0, paletteAlpha, size, format, sprite_gfx_mem,
rotationIndex, false, !active, false, false, false);
else
oamSet( &oamSub, sprite_index, renx, reny,
0, paletteAlpha, size, format, sprite_gfx_mem_sub,
rotationIndex, false, !active, false, false, false);
}
bool Balloon::isTouched(touchPosition touch)
{ // checking balloon pixel range with touch location
if(touch.px >= (x>>8)-9 && touch.px <=(x>>8)+10)
if(touch.py >= (y>>8)-16 && touch.py <=(y>>8)+8)
return true;
return false;
}
void Balloon::update()
{
y = (y - yvel); // set balloon Y location to new Y-velocity
if(onBottomScreen)
{
if(((y - (16<<8)) >> 8) < -32)
{
y = 210<<8;
setOnTop();
}
}
if(!isOnBottomScreen() && ((y - (16<<8)) >> 8) < -32)
switchActive();
}