"smearing" in game (but not for me)

Started by
6 comments, last by hop 18 years, 7 months ago
Hello, I recently THOUGHT I had finished my first game in C++ (a pong game) so I submitted it in the Your Annoucements forum, and then found out that the images were not being wiped off the background buffer for people who tried my game. This does not happen when I run the game myself, so I'm not sure what could be wrong. Here's the download of the game to try out yourselves: here And here's the full source (and I'm using DevCpp and "-lmingw32 -lSDLmain -lSDL" is linked under project options):
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>

SDL_Surface *back;
SDL_Surface *ball;
SDL_Surface *paddle1;
SDL_Surface *paddle2;
SDL_Surface *screen;
SDL_Surface *pong;
SDL_Surface *win;
SDL_Surface *lose;

int oney = 190, twoy = 190, ballx = 100, bally = 100;
int mx = 8, my = 2;
int menu = 0;

int InitImages()
{
   back = SDL_LoadBMP("art/back.bmp");
   ball = SDL_LoadBMP("art/ball.bmp");
   paddle1 = SDL_LoadBMP("art/paddle.bmp");
   paddle2 = SDL_LoadBMP("art/paddle.bmp");
   pong = SDL_LoadBMP("art/pong.bmp");
   win = SDL_LoadBMP("art/win.bmp");
   lose = SDL_LoadBMP("art/lose.bmp");
   return 0;
}

void DrawIMG(SDL_Surface *img, int x, int y)
{
  SDL_Rect dest;
  dest.x = x;
  dest.y = y;
  SDL_BlitSurface(img, NULL, screen, &dest);
}

void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2)
{
  SDL_Rect dest;
  dest.x = x;
  dest.y = y;
  SDL_Rect dest2;
  dest2.x = x2;
  dest2.y = y2;
  dest2.w = w;
  dest2.h = h;
  SDL_BlitSurface(img, &dest2, screen, &dest);
}

void DrawBG()
{
  DrawIMG(back, 0, 0);
}

void DrawIntro(SDL_Surface *screen)
{
  DrawIMG(pong, 175, 100);
  SDL_Flip(screen);
}

void DrawScene(SDL_Surface *screen)
{
  DrawIMG(back, ballx - 12, bally - 12, 54, 54, ballx - 12, bally - 12);
  DrawIMG(back, 10, oney - 7, 30, 114, 10, oney - 7);
  DrawIMG(back, 600, twoy - 7, 30, 114, 600, twoy - 7);
  DrawIMG(ball, ballx, bally);
  DrawIMG(paddle1, 10, oney);
  DrawIMG(paddle2, 600, twoy);
  SDL_Flip(screen);
}

void computeAI()
{
  if (twoy + 50 < bally + 15)
    twoy += 7;
  if (twoy + 50 > bally + 15)
    twoy -= 7;
}

void compute()
{
  ballx += mx;
  bally += my;

        if (ballx <= 40 && ballx > 10 && bally + 15 >= oney + 25 && bally + 15 <= oney + 75 && mx < 0)
          mx = mx * -1;
        if (ballx + 30 < 630 && ballx + 30 >= 600 && bally + 15 >= twoy + 25 && bally + 15 <= twoy + 75 && mx > 0)
          mx = mx * -1;
        if (ballx < 40 && ballx > 10 && bally + 15 > oney - 17 && bally + 15 < oney + 25 && mx < 0)
        {
          mx = mx * -1;
          my -= 1;
        }
        if (ballx < 40 && ballx > 10 && bally + 15 < oney + 117 && bally + 15 > oney + 75 && mx < 0)
        {
          mx = mx * -1;
          my += 1;
        }
        if (ballx + 30 < 630 && ballx + 30 > 600 && bally + 15 > twoy - 17 && bally + 15 < twoy + 25 && mx > 0)
        {
          mx = mx * -1;
          my -= 1;
        }
        if (ballx + 30 < 630 && ballx + 30 > 600 && bally + 15 < twoy + 117 && bally + 15 > twoy + 75 && mx > 0)
        {
          mx = mx * -1;
          my += 1;
        }

        if (bally > 450 || bally < 0)
          my = my * -1;
}

void pwin(SDL_Surface *screen)
{
  DrawIMG(win, 175, 100);
  SDL_Flip(screen);
  SDL_Delay(2000);
}

void plose(SDL_Surface *screen)
{
  DrawIMG(lose, 175, 100);
  SDL_Flip(screen);
  SDL_Delay(2000);
}

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

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

  screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);
  if ( screen == NULL )
  {
    printf("Unable to set 640x480 video: %s\n", SDL_GetError());
    exit(1);
  }
  int introdone = 0;
  int gamedone = 0;
  int entgame = 0;
  InitImages();
  while(entgame == 0)
  {
  introdone = 0;
  gamedone = 0;
  oney = 190, twoy = 190, ballx = 100, bally = 100;
  mx = 8, my = 2;
  DrawBG();

  while(introdone == 0)
  {
    DrawIntro(screen);
    SDL_Event event;
    while ( SDL_PollEvent(&event) )
    {
      if ( event.type == SDL_QUIT )
      {
        introdone = 1;
        gamedone = 1;
        entgame = 1;
      }
      if ( event.type == SDL_KEYDOWN )
      {
        if ( event.key.keysym.sym == SDLK_ESCAPE )
        {
          introdone = 1;
          gamedone = 1;
          entgame = 1;
        }
      }
    }
    keys = SDL_GetKeyState(NULL);
    if ( keys[SDLK_UP] ) { gamedone = 0; introdone = 1; }
    if ( keys[SDLK_DOWN] ) { gamedone = 2; introdone = 1; }
  }
  DrawBG();

  while(gamedone == 0)
  {
    SDL_Event event;
    while ( SDL_PollEvent(&event) )
    {
      if ( event.type == SDL_QUIT )  {  gamedone = 1;  }

      if ( event.type == SDL_KEYDOWN )
      {
        if ( event.key.keysym.sym == SDLK_ESCAPE ) { gamedone = 1; }
      }
    }
    keys = SDL_GetKeyState(NULL);
    if ( keys[SDLK_UP] ) { oney -= 7; }
    if ( keys[SDLK_DOWN] ) { oney += 7; }
    computeAI();
    compute();
    DrawScene(screen);
    if (ballx < -10)
    {
      gamedone = 1;
      plose(screen);
    }
    if (ballx > 650)
    {
      gamedone = 1;
      pwin(screen);
    }
  }
  while(gamedone == 2)
  {
    SDL_Event event;
    while ( SDL_PollEvent(&event) )
    {
      if ( event.type == SDL_QUIT )  {  gamedone = 1;  }

      if ( event.type == SDL_KEYDOWN )
      {
        if ( event.key.keysym.sym == SDLK_ESCAPE ) { gamedone = 1; }
      }
    }
    keys = SDL_GetKeyState(NULL);
    if ( keys[SDLK_w] ) { oney -= 7; }
    if ( keys[SDLK_s] ) { oney += 7; }
    if ( keys[SDLK_UP] ) { twoy -= 7; }
    if ( keys[SDLK_DOWN] ) { twoy += 7; }
    compute();
    DrawScene(screen);
    if (ballx < -50 || ballx > 690)
      gamedone = 1;
  }
  }

  return 0;
}
Thanks in advance!
Advertisement
well, if it works for you and not others, make surey our shipping the proper version of the dll's.
| Member of UBAAG (Unban aftermath Association of Gamedev)
Excuse me if I'm wrong, but might that be caused by you not clearing the screen each frame? Try adding this to the top of your render function:

The following code will clear the screen to black.

SDL_Rect bg;bg.x = 0;bg.y = 0;bg.w = 640;bg.h = 480;SDL_FillRect(screen, &bg, SDL_MapRGB(screen->format, 0, 0, 0));
my siteGenius is 1% inspiration and 99% perspiration
I don't think that that is the problem because here is the code that is supposed to refresh the background behind the objects:

This is the function used:
void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2){  SDL_Rect dest;  dest.x = x;  dest.y = y;  SDL_Rect dest2;  dest2.x = x2;  dest2.y = y2;  dest2.w = w;  dest2.h = h;  SDL_BlitSurface(img, &dest2, screen, &dest);}


This is where the scene is drawn:
void DrawScene(SDL_Surface *screen){  DrawIMG(back, ballx - 12, bally - 12, 54, 54, ballx - 12, bally - 12);  // this makes the background behind the ball  DrawIMG(back, 10, oney - 7, 30, 114, 10, oney - 7);  // this makes the background behind the first paddle  DrawIMG(back, 600, twoy - 7, 30, 114, 600, twoy - 7);  // this makes the background behind the second paddle  DrawIMG(ball, ballx, bally);  DrawIMG(paddle1, 10, oney);  DrawIMG(paddle2, 600, twoy);  SDL_Flip(screen);}



Also I made sure the dll in the folder worked and reuploaded it. In the case of a dll that needed to be accessed was in the folder of the exe and in the system folder folder, which would be accessed first? The only explaination I can think of is that people have old SDL.dll's in thier system folder and that is messing it up. Unless I'm missing something else.
Well, maybe you don't have a graphics accelerated card, so you don't get the effect of smearing. I reproduced this by turning all of my acceleration off. This made the game run 100x faster for some reason.

I agree with silverphyre673, you need to clear the back screen with your original back. Maybe in your DrawScene() add DrawBG() to it or something.
Quote:Original post by silverphyre673
Excuse me if I'm wrong, but might that be caused by you not clearing the screen each frame? Try adding this to the top of your render function:

The following code will clear the screen to black.

*** Source Snippet Removed ***


When you are just clearing the entire screen to black, you can simply use: SDL_FillRect(screen, 0, 0);
Quote:Original post by Drew_Benton
Quote:Original post by silverphyre673
Excuse me if I'm wrong, but might that be caused by you not clearing the screen each frame? Try adding this to the top of your render function:

The following code will clear the screen to black.

*** Source Snippet Removed ***


When you are just clearing the entire screen to black, you can simply use: SDL_FillRect(screen, 0, 0);


Oh yeah =) Forgot about that. Anyways, yeah, just try it, and if it doesn't work, let us know.

EDIT: Interesting. I get the smearing/speeding up problem when I compile it myself, but not when I use your version. The smearing problem goes away when I added SDL_FillRect(screen, 0, 0) to the beginning of the rendering function:

void DrawScene(SDL_Surface *screen){  SDL_FillRect(screen, 0, 0); //Changed!  Clears the screen to black each frame.  DrawIMG(back, ballx - 12, bally - 12, 54, 54, ballx - 12, bally - 12);  DrawIMG(back, 10, oney - 7, 30, 114, 10, oney - 7);  DrawIMG(back, 600, twoy - 7, 30, 114, 600, twoy - 7);  DrawIMG(ball, ballx, bally);  DrawIMG(paddle1, 10, oney);  DrawIMG(paddle2, 600, twoy);  SDL_Flip(screen);}


EDIT 2: You also need to correct the timing problem. This code solved it in a simple manner, although you would need something a bit more elegant for a bigger game =)

    //These next long declarations are globally declared:    long t_s = -1, t_c = -1;    /*in function main():*/    keys = SDL_GetKeyState(NULL);    t_c = SDL_GetTicks();    if (t_s == -1 || t_c - t_s > 10)    {        t_s = SDL_GetTicks();        t_c = SDL_GetTicks();        /*this was originally in the code in the main() function.*/        if ( keys[SDLK_UP] ) { oney -= 7; }        if ( keys[SDLK_DOWN] ) { oney += 7; }        computeAI();        compute();        /*********************************************************/    }


The game runs fine for me now =)

[Edited by - silverphyre673 on September 4, 2005 11:25:01 AM]
my siteGenius is 1% inspiration and 99% perspiration
Wow, thanks a lot guys, especally silver for the timing thing I had no idea how to do that. I've made all the changes and reuploaded it under the same name so you can click the link in my first post to try it out. It still looks exactly the same for me, so I would like someone else to try it out to make sure I did everything right.

Thanks everyone!

This topic is closed to new replies.

Advertisement