const int PIXEL_WIDTH = 10;
const int PIXEL_HEIGHT = 10;
const int WORLD_X = 64; //WORLD_X * PIXEL WIDTH = SCREEN_WIDTH if you want the world to be the same size as the screen
const int WORLD_Y = 64;
enum Pixel_Types {
AIR,
WALL,
DIRT,
STONE
};
class Pixel
{
int x, y;
bool affected_by_gravity;
Pixel_Types type;
public:
Pixel() : affected_by_gravity(false), type(AIR), x(0), y(0) {}
Pixel(int temp_x, int temp_y) : affected_by_gravity(false), type(AIR), x(temp_x), y(temp_y) {}
int getX() { return x; } //x is 0-63, scales up in the rendering code
int getY() { return y; } //y is 0-63, scales up in the rendering code
int getScreenX() { return x*PIXEL_WIDTH; } //x is 0-63, scales up in the rendering code
int getScreenY() { return y*PIXEL_HEIGHT; } //y is 0-63, scales up in the rendering code
bool setDeltaX(int temp_delta_x);
bool setDeltaY(int temp_delta_y);
void setAffectedByGravity(bool yesorno) { affected_by_gravity = yesorno; }
bool getAffectedByGravity() { return affected_by_gravity; }
Pixel_Types getType() { return type; }
void setType(Pixel_Types what_type) { type = what_type; }//if (type == DIRT or type == STONE) { affected_by_gravity = true; } }
};
std::vector<Pixel> world; //the world is a dynamically allocated thing
Pixel* getPixelFromCoordinates(int x, int y)
{
if (x > 63) x = 63;
else if (x < 0) x = 0;
if (y > 63) y = 63;
else if (y < 0) y = 0;
for (int pixel_index = 0; pixel_index < world.size(); pixel_index++) {
if (world.at(pixel_index).getX() == x && world.at(pixel_index).getY() == y) {
return &world.at(pixel_index);
}
}
return NULL;
}
bool Pixel::setDeltaX(int temp_delta_x) {
if (x+temp_delta_x > SCREEN_WIDTH/PIXEL_WIDTH or x+temp_delta_x < 0) {
return false;
}
if (getPixelFromCoordinates(x+temp_delta_x, y)->type == AIR) {
x += temp_delta_x;
return true;
}
return false;
}
bool Pixel::setDeltaY(int temp_delta_y) {
if (y+temp_delta_y > SCREEN_HEIGHT/PIXEL_HEIGHT or y+temp_delta_y < 0) {
return false;
}
if (getPixelFromCoordinates(x, y+temp_delta_y)->type == AIR) {
y += temp_delta_y;
return true;
}
return false;
}
void generateWorld()
{
for (int world_generation_index = 0; world_generation_index < 4096; world_generation_index++) {
int x = world_generation_index % WORLD_X; //the world is 64 pixels left and right, and 64 up and down. this math is pretty easy and just extrapolates that. also each pixel is 10 pixels across, times 64 pixels = 640 (the resolution)
int y = floor(world_generation_index / WORLD_Y); //both x and y start at 0
world.push_back(Pixel(x, y));
if (x == 0 || x == 63) {
world.at(world_generation_index).setType(WALL);
}
if (y == 1) {
world.at(world_generation_index).setType(WALL);
}
}
std::cout << "World size: " << world.size() << std::endl;
}
void createPixel(int x, int y, Pixel_Types type)
{
std::cout << x << std::endl;
std::cout << y << std::endl << std::endl;
y = (SCREEN_HEIGHT / PIXEL_HEIGHT) - y; //compensate for the stupid inverted y in opengl
//if (getPixelFromCoordinates(x, y)->getType() == AIR) {
getPixelFromCoordinates(x, y)->setType(type);
//}
}
void physicsOneStep()
{
for (int pixel_index = 0; pixel_index < world.size(); pixel_index++) {
if (world.at(pixel_index).getType() == DIRT or world.at(pixel_index).getType() == STONE) {//if (world.at(pixel_index).getAffectedByGravity()) {
world.at(pixel_index).setDeltaY(-1);
//std::cout << world.at(pixel_index).getX() << std::endl;
//std::cout << world.at(pixel_index).getY() << std::endl << std::endl;
}
}
}
因此,当我尝试运行此代码(较大项目的一部分)时,偶尔会给我从createPixel()
中调用setType(DIRT)
的segfault。我知道提供给createPixel()
的值在允许的范围内(0至64)。如果您两次在同一位置单击(调用createPixel()
),则似乎可以看到。调试器说segfaults是
void setType(Pixel_Types what_type) { type = what_type; }
不过,我已经验证了我为此提供的值是否正确。
由于类内部没有动态分配,因此在这种分配上有segfault肯定会发生,因为this
指针本身不正确(null或不良分配)。当segfault被击倒时,您应该抬起回溯,以查看如何分配称为setType
的对象。例如,不应该行
world.push_back(Pixel(x, y));
be
world.push_back(new Pixel(x,y));
?