Clearing previously drawn pixels

Started by
5 comments, last by PnP Bios 19 years, 6 months ago
Hey guys, I'm new to this place, so Hi. I'm learning SDL. The first thing I'm doing is making a blood eninge. I ran into a problem though, the pixels I'm drawing for the blood explosion aren't going away. I know there is no update function, and I use UpdateRect for the whole screen too. But lets say that I draw a pixel somewhere. Next frame, when it goes somewhere else, it is still drawn at the privious place as well. This makes the blood never go away. Is there anything in here that is making the previous blood pixels remain?

#include "sdl.h"
#include <stdlib.h>
#include <time.h>
#include <memory.h>
#include <cmath>
#include <vector>

using namespace std;

#define RED 1
#define GREEN 2
#define BLUE 3


class Blood {
public:
    float x, y;
    float xvel, yvel;
    int life, color;

    //Blood *next;
};

vector<Blood*>bloods;

void CreateBlood(int x, int y, int angle, int intensity, int color);
void cleanup();
void cleanup2();
void UpdateBlood();
void Event();
void Input();
bool KeyDown(bool KeyFlag);
bool KeyHit(bool &KeyFlag);

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

SDL_Surface *DisplaySurface;
Blood *first_blood = NULL;
SDL_Event g_Event;

char *pixel_data;
//int* pixel_data;
int pixel_color;

int relative_angle;
int test_intensity = 5;
int test_angle = 0;
int max_bloodlife = 30;
float gravity = .4;

bool f_Up;
bool f_Down;
bool f_Left;
bool f_Right;
bool f_Space;
bool f_Escape; 

int main(int argc, char* argv[]) {
	bloods.clear();
    srand(time(NULL));

	if(SDL_Init(SDL_INIT_VIDEO) == -1) {
	    fprintf(stderr,"Could not initialize SDL!\n");
		exit(1);
	}
	else {
		fprintf(stdout,"SDL initialized properly!\n");
		atexit(SDL_Quit);
	}
	DisplaySurface = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0,SDL_ANYFORMAT);
	SDL_ShowCursor(SDL_DISABLE); 
	if(!DisplaySurface) {
		fprintf(stderr,"Could not set up display surface!\n");
		exit(1);
	}

	int debug = 0;
	while(1) {
        
        Event();
		if (f_Escape)
			break;
		
		//check if surface needs locking
		if(SDL_MUSTLOCK(DisplaySurface)) {
			if(SDL_LockSurface(DisplaySurface) == -1) {
				fprintf(stderr,"Could not lock display surface!\n");
				cleanup();
				exit(1);
			}
		}
     
        UpdateBlood();
	    //update the screen
		SDL_UpdateRect(DisplaySurface,0,0,0,0);

	    if(SDL_MUSTLOCK(DisplaySurface)) 
		    SDL_UnlockSurface(DisplaySurface);

		Input();
		if(test_angle > 360)
			test_angle -= 360;
		if(test_angle < 360)
			test_angle += 360; 
	}
	cleanup();
	fprintf(stdout,"Terminating normally.\n");
	return 0;
}

void Event() {
    //wait for an event
    if(SDL_PollEvent(&g_Event) == 0) {
	    //No event, so do stuff.
        if(g_Event.key.keysym.sym == SDLK_ESCAPE) {
            SDL_Event quit;
            quit.type = SDL_QUIT;
            SDL_PushEvent(&quit);
		}

        switch(g_Event.type) {
            case SDL_KEYDOWN:
                switch(g_Event.key.keysym.sym) {
                    case SDLK_UP:
                        f_Up = true;
                        break;
                    case SDLK_DOWN:
                        f_Down = true;
                        break;
                    case SDLK_LEFT:
                        f_Left = true;
                        break;
                    case SDLK_RIGHT:
                        f_Right = true;
                        break;
                    case SDLK_SPACE:
                        f_Space = true;
                        break;
                    case SDLK_ESCAPE:
                        f_Escape = true;
                        break;
                }
                break;

            case SDL_KEYUP:
                switch(g_Event.key.keysym.sym) {
                    case SDLK_UP:
                        f_Up = false;
                        break;
                    case SDLK_DOWN:
                        f_Down = false;
                        break;
                    case SDLK_LEFT:
                        f_Left = false;
                        break;
                    case SDLK_RIGHT:
                        f_Right = false;
                        break;
                    case SDLK_SPACE:
                        f_Space = false;
                        break;
                    case SDLK_ESCAPE:
                        f_Escape = false;
                        break;
                }
                break;

            default:
                break;
			    
		} 
	} 
	else {
	    //event occurred, check for quit
		if(g_Event.type == SDL_QUIT) {
			SDL_Event quit;
            quit.type = SDL_QUIT;
            SDL_PushEvent(&quit);
		}
	}
}

void Input() {
	if(KeyDown(f_Up))
        test_intensity++;
    if(KeyDown(f_Down))
        test_angle -= 4;
    if(KeyDown(f_Left))
        test_intensity--;
    if(KeyDown(f_Right))
        test_angle += 4;
	if(KeyDown(f_Space))
        CreateBlood(320,240,test_angle,test_intensity,3);
}

void CreateBlood(int x, int y, int angle, int intensity, int color) {

	Blood* blood;

    for(int i = 0; i<=intensity; i++) {

		blood = NULL;

		if (!(blood = new Blood)) {
			fprintf(stdout, "Out of memory :(\n");
			cleanup();
			exit(3);
		}

        blood->x = x + (rand()%(-600+300))/100.00;
        blood->y = y + (rand()%(-600+300))/100.00;
        blood->life = rand()%(-(intensity/12+1));
	    relative_angle = angle + rand()%110 - 55;
	    blood->xvel = cos(relative_angle) * (intensity/(rand()%14 + 10));
	    blood->yvel = sin(relative_angle) * (intensity/(rand()%14 + 10));
		blood->color = color;

		bloods.push_back(blood);

    }
}

void cleanup() {
	vector<Blood*>::iterator rmvme = bloods.begin();

	cleanup2();
	while (rmvme != bloods.end()) {
		delete *rmvme;
		rmvme++;
	}
	bloods.clear();
}

void cleanup2() {
	vector<Blood*>::iterator rmvme = bloods.begin();

	while (rmvme != bloods.end()) {
		if (*rmvme == NULL) {
			bloods.erase(rmvme);
			rmvme = bloods.begin();
			continue;
		}
		rmvme++;
	}
}
		

void UpdateBlood() {

	//Blood **blood_p = &first_blood;
	vector<Blood*>::iterator curBloodIt = bloods.begin();
	Blood* curBlood;
	unsigned int numBloods = 0;

	while(/*curBloodIt != bloods.end()*/numBloods < bloods.size()) {

		curBlood = bloods.at(numBloods);
		if (!curBlood) {
			cleanup2();
			numBloods = 0;
			continue;
		}

		if(curBlood->life == 0)
		{
			delete curBlood;
			bloods.at(numBloods) = NULL;
		}
		else
		{
			curBlood->x += curBlood->xvel;
			curBlood->y += curBlood->yvel;
			curBlood->yvel += gravity;

			if (curBlood->x >= SCREEN_WIDTH || curBlood->x <= 0)
				curBlood->life = 0;
			if (curBlood->y >= SCREEN_HEIGHT || curBlood->y <= 0)
				curBlood->life = 0;
			if (curBlood->life == 0) {
				delete curBlood;
				bloods.at(numBloods) = NULL;
				continue;
			}

			pixel_color = SDL_MapRGB(DisplaySurface->format, 255, 0, 0);
			
			/*if(curBlood->color == RED)
			    pixel_color = SDL_MapRGB(DisplaySurface->format, 255-(max_bloodlife - curBlood->life)*8, 0, 0);
			if(curBlood->color == GREEN)
			    pixel_color = SDL_MapRGB(DisplaySurface->format, 0, 255-(max_bloodlife - curBlood->life)*8, 0);
			if(curBlood->color == BLUE)
			    pixel_color = SDL_MapRGB(DisplaySurface->format, 0, 0, 255-(max_bloodlife - curBlood->life)*8);*/

			//grab pixel pointer
			pixel_data = (char*)DisplaySurface->pixels;
			
			//vertical offset
			pixel_data += ((unsigned int)curBlood->y * DisplaySurface->pitch);
			
			//horizontal offset
			pixel_data += ((unsigned int)curBlood->x * DisplaySurface->format->BytesPerPixel);

			//copy from color to frame buffer
			memcpy(pixel_data,&pixel_color,DisplaySurface->format->BytesPerPixel);
			//memcpy(pixel_data,&pixel_color,sizeof(int));

			curBloodIt++;
		}
		numBloods++;
	}
}

bool KeyDown(bool KeyFlag) {
    return KeyFlag;
}

bool KeyHit(bool &KeyFlag) {
    if(KeyFlag == true) {
        KeyFlag = false;
        return true;
    }
    return false;
}

Seriously, it isn't that complicated. You don't need to look through it all or anything. Just look at the updaterect and pixel drawing and lemme know if I've done something wrong. I've also had another terrible thing happen. I don't know when, because I've never gotten this error, but my .Exe randomly started requiring a WHOLE bunch of extra .DLL files besides SDL.dll. If I run it on a computer tha doesn't have Visual C++ installed, I get all sorts of errors becasue MSVCPD06.DLL wasn't found or something. Then, when I upload that, it needs another .DLL and I have no clue why that's happening. Do you think these random required .DLL additions are just screwed compiler settings? Any help would REALLY be appreciated!
Advertisement
Please use the source tags, like this:

#include "sdl.h"#include <stdlib.h>#include <time.h>#include <memory.h>#include <cmath>#include <vector>using namespace std;#define RED 1#define GREEN 2#define BLUE 3class Blood {public:    float x, y;    float xvel, yvel;    int life, color;    //Blood *next;};vector<Blood*>bloods;void CreateBlood(int x, int y, int angle, int intensity, int color);void cleanup();void cleanup2();void UpdateBlood();void Event();void Input();bool KeyDown(bool KeyFlag);bool KeyHit(bool &KeyFlag);const int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;SDL_Surface *DisplaySurface;Blood *first_blood = NULL;SDL_Event g_Event;char *pixel_data;//int* pixel_data;int pixel_color;int relative_angle;int test_intensity = 5;int test_angle = 0;int max_bloodlife = 30;float gravity = .4;bool f_Up;bool f_Down;bool f_Left;bool f_Right;bool f_Space;bool f_Escape; int main(int argc, char* argv[]) {	bloods.clear();    srand(time(NULL));	if(SDL_Init(SDL_INIT_VIDEO) == -1) {	    fprintf(stderr,"Could not initialize SDL!\n");		exit(1);	}	else {		fprintf(stdout,"SDL initialized properly!\n");		atexit(SDL_Quit);	}	DisplaySurface = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0,SDL_ANYFORMAT);	SDL_ShowCursor(SDL_DISABLE); 	if(!DisplaySurface) {		fprintf(stderr,"Could not set up display surface!\n");		exit(1);	}	int debug = 0;	while(1) {                Event();		if (f_Escape)			break;				//check if surface needs locking		if(SDL_MUSTLOCK(DisplaySurface)) {			if(SDL_LockSurface(DisplaySurface) == -1) {				fprintf(stderr,"Could not lock display surface!\n");				cleanup();				exit(1);			}		}             UpdateBlood();	    //update the screen		SDL_UpdateRect(DisplaySurface,0,0,0,0);	    if(SDL_MUSTLOCK(DisplaySurface)) 		    SDL_UnlockSurface(DisplaySurface);		Input();		if(test_angle > 360)			test_angle -= 360;		if(test_angle < 360)			test_angle += 360; 	}	cleanup();	fprintf(stdout,"Terminating normally.\n");	return 0;}void Event() {    //wait for an event    if(SDL_PollEvent(&g_Event) == 0) {	    //No event, so do stuff.        if(g_Event.key.keysym.sym == SDLK_ESCAPE) {            SDL_Event quit;            quit.type = SDL_QUIT;            SDL_PushEvent(&quit);		}        switch(g_Event.type) {            case SDL_KEYDOWN:                switch(g_Event.key.keysym.sym) {                    case SDLK_UP:                        f_Up = true;                        break;                    case SDLK_DOWN:                        f_Down = true;                        break;                    case SDLK_LEFT:                        f_Left = true;                        break;                    case SDLK_RIGHT:                        f_Right = true;                        break;                    case SDLK_SPACE:                        f_Space = true;                        break;                    case SDLK_ESCAPE:                        f_Escape = true;                        break;                }                break;            case SDL_KEYUP:                switch(g_Event.key.keysym.sym) {                    case SDLK_UP:                        f_Up = false;                        break;                    case SDLK_DOWN:                        f_Down = false;                        break;                    case SDLK_LEFT:                        f_Left = false;                        break;                    case SDLK_RIGHT:                        f_Right = false;                        break;                    case SDLK_SPACE:                        f_Space = false;                        break;                    case SDLK_ESCAPE:                        f_Escape = false;                        break;                }                break;            default:                break;			    		} 	} 	else {	    //event occurred, check for quit		if(g_Event.type == SDL_QUIT) {			SDL_Event quit;            quit.type = SDL_QUIT;            SDL_PushEvent(&quit);		}	}}void Input() {	if(KeyDown(f_Up))        test_intensity++;    if(KeyDown(f_Down))        test_angle -= 4;    if(KeyDown(f_Left))        test_intensity--;    if(KeyDown(f_Right))        test_angle += 4;	if(KeyDown(f_Space))        CreateBlood(320,240,test_angle,test_intensity,3);}void CreateBlood(int x, int y, int angle, int intensity, int color) {	Blood* blood;    for(int i = 0; i<=intensity; i++) {		blood = NULL;		if (!(blood = new Blood)) {			fprintf(stdout, "Out of memory :(\n");			cleanup();			exit(3);		}        blood->x = x + (rand()%(-600+300))/100.00;        blood->y = y + (rand()%(-600+300))/100.00;        blood->life = rand()%(-(intensity/12+1));	    relative_angle = angle + rand()%110 - 55;	    blood->xvel = cos(relative_angle) * (intensity/(rand()%14 + 10));	    blood->yvel = sin(relative_angle) * (intensity/(rand()%14 + 10));		blood->color = color;		bloods.push_back(blood);    }}void cleanup() {	vector<Blood*>::iterator rmvme = bloods.begin();	cleanup2();	while (rmvme != bloods.end()) {		delete *rmvme;		rmvme++;	}	bloods.clear();}void cleanup2() {	vector<Blood*>::iterator rmvme = bloods.begin();	while (rmvme != bloods.end()) {		if (*rmvme == NULL) {			bloods.erase(rmvme);			rmvme = bloods.begin();			continue;		}		rmvme++;	}}		void UpdateBlood() {	//Blood **blood_p = &first_blood;	vector<Blood*>::iterator curBloodIt = bloods.begin();	Blood* curBlood;	unsigned int numBloods = 0;	while(/*curBloodIt != bloods.end()*/numBloods < bloods.size()) {		curBlood = bloods.at(numBloods);		if (!curBlood) {			cleanup2();			numBloods = 0;			continue;		}		if(curBlood->life == 0)		{			delete curBlood;			bloods.at(numBloods) = NULL;		}		else		{			curBlood->x += curBlood->xvel;			curBlood->y += curBlood->yvel;			curBlood->yvel += gravity;			if (curBlood->x >= SCREEN_WIDTH || curBlood->x <= 0)				curBlood->life = 0;			if (curBlood->y >= SCREEN_HEIGHT || curBlood->y <= 0)				curBlood->life = 0;			if (curBlood->life == 0) {				delete curBlood;				bloods.at(numBloods) = NULL;				continue;			}			pixel_color = SDL_MapRGB(DisplaySurface->format, 255, 0, 0);						/*if(curBlood->color == RED)			    pixel_color = SDL_MapRGB(DisplaySurface->format, 255-(max_bloodlife - curBlood->life)*8, 0, 0);			if(curBlood->color == GREEN)			    pixel_color = SDL_MapRGB(DisplaySurface->format, 0, 255-(max_bloodlife - curBlood->life)*8, 0);			if(curBlood->color == BLUE)			    pixel_color = SDL_MapRGB(DisplaySurface->format, 0, 0, 255-(max_bloodlife - curBlood->life)*8);*/			//grab pixel pointer			pixel_data = (char*)DisplaySurface->pixels;						//vertical offset			pixel_data += ((unsigned int)curBlood->y * DisplaySurface->pitch);						//horizontal offset			pixel_data += ((unsigned int)curBlood->x * DisplaySurface->format->BytesPerPixel);			//copy from color to frame buffer			memcpy(pixel_data,&pixel_color,DisplaySurface->format->BytesPerPixel);			//memcpy(pixel_data,&pixel_color,sizeof(int));			curBloodIt++;		}		numBloods++;	}}bool KeyDown(bool KeyFlag) {    return KeyFlag;}bool KeyHit(bool &KeyFlag) {    if(KeyFlag == true) {        KeyFlag = false;        return true;    }    return false;}
Sorry, I am just used to that PhpBB stuff that everybody has I thought I needed a tag.
Is what I asked that complicated that nobody would know?
I was having a similiar issue
I remember that in D3D and OGL before rendering I would clear the screen to all black
so I did the same in SDL and it worked

SDL_FillRect(SDL_GetVideoSurface(), NULL, SDL_MapRGB(SDL_GetVideoSurface()->format, 0,0,0));
above post was from me
for whatever reason gamedev no longer warns that you have not entered your password
efoday has the right idea.

thankgoodness you haven't been tainted by qbasic, otherwise you might be tempted to ask for the CLS equivilant.

when you have enough objects, clearing the screen isn't an issue. ususaly you will overwrite all of the previous garbage with new data.

essentially using a filled rect...
HxRender | Cornerstone SDL TutorialsCurrently picking on: Hedos, Programmer One

This topic is closed to new replies.

Advertisement