Jump to content
  • Advertisement
Sign in to follow this  
knarjons

sdl , flickering bmp

This topic is 4904 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. I have done a game, PONG, two paddles and a ball. One of the first games i came in contact with as a child. Im new to sdl and there is a problem when the ball gets close to the paddle, the paddle start to flicker and it doesnt stop until the ball has bounced away a bit from the paddle. the code:
//******************INCLUDES*****************************
#include <SDL.h>

#include <iostream>
using namespace std;

#include "font.h"


//*******************STRUKTURER**************************

struct sprite //håller info för rörliga bilder
{
	int x; // innehåller x-koord för sprite
	int y; //innehåller y-koord för sprite
	int xvel; //anger hur många pixels bild flyttar i x-led
	int yvel; //anger hur många pixels bild flyttar i y-led
	int width; // bredd på sprite
	int height; //höjd på sprite
};


//******************GLOBALER*****************************
SDLFont *font1;        // 2 fonts
SDLFont *font2;

int p1score=0, p2score=0;


//En SDL_Surface per bild
SDL_Surface *screen, *backg, *Ball, *pl1paddle, *pl2paddle; 


//Varje bilds info frå struct sprite
sprite ball, paddle1, paddle2;

//*******************Funktioner***************************

//Ladda in en bild o ändra till format som SDL använder
SDL_Surface * ImageLoad(char *file)
{
	SDL_Surface *temp1, *temp2;
	temp1=SDL_LoadBMP(file);
	temp2=SDL_DisplayFormat(temp1);
	SDL_FreeSurface(temp1);
	return temp2;
}


//Visa en bild
void DrawIMG(SDL_Surface *img, int x, int y)
{
	SDL_Rect dest; //Definierar en rektangulär yta
	dest.x = x;
	dest.y = y;
	SDL_BlitSurface(img, NULL, screen, &dest);
}


//Visa en bit av en bild, för att inte ska bli spår när vi flyttar
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);
}


//Visar en bild o tar bort det gamla som inte ska visas
void draw(SDL_Surface *surf, int x, int y, int width, int height)
{
	DrawIMG(backg, x-20, y-20, width+80, height+80, x-20, y-20);
	DrawIMG(surf, x, y);
	
	SDL_Flip(screen); // Från minnet till skärmen
}


//Visa ställning
void DrawScore(int pl1score, int pl2score)
{
	drawString(screen, font2,30, 20, "SCORE:  %d", pl1score);
	drawString(screen, font2,620, 20, "SCORE:  %d", pl2score);
	
}

// Visa allt som ska visas
void DrawAll()
{
	
	draw(Ball, ball.x, ball.y, ball.width, ball.height);
	draw(pl1paddle, paddle1.x, paddle1.y, paddle1.width, paddle1.height);
	draw(pl2paddle, paddle2.x, paddle2.y, paddle2.width, paddle2.height);
	DrawScore(p1score, p2score);
}

//Sätt upp alla startvärden
void restart()
{
	DrawIMG(backg, 0, 0);
	ball.x=395;
	ball.y=295;
	ball.yvel=3; 
	ball.xvel=10;
	ball.width=10;
	ball.height=10;

	paddle1.x=40;
	paddle1.y=260;
	paddle1.xvel=0;
	paddle1.yvel=0;
	paddle1.width=10;
	paddle1.height=80;

	paddle2.x=760;
	paddle2.y=260;
	paddle2.xvel=0;
	paddle2.yvel=0;
	paddle2.width=10;
	paddle2.height=80;
}

void newgame()
{
	p1score=0;
	p2score=0;

	restart();
}

//Kolla om kollision, utför i såfall lämlig åtgärd;
void checkforcollision()
{
	//Boll och vägg (eller tak golv)
	if(ball.y<=0) // taket
	{
		ball.yvel=-ball.yvel; // ändra riktning på bollen
	}
	if(ball.y+ball.height>=600) //golvet
	{
		ball.yvel=-ball.yvel; // ändra riktning
	}

	//spelare 1 o vägg (tak golv)
	if(paddle1.y<=0)
	{
		paddle1.y=0;
	}
	if(paddle1.y>=paddle1.height+600)
	{
		paddle1.y=600-paddle1.height;
	}

	//spelare 2 o vägg
	if(paddle2.y<=0)
	{
		paddle2.y=0;
	}
	if(paddle2.y>=paddle2.height+600)
	{
		paddle2.y=600-paddle2.height;
	}

	//boll o spelare 1
	if(ball.x<=paddle1.x+paddle1.width &&ball.y<=paddle1.y+paddle1.height &&ball.y>=paddle1.y)
	{
		ball.xvel=-ball.xvel;//byt rikting x-led
		ball.xvel++; //öka hastighet
		ball.yvel++;
	}

	//boll o spelare 2
	if(ball.x+ball.width>=paddle2.x && ball.y>= paddle2.y&&ball.y<=paddle2.y+paddle2.height)
	{
		ball.xvel=-ball.xvel;//byt rikting x-led
		ball.xvel--; //öka hastighet
		ball.yvel--;
	}


	//Kolla om spelare 1 vinner
	if(ball.x>=800-ball.width)
	{
		p1score++;
		if(p1score==10)
		{
			int i=0;
			while(i!=500)
			{
				drawString(screen, font2,350, 220, "Spelare 1 VANN");
				SDL_Flip(screen);
				i++;
			}
			newgame();
		}
		SDL_Delay(500);
		restart();
	}

	//Kolla om spelare 2 vinner
	if(ball.x<=0)
	{
		p2score++;
		if(p2score==10)
		{
			int i=0;
			while(i!=500)
			{
				drawString(screen, font2,350, 220, "Spelare 2 VANN");
				SDL_Flip(screen);
				i++;
			}
			newgame();
		}
		SDL_Delay(500);
		restart();
	}
}

//flytta bollen
void updateball()
{
	ball.x+=ball.xvel;
	ball.y+=ball.yvel;
}



//************************MAIN*******************************

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

	//Standard initiering sdl 
	if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO)<0)
	{
		exit(1);
	}
	atexit(SDL_Quit);

	screen=SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE|SDL_HWPALETTE);
	if(screen==NULL)
	{
		exit(1);
	}

	font1=initFont("data/font1");
	font2=initFont("data/font2");

	//Variabler
	backg=ImageLoad("bakgrund.bmp");
	Ball=ImageLoad("boll.bmp");
	pl1paddle=ImageLoad("paddel.bmp");
	pl2paddle=ImageLoad("paddel.bmp");

	ball.x=395;
	ball.y=295;
	ball.xvel=10;
	ball.yvel=3;
	ball.width=10;
	ball.height=10;

	paddle1.x=40;
	paddle1.y=260;
	paddle1.xvel=0;
	paddle1.yvel=0;
	paddle1.width=10;
	paddle1.height=80;

	paddle2.x=760;
	paddle2.y=260;
	paddle2.xvel=0;
	paddle2.yvel=0;
	paddle2.width=10;
	paddle2.height=80;

SDL_WM_SetCaption("Rickes bollspel","Rickes bollspel");
SDL_ShowCursor(0);


//*****************SPEL-LOOP***************************
DrawIMG(backg, 0, 0);
while(1)
{
	DrawAll();
	updateball();
	checkforcollision();

	SDL_Event event;
	Uint8 *keys;

	while(SDL_PollEvent(&event))
	{
		if(event.type==SDL_QUIT)
		{
			return 0;
		}

		if(event.type == SDL_KEYDOWN)
		{
			if(event.key.keysym.sym==SDLK_ESCAPE)
			{
				return 0;
			}
		}
	}

	keys=SDL_GetKeyState(NULL);
	if(keys[SDLK_UP])
	{
		paddle2.y -=6;
	}
	if(keys[SDLK_DOWN])
	{
		paddle2.y +=6;
	}

	if(keys[SDLK_a])
	{
		paddle1.y -=6;
	}

	if(keys[SDLK_z])
	{
		paddle1.y +=6;
	}
}
return 0;
}

Share this post


Link to post
Share on other sites
Advertisement
One thing I would stringly suggest - take the SDL_Flip(screen) out of the Draw() function and put it at the end of the DrawAll() function. You don't want to flip the screen every time you draw an object.

Share this post


Link to post
Share on other sites
what a different that made, i will have to slow down the speed now. The flickering stopped also. But another thing came up, when the ball are close to the paddle it dissapears for a little moment and shows again when it has bounced and are going away from the paddle, The ball is invisible when it bounce.

Share this post


Link to post
Share on other sites
maybe you could try to change in void DrawAll() so that you draw you ball last, and not the paddles. And maybe you should mask your imagaes. Svensk?

/Whizz


Share this post


Link to post
Share on other sites
well, now the paddle dissaperad instead, i dont really know what you meen by mask? Yes Swedish, sorry for my comments,

Share this post


Link to post
Share on other sites
Quote:
Original post by Dave Hunt
One thing I would stringly suggest - take the SDL_Flip(screen) out of the Draw() function and put it at the end of the DrawAll() function. You don't want to flip the screen every time you draw an object.


Seconded, you only want to flip the screen buffers when you've finished drawing everything for that particular frame, doing a buffer flip only once will also improve your framerate if SDL is tied to refresh rate for updating the screen.

Share this post


Link to post
Share on other sites
I think

void draw(SDL_Surface *surf, int x, int y, int width, int height)
{
DrawIMG(backg, x-20, y-20, width+80, height+80, x-20, y-20);
DrawIMG(surf, x, y);

SDL_Flip(screen); // Från minnet till skärmen
}


this function is supposed to re-draw the part of the background "damaged" by the sprite, then draw the sprite. The problem is, you draw the ball, then clear an area around the paddle before drawing the paddle. If the ball is in the space around the paddle that gets cleared, it will seem to disappear as it gets close to the paddle because it is getting drawn over.

To avoid this, you can clear all the sprites at once at their current location (ie. re-draw the piece of background they cover), then update all the sprites at once, then draw them all at once at their new location.

I suck at explaining things, so I hope that was OK [wink]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!