gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Sprite Problem

#9496 - iuiz - Wed Aug 06, 2003 12:04 pm

Hi,

I got a Problem, by displaying an animated Sprite. My Sprite has 16*32 Pixels and 6 Frames (16*192Pixel). www.halof.com/player2.gif I converted it, using bmp2gba.exe, without Problems.

My Sprite Struct looks like this:
Code:
typedef struct
{
   u16 x;               //x and y position on screen
   u16 y;
   u16 spriteFrame[6];     //animation frame storage
   int direction;   //0=standing,1=up, 2=right, 3=down, 4=left
   int activeFrame;        //which frame is active
   u16 OAMSpriteNum;       //which sprite referring to
}Sprite;



And here I try to initalise my Sprite:
Code:
//Player Sprite ->
   player.x = 120;
   player.y = 100;
   player.activeFrame = 0;
   player.spriteFrame[0] = 0;
   player.spriteFrame[1] = 16;
   player.spriteFrame[2] = 32;
   player.spriteFrame[3] = 48;
   player.spriteFrame[4] = 64;
   player.spriteFrame[5] = 80;
   player.direction = 0;
   player.OAMSpriteNum = 0;

   sprites[0].attribute0 = COLOR_256 | WIDE | player.y;
   sprites[0].attribute1 = SIZE_32 | player.x;
   sprites[0].attribute2 = 0;

    for(loop = 0; loop < 3072; loop++)
   {
      OAMData[loop] = playerData[loop];
   }


I have no Problems, displaying player.spriteFrame[0] to [3], but [4] is just 0 again.

Can someone help me. Thx

#9497 - mtg101 - Wed Aug 06, 2003 1:36 pm

I'm not sure if this is related, but shouldn't that last for loop be looping to (3072 / 2) not (3072), as you're dealing with 16bit OAMData/playerData?
_________________
---
Speaker for the Dead

#9499 - iuiz - Wed Aug 06, 2003 2:41 pm

Ups, you are right. Normaly I user 1536, but as i spend hours in finding the bug i tryed to doubbel this value, so that there is 3072 at this moment. But 3072/2 doesnt help. The Sprite isnt displayed correct.

#9500 - iuiz - Wed Aug 06, 2003 2:55 pm

Ok, I found a way to display the Sprite correctly. Somehow it has some Elements of dynamic Memory management, but I dont know if it doesnt takes to much CPU Power on Hardware, because I dont own a ez-f device, yet.

Code:
//Main Loop:
   while(1) {
      GetInput();

      // Move the Main Charakter ->
      if(player.direction==1 && gSprite.actualSprite1!=0) {
         InitializeSprites();
         createSpritePlayerUp();
      }
      
      if(player.direction==3 && gSprite.actualSprite1!=3) {
         InitializeSprites();
         createSpritePlayerDown();
      }
      
      if(player.direction!=0)
         MoveSprite(&sprites[0], player.x, player.y);
      
      player.direction=0;
      // <- Move Main Charakter   
      
      
      animation++;
      if(animation>9)   //Change Movement Animation Speed here
         animation=0;


Code:
void createSpritePlayerUp() {
   u16 loop=0;

   player.activeFrame = 0;
   player.loopDirectionA = 0;
   player.loopDirectionB = 0;
   player.OAMSpriteNum = 0;
   player.activeFrame = 0;
   player.spriteFrame[0] = 0;
   player.spriteFrame[1] = 16;
   player.spriteFrame[2] = 32;
   
   sprites[0].attribute0 = COLOR_256 | WIDE | player.y;
   sprites[0].attribute1 = SIZE_32 | player.x;
   sprites[0].attribute2 = 0;

   //Player Sprite ->

    for(loop = 0; loop < 1534; loop++)
   {
      OAMData[loop] = playerData1[loop];
   }

   gSprite.actualSprite1=0;
   gSprite.actualSprite2=1;
   gSprite.actualSprite3=2;
   //<- Player Sprite
}

void createSpritePlayerDown() {
   u16 loop=0;

   player.activeFrame = 0;
   player.loopDirectionA = 0;
   player.loopDirectionB = 0;
   player.OAMSpriteNum = 0;
   player.activeFrame = 0;
   player.spriteFrame[0] = 0;
   player.spriteFrame[1] = 16;
   player.spriteFrame[2] = 32;

   sprites[0].attribute0 = COLOR_256 | WIDE | player.y;
   sprites[0].attribute1 = SIZE_32 | player.x;
   sprites[0].attribute2 = 0;

    for(loop = 0; loop < 1534; loop++)
   {
      OAMData[loop] = playerData2[loop];
   }

   gSprite.actualSprite1=3;
   gSprite.actualSprite2=4;
   gSprite.actualSprite3=5;
   //<- Player Sprite
}


Code:
void movementAnimation()
{
   u16 loop;

   if(player.activeFrame>2)
      player.activeFrame=0;

   if(animation==0) {
      if(player.loopDirectionA==0)
         player.activeFrame++;
      if(player.loopDirectionA==1)
         player.activeFrame--;
      if(player.activeFrame == 0)
         player.loopDirectionA=0;
      if(player.activeFrame == 2)
         player.loopDirectionA=1;
   }

   sprites[player.OAMSpriteNum].attribute2 = player.spriteFrame[player.activeFrame];
}


This means, that everytime the walking Direction changes another Sprite will be load into Memory. "if(animation>9)" means, that only every 9th Frame the Sprite Frame will change.


Comments please ;). Remember please, that is it alywase my first Programm on the GBa. It is "fast coded code", I plan to optimize it as good, as I can.

Here is the .gba. It works quite good on an Emu. But the Header isn't fixed, if you plan to run it on Hardware.
www.halof.com/rpgV2.zip

#9790 - Chross - Mon Aug 18, 2003 7:43 am

Now I realize that this topic is somewhat old now, but I just recently had this problem and my friend helped me figure it out. It may not be your code that was the problem but bmp2sprite. I had used that too and it seemed to repeat the sprite data in the header file. When I used pcx2sprite (by dovoto) it worked out fine.

Chross out.

#9795 - iuiz - Mon Aug 18, 2003 11:58 am

lol,

I had similar Problems with pcx2sprite, thats why I am using bmp2sprite now.