Looking to generate random sprite colours
Looking to generate random sprite colours
Hello, i am currently playing around with the capabilities of myself using devkitpro + libnds to program some games later on for the nds. Currently i have a nice little sprite demo running that simply floats white balloons from a bottom main screen up to a top sub screen. What i am trying to do now, is to somehow generate a random colour for the balloon to use instead of its white main colour. I have played around with some ideas in my head and i would like to know the communities opinion on the subject.
1. Have a set standard of colour palettes to choose from.
I can only think of including multiple image files into the program though, and thus loading several palettes into memory, and then choosing one for each balloon done. Though this seems like a vast waste of memory just for getting different colours.
2. Somehow bend the specific sprite with a colour at the time of rendering
I am trying to look more into this idea, but the only references i can find is alpha blending the sprite with the background. I hope that there is a way to try and blend the sprite with a specific colour, but even then it would blend the whole image, and not the specific colour. Would there be a way to actually change the specific palette colour index of a sprite using its palette bits in the 3 attribute index? This way i could try and replace the white colour reference with a randomly generated one. Unfortunately by the looks of it, it would effect all of the sprites using the same palette as the palette is only a reference to that in the memory.
1. Have a set standard of colour palettes to choose from.
I can only think of including multiple image files into the program though, and thus loading several palettes into memory, and then choosing one for each balloon done. Though this seems like a vast waste of memory just for getting different colours.
2. Somehow bend the specific sprite with a colour at the time of rendering
I am trying to look more into this idea, but the only references i can find is alpha blending the sprite with the background. I hope that there is a way to try and blend the sprite with a specific colour, but even then it would blend the whole image, and not the specific colour. Would there be a way to actually change the specific palette colour index of a sprite using its palette bits in the 3 attribute index? This way i could try and replace the white colour reference with a randomly generated one. Unfortunately by the looks of it, it would effect all of the sprites using the same palette as the palette is only a reference to that in the memory.
Re: Looking to generate random sprite colours
You could use 16 bit (Bmp) sprites. Not seeing the graphics you are using (and not knowing if you're using solid colors for how easy it might be) the graphics come from direct color values instead of palette index values. It wouldn't be too hard to generate a random number and populate the graphics in code.
I suppose the usual thing would be to just switch palettes...
I suppose the usual thing would be to just switch palettes...
Re: Looking to generate random sprite colours
That is the image i am using. It is a simple 3 colour palette with no shading. I am just trying to generate a random colour to replace the white so that multiple instances of the image would display different colours
Re: Looking to generate random sprite colours
The easiest way to change the colour of the sprite is to use the sprite in 16 colour mode, then you have access to 16 palettes. Set up the 16 palettes with different colour 2 (the white colour, assuming colour 0 is the green one, and black is colour 1). Then when you add your sprite to the screen, you can set a different palette (0-15).
You can also do this with 256 colour sprites, but in this case you will be using extended palettes.
I'm not sure that BMP sprites would be the best for you unless you only have 1 sprite on the screen at a time as changing the colour in that image using coding would require a lot of work (double loop + conditional update) it just might kill your frame rate, espially if you have 2 sprites as you would need to do the update in a hblank interrupt - but then you get the problem of two sprites overlapping their y range*. As a 32x32 16 colour sprite eats up a load of memory and taking into account the limit on the number of tiles you can have for a spite, I would sugest not using BMP sprites, unless you really need to.
*By this I mean if sprite 0 (white) is at 32-64, and sprite 1 (red) is at 48-80 then the lower half of sprite 0 will be red if you changed the colour of the sprite part way though the rendering loop.
You can also do this with 256 colour sprites, but in this case you will be using extended palettes.
I'm not sure that BMP sprites would be the best for you unless you only have 1 sprite on the screen at a time as changing the colour in that image using coding would require a lot of work (double loop + conditional update) it just might kill your frame rate, espially if you have 2 sprites as you would need to do the update in a hblank interrupt - but then you get the problem of two sprites overlapping their y range*. As a 32x32 16 colour sprite eats up a load of memory and taking into account the limit on the number of tiles you can have for a spite, I would sugest not using BMP sprites, unless you really need to.
*By this I mean if sprite 0 (white) is at 32-64, and sprite 1 (red) is at 48-80 then the lower half of sprite 0 will be red if you changed the colour of the sprite part way though the rendering loop.
Re: Looking to generate random sprite colours
Here's a thought... You could pre-create balloons with as many colors as you like, allocate graphics for each one, load the gfx into memory and then when a balloon is created, randomize which gfx location the sprite will use. You could get away with quite a few different colored balloons that way and the code would be pretty quick and painless.
Re: Looking to generate random sprite colours
While i have been thinking about copying the palette and then modifying the white colour into a different one, i still do not like the memory consumption that this entails. I was more hoping of there being a method of something akin to the alpha blend, but where instead of taking two different sources, there would be one source and a blend of the colour that you would like to have, and all this at the time of rendering. Unfortunately, it doesnt seem like this is feasible nor possible without heavy sprite manipulation or even modifying the current toolchain.
Like i said earlier in this post, i will play around with modifying the palette and see what results this will give me.
Like i said earlier in this post, i will play around with modifying the palette and see what results this will give me.
Re: Looking to generate random sprite colours
Actually that feature is not available on the hardware - the alpha blend / colour change on the fly.hassifa wrote:While i have been thinking about copying the palette and then modifying the white colour into a different one, i still do not like the memory consumption that this entails. I was more hoping of there being a method of something akin to the alpha blend, but where instead of taking two different sources, there would be one source and a blend of the colour that you would like to have, and all this at the time of rendering. Unfortunately, it doesnt seem like this is feasible nor possible without heavy sprite manipulation or even modifying the current toolchain.
Like i said earlier in this post, i will play around with modifying the palette and see what results this will give me.
The only way to have one sprite use multiple colour overlays is to change the palette that that sprite uses, unless you do some fancy interupt coding. There is no memory overhead for using different palettes for 16 colour (4bit) sprites, there's a dedicated vram bank for the extended palettes of 256 colour (8bit) sprites, and well 16bit sprites just eat memory.
How are you saving your sprite in memory? 4bit, 8bit or 16bit? As I said, 4 bit gives you 16 palette entries that are basically free memory (free in the sence that the palette memory is pre-allocated), 8bit allows extended palettes at the cost of a VRAM bank, and 16 bit allows multiple colours in the sprite, but at the expense of sprite memory.
Re: Looking to generate random sprite colours
Just to try to keep you away from alpha blending a little more, you can not blend obj to obj, only obj to bg or bg to obj. From gbatek:
The OBJ Layer
Before special effects are applied, the display controller computes the OBJ priority ordering, and isolates the top-most OBJ pixel. In result, only the top-most OBJ pixel is recursed at the time when processing special effects. Ie. alpha blending and semi-transparency can be used for OBJ-to-BG or BG-to-OBJ , but not for OBJ-to-OBJ.
The OBJ Layer
Before special effects are applied, the display controller computes the OBJ priority ordering, and isolates the top-most OBJ pixel. In result, only the top-most OBJ pixel is recursed at the time when processing special effects. Ie. alpha blending and semi-transparency can be used for OBJ-to-BG or BG-to-OBJ , but not for OBJ-to-OBJ.
Re: Looking to generate random sprite colours
Right now for this sprite, i am using only 4bit colours. I am just testing out the correct way that i should allocate the sprites tiles and palette to memory, as well as the easiest way to actually display sprites. The tutorial that i was following was from http://ekid.nintendev.com/bouncy/index.php , but i believe that it is out-of-date, considering that it deal with manipulating the memory location of sprites to determine the display, instead of using the available methods in the updated libnds.StevenH wrote: How are you saving your sprite in memory? 4bit, 8bit or 16bit? As I said, 4 bit gives you 16 palette entries that are basically free memory (free in the sence that the palette memory is pre-allocated), 8bit allows extended palettes at the cost of a VRAM bank, and 16 bit allows multiple colours in the sprite, but at the expense of sprite memory.
I did manage to get a small working game out of that tutorial, that compromises of balloons rising up from the bottom screen to the top screen, and trying to pop them. Now i am just trying to re-write it using the new available methods.
Re: Looking to generate random sprite colours
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.
(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();
}
Who is online
Users browsing this forum: No registered users and 1 guest