I have been struggling with this for a while and was wondering if anyone could help. I am trying to make a particle sample using C++ and SDL1.3 and I have had great success up until this point. The program compiles and the screen opens and nothing happens. When I run the debugger I get this error:
Unhandled exception at 0x0102414a in SDL 1.3 Space.exe: 0xC0000005: Access violation reading location 0x00000008. The program '[7272] SDL 1.3 Space.exe: Native' has exited with code -1073741819 (0xc0000005).
and it points to this piece of the code:
bool particle::isDead()
{
return (SDL_GetTicks() >= endTime || x == 0 || y == 0 || x == SDL_GetVideoSurface()->w -1 || y == SDL_GetVideoSurface()->h - 1);
}
It would be greatly appreciated if someone would be so kind as to help me and /or point me in the right direction.
This is the entire program:
#include "SDL.h"
#include "common.h"
#include <stdio.h>
#include <string>
#include <cstdlib>
#include <vector>
#include <ctime>
/*static SDL_Texture *background = 0; //background
SDL_Renderer *renderer;
void render()
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, background, NULL, NULL); //Display background
S开发者_Go百科DL_RenderPresent(renderer);
endFrame = SDL_GetTicks();
};*/
class particle
{
float x, y, xvel, yvel;
Uint32 endTime;
Uint8 color;
public:
particle( float X, float Y, float Xvel, float Yvel, int life, Uint8 Color );
void move();
void show();
bool isDead();
};
particle::particle( float X, float Y, float Xvel, float Yvel, int life, Uint8 Color )
{
x = X;
y = Y;
xvel = Xvel;
yvel = Yvel;
endTime = SDL_GetTicks() + life;
color = Color;
}
void particle::move()
{
x += xvel;
y += yvel;
if ( x < 0 )
x = 0;
if ( y < 0 )
y = 0;
if ( x > SDL_GetVideoSurface() -> w)
x = SDL_GetVideoSurface() -> w - 1;
if ( y > SDL_GetVideoSurface() -> h)
y = SDL_GetVideoSurface() -> h -1;
}
void particle::show()
{
Uint8* pixels = (Uint8*) SDL_GetVideoSurface()->pixels;
Uint8* pixel = pixels + (int) y * SDL_GetVideoSurface()->pitch + (int) x;
*pixel = color;
}
bool particle::isDead()
{
return (SDL_GetTicks() >= endTime || x == 0 || y == 0 || x == SDL_GetVideoSurface()->w -1 || y == SDL_GetVideoSurface()->h - 1);
}
class particleEngine
{
std::vector <particle*> particles;
int x, y, maxparticle;
public:
particleEngine( int maxpart, int X, int Y );
~particleEngine();
void refresh();
};
particleEngine::particleEngine( int maxpart, int X, int Y )
{
x = X;
y = Y;
maxparticle = maxpart;
for ( int i = 0; i < maxparticle; i++ )
particles.push_back (new particle( x + rand()%6-3, y + rand()%6-3, rand()%10 + (float)rand()/(float)RAND_MAX - 5, rand()%10 + (float)rand()/(float)RAND_MAX - 5, 500 + rand()%1000, 0));
}
particleEngine::~particleEngine()
{
for ( int i = 0; i < maxparticle; i++)
delete particles[i];
}
void particleEngine::refresh()
{
for ( int i = 0; i < maxparticle; i++)
{
if ( particles[i]->isDead())
{
delete particles[i];
particles[i] = new particle( x + rand()%6-3, y + rand()%6-3, rand()%10 + (float)rand()/(float)RAND_MAX - 5, rand()%10 + (float)rand()/(float)RAND_MAX - 5, 500 + rand()%1000, 0);
}
else
{
particles[i]->move();
particles[i]->show();
}
}
}
int main( int argc, char* argv[] )
{
bool running = true;
const int FPS = 30;
Uint32 startFrame;
srand (time(0));
particleEngine ps(1000, SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
SDL_Window *window; /* main window */
SDL_Renderer *renderer;
if (SDL_Init(SDL_INIT_EVERYTHING)!= 0)
{
printf("Could not initialize SDL");
}
window = SDL_CreateWindow("SDL 1.3 Particles", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
// Body of the program goes here.
while (running)
{
startFrame = SDL_GetTicks();
SDL_Event event;
//render();
//While there's events to handle
while( SDL_PollEvent( &event ) )
{
//If the user has Xed out the window
if (event.type == SDL_QUIT)
{
running = false;
}
}
//SDL_FillRect(renderer, &renderer->clip_rect, SDL_MapRGB(renderer->format, 0x00,0x00, 0x00));
ps.refresh();
//SDL_RenderCopy(renderer, 0, 0, 0);
SDL_RenderPresent(renderer);
//SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
//SDL_RenderClear(renderer);
if (1000/FPS>SDL_GetTicks()-startFrame)
SDL_Delay(1000/FPS-(SDL_GetTicks()-startFrame));
}
SDL_Quit();
return 0;
}
Access violations mean you are dereferencing null pointers(or pointers to memory you don't have access to), so this would mean (assuming the debugger synced with the source correctly) that SDL_GetVideoSurface
is returning null, so you'll probably wanna throw a few checks in isDead
. Secondly, its probably a good idea to store the w/h of the surface minus 1 in your class at during the creation of the surface, should mean a little less computational overhead along with shorter code.
精彩评论