2014-02-08 3 views
0
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; 
     } 
    } 
} 

Так что, когда я пытаюсь запустить этот код (часть более крупного проекта) он иногда дает мне Segfault о вызове setType(DIRT) изнутри createPixel(). Я знаю, что значения, указанные в createPixel(), находятся в пределах диапазона, в котором они разрешены (от 0 до 64). Кажется segfault, если вы нажмете (который вызывает createPixel()) в том же месте дважды. Линия, отладчик говорит это ошибка сегментацииSegfault при попытке получить доступ к булево внутри класса

void setType(Pixel_Types what_type) { type = what_type; }

хотя, я проверил, что те ценности, которые я подаваемые это правильно.

ответ

1

Поскольку динамического распределения внутри класса не существует, наличие segfault для такого распределения наиболее вероятно происходит, потому что сам указатель this неверен (NULL или плохо назначен). Вы должны получить трассировку, когда она будет устранена, чтобы увидеть, как был выделен объект, на который вы назвали setType. Например, не следует линия

world.push_back(Pixel(x, y)); 

быть

world.push_back(new Pixel(x,y)); 

?

+0

Хорошо, поэтому я попробовал это, а также изменил переменную мира для работы с указателями пикселей, и у меня все еще есть segfault на той же линии. Я просмотрел переменные и заметил, что 'this' был установлен в' 0x0', а переменные в классе пикселей были неопределенными, даже когда я использовал 'new Pixel (x, y)', как показано здесь: http: // i.imgur.com/kFZ8QBL.png, и это то, на что он должен выглядеть, как вызванный из 'generateWorld()' http://i.imgur.com/QlJ5Wx9.png – Aearnus

+0

Мои диалоги были правильными. Вы вызываете 'setType' на нулевой указатель. Обратите внимание, что я не сказал, что исправил все проблемы с распределением с моей коррекцией. Так что встаньте фрейм стека в отладчике, чтобы искать, когда появляется этот нулевой указатель. – hivert

+0

Обычный стек: http://i.imgur.com/JAV7SSH.png и стек, когда я получаю segfault: http://i.imgur.com/YoLOhFd.png Как вы можете видеть, указатель для пикселя 0x0 во втором изображении. Было бы просто передать указатель на пиксель, с которым я хочу работать, быть чем-то, что я мог бы сделать (как, в котором не было 'setType()' быть функцией в Pixel')? – Aearnus

Смежные вопросы