Jump to content
  • Advertisement
Sign in to follow this  
sheep19

[SDL] drawing and undrawing a rectangle

This topic is 3542 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

I created my own Rect class, which can draw itself. so I have these two functions: void draw(); void undraw();
void Rect::draw()
{
	SDL_FillRect(SDL_GetVideoSurface(), &getSDL_Rect(), color);
	drawn = true;
}


I think it's ok until now, but when I want to undraw it, I need to know the background I'm using in the game. so in the constructor I pass the address of the background and assign it to another background variable that I use to undraw the rectangle. Edit: maybe update the screen everytime something changes?
//main loop
bool quit = false;
	while(!quit)
	{
		while( SDL_PollEvent( &event ) )
		{
			//If the user has Xed out the window
			if(event.type == SDL_QUIT)
				quit = true;

			if(keystates[SDLK_ESCAPE])
				quit = true;
			
		}
		
		Rect a(100, 100, 100, 100,);
		a.draw();
		applySurface(0,0, background, screen);
		a.x += 300;
		a.draw();
		
		SDL_Flip(screen);
	}

void Rect::undraw()
{
	SDL_Rect offset;
	offset.x = 0;
	offset.y = 0;

	SDL_BlitSurface(background, 0, SDL_GetVideoSurface(), &offset);
	drawn = false;
}


I don't like the thing that I need to know the background. What if I delete it somewhere else? Rect will get an address that has nothing and it will crash the program. What is a better way to do this?

Share this post


Link to post
Share on other sites
Advertisement
Generally, every frame you have to draw everything.

This means that rather than having an undraw for your rect, you will need clear you framebuffer, draw the background and then draw your rect (along with anything else you want drawn).

Share this post


Link to post
Share on other sites
Undraw's perpose is to make the image "invisible". I guess I should rename the function.

This works.

bool quit = false;
while(!quit)
{
while( SDL_PollEvent( &event ) )
{
//If the user has Xed out the window
if(event.type == SDL_QUIT)
quit = true;
if(keystates[SDLK_ESCAPE])
quit = true;
if(keystates[SDLK_LEFT])
{
if(player.x >= 0)
player.move(-RECT_STEP);
}
if(keystates[SDLK_RIGHT])
{
if(player.x + player.Width() <= SCREEN_WIDTH)
player.move(RECT_STEP);
}

applySurface(0, 0, background, screen);
}

player.draw();
computer.draw();

SDL_Flip(screen);
}

Share this post


Link to post
Share on other sites
Why don't you just have a render queue? Clear the entire screen every frame. Things are placed into the queue based on position(background is always drawn first). The rect will draw itself every frame as it should in most applications. Simply pop the rect from the queue when you dont want it to be drawn anymore and you wont have to worry about pointers to the background image etc...it will all handle itself.

Share this post


Link to post
Share on other sites
There are two approaches here... It sounds like you want to do it the dirty way... That is, using "Dirty rects" ;). The other way is what the others are trying to influence you toward. That's the easy way.

The easy way:
Draw everything from the background up and update the entire screen, every frame:
while(!done)
{
while(SDL_PollEvent(&event))
{
// Handle events
}

// Update everything
updateSprites();

// Draw everything
drawBG(screen);
drawSprites(screen);
drawFG(screen);

// Update the screen
SDL_Flip(screen);
// Regulate frame rate here somehow
}


The dirty way will usually run a little faster. In this method (the simple dirty rect method), you only update the screen in areas that have changed. That means you should keep a list of those dirty rects and pass those to SDL_UpdateRects(). It's a little more complicated, and there are other ways to do it as well. Luckily, I've put the basic functionality into Sprig, a graphics lib for SDL:
http://pubpages.unh.edu/~jmb97/SPriG.html

Information for using the dirty rect system is in the documentation, and there's a demo specifically for using that system. You just tell Sprig whenever you draw in a rect, then after Sprig combines the dirty rects and updates the screen, you can get the final rects back so you can redraw the background image again. It works out very nicely :)

Jonny D

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!