Sign in to follow this  

sdl , flickering bmp

This topic is 4693 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
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
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
The RUG

Could you show me the code?? As I said, this is my first program using SDL. I have started with 2 tutorials to built this program, one for the game and one for the texts. And made them work together.

Share this post


Link to post
Share on other sites
Thats what I was thinking. I had a huge post, but the damn thing timed out and I assumed it hadn't worked. So I went out for a bit, and now I'm back, I see 5 blank posts [bawling] Theres no justice. I'll try and edit it into one of my old posts.

Edit: ARRRRRRGH *bangs head on keyboard*
this is the solution I came up with... but for some reason I can't post it. I've tried from 2 PCs. Hopefully this'll be good enough to solve your problem knarjons.

Share this post


Link to post
Share on other sites

This topic is 4693 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this