problem with sprite.

Started by
6 comments, last by coderx04 19 years, 4 months ago

void DrawScene()
{

  sun.clearBG();
  Swords.clearBG();

  sun.updateBG();
  Swords.updateBG();

  sun.draw();
  Swords.draw();

  SDL_Flip(screen);
}


SDL_Surface * ImageLoad(char *file)
{
  SDL_Surface *temp1, *temp2;
  temp1 = SDL_LoadBMP(file);
  temp2 = SDL_DisplayFormat(temp1);
  SDL_FreeSurface(temp1);
  return temp2;
}

int InitImages()
{
  back = ImageLoad("back.bmp");
  image = ImageLoad("map1.bmp");
  return 0;
}
//---------------------------------------------

void DrawBG(SDL_Surface *bg)
{
    //Slock(screen);
	SDL_FillRect(screen, NULL, 0);

  DrawIMG(bg, 0, 0);	
}

//---------------------------------------------


int main(int argc, char *argv[])
{
   	Uint8* keys;

	my_timer_id = SDL_AddTimer((33/10)*10, my_callbackfunc, my_callback_param);

	if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER) <0 )
	{
		printf("Unable to init SDL: %s\n", SDL_GetError());
		return 1;
	}

	atexit(SDL_Quit);


    if(Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 2048) < 0)
	{
		printf("Warning: Couldn't set 44100 Hz 16-bit audio\n		- Reason: %s\n", SDL_GetError());
	}




 screen=SDL_SetVideoMode(SCREENWIDTH,SCREENHEIGHT,32,SDL_SWSURFACE|SDL_FULLSCREEN|SDL_HWPALETTE);
  if ( screen == NULL )
  {
    printf("Unable to set 640x480 video: %s\n", SDL_GetError());
    exit(1);
  }
  
	//load the music
    music = Mix_LoadMUS("data/sound/(sblu)moon6.xm");

	

	//play the music

	if(!Mix_PlayingMusic())
    {
      // then start playing it.
      Mix_PlayMusic(music, 0);
    }
  
  Swordsbase.init("data/testC/down");
  sunbase.init("data/sun");

  sun.init(&sunbase,screen);
  sun.set(480,50);
  sun.setSpeed(1);

  Swords.init(&Swordsbase,screen);
  Swords.set(150,300);
  Swords.setSpeed(2);


  SDL_ShowCursor(0);

  font = initFont("data/font");

  InitImages();
  //DrawBG(back);

  

  while (game_state!=GAME_EXIT)
  {
    SDL_Event event;

    while ( SDL_PollEvent(&event) )
    {
      if ( event.type == SDL_QUIT )  
		  { game_state=GAME_EXIT;}

      if ( event.type == SDL_KEYDOWN )
      {
        if ( event.key.keysym.sym == SDLK_ESCAPE ) { game_state=GAME_EXIT; }
      }
    }

    keys = SDL_GetKeyState(NULL);

    if ( keys[SDLK_UP] ) { Swords.yadd(-1); }
    if ( keys[SDLK_DOWN] ) { Swords.yadd(1); }
    if ( keys[SDLK_LEFT] ) { Swords.xadd(-1); }
    if ( keys[SDLK_RIGHT] ) { Swords.xadd(1); }
	if ( keys[SDLK_s] )
		{
            if(game_state!=GAME_RUN||game_state!=GAME_STARTING)
			{
				SDL_FillRect(screen,0,0);

				sun.clearBG();
				Swords.clearBG();

				game_state = GAME_STARTING;
				
			}
			//SDL_FillRect(screen,0,0);
			//DrawIMG(image, 0, 0);
			//SDL_Flip(screen);
		}
	if(game_state == GAME_INIT)
	DrawBG(back);
	if(game_state == GAME_STARTING)
	{

	    SDL_FillRect(screen, NULL, 0);
		DrawBG(image);
		//SDL_Flip(screen);
		//game_state++;
	}


    DrawScene();

  }

  return 0;
}

I have problem, when the character move down, it have some red colour on the screen.. And when I change the background image, it still have a square colour from the previous background image... Ill show you the picture how to upload a picture in here?
Advertisement






The one with yellow circle is what im complain about..
The green border is there because Antialasing doesn't work so hot with color keying.

Another thing I noticed is that you are doing the dirty rectange method with page flipping. you need to change that too. SDL is slow, but you can atleast do better than dirty rectangle.
HxRender | Cornerstone SDL TutorialsCurrently picking on: Hedos, Programmer One
Soory I dont understand what you mean by dirty rectangle method?

Is it because I flip the whole screen? I have to flip every rectangle sprite or what?

Please help ...

And what is Antiliasing ? how to solve this? please..
From the screen shots and code provided I can't really tell what the problem is being caused by. It may be because of not using dirty rects correctly but I am not sure. At any rate, I would suggest clearing the background every frame and redrawing everything every frame and see if the same problem persists.

After a second look, the problem seems to be in the obj.clearBG() and obj.updateBG() functions. Looks like the wrong part of the background is being drawn or a bad rectangle is being passed somewhere.

Hope it helped.
Evillive2
void CSprite::clearBG(){  if(mDrawn==1)  {    SDL_Rect dest;    dest.x = mOldX;    dest.y = mOldY;    dest.w = mSpriteBase->mW;    dest.h = mSpriteBase->mH;    SDL_BlitSurface(mBackreplacement, NULL, mScreen, &dest);  }}void CSprite::updateBG(){  SDL_Rect srcrect;  srcrect.w = mSpriteBase->mW;  srcrect.h = mSpriteBase->mH;  srcrect.x = mX;  srcrect.y = mY;  mOldX=mX;mOldY=mY;  SDL_BlitSurface(mScreen, &srcrect, mBackreplacement, NULL);}


Where is wrong with that?

And actually Im not quite understand how to
- Erase all the Image in the screen?
- when to use the SDL_FLIP?
- Whats wrong with the transparant image?
The method it appears you are using to display your sprites is called the dirty rectangle method. This is where you only update the parts of the screen that have changed each frame instead of re-drawing the whole scene over again. The performance gains you might get from doing this right now are probably pretty small compared to the hassle it is causing you. I can't speak for everyone but most tutorials and articles I have read start out using the "redraw everything every frame" method so that people learn the concept of draw/render order to show perspective. In your case the DrawScene function would look similar to this:
void DrawScene(){    // this fills the backbuffer with black    SDL_FillRect( screen, 0, 0 );    // draw the background    DrawBG( back );    // draw the sprites    sun.draw();    sword.draw();    // flip the buffers    SDL_Flip( screen );}


the SDL_FillRect( screen, 0,0 ) should only be called once at the beginning of DrawScene. You don't want to do it anywhere else because it will just draw over everything so that it has to be redrawn again.

While using SDL you will notice that when you use SDL_BlitSurface to draw to the screen that nothing actually gets drawn to the screen UNTIL SDL_UpdateRect or SDL_Flip is called. That is why we only call SDL_Flip once at the END of DrawScene. All of your drawing should take place between the SDL_FillRect and SDL_Flip calls. If you do any drawing outside that block it may not work right or not show up at all.

This may seem a little counter intuitive to redraw everything every frame but getting it working first is more important than optimising before you are ready.

As for the player sprite, it looks like it has a green aura around it. This might be because you resized the image in an image editing program like photoshop and it tried to anti-alias the picture (smooth the edges). The sprites you are using look like ones found on the net ripped from snes games or made for programs like RPG Maker. Most of these sprite sheets are in 8 bit palletized bitmaps. I have found that leaving it in 8 bit while resizing usually disables anti-aliasing (in paint shop and ms-paint anyway).

Hope it helped.
Evillive2
Thank you very much eville, its really help. Its working fine now. I will rate you *_*

This topic is closed to new replies.

Advertisement