断言`fp_!= 0'失败(RapidJSON)

时间:2017-03-22 02:46:11

标签: c++ json game-engine sfml rapidjson

我正在制作一个可以从JSON和PNG文件加载图形的游戏引擎,我已经取得了一些实际进展。唯一的问题是,我无法弄清楚如何一次加载多个精灵。我尝试了很多不同的方法,但这是我认为可行的方法。虽然编译时,终端给了我这个错误:

  

测试:/home/thomas/Documents/project-repos/game/rapidjson/filereadstream.h:45:rapidjson :: FileReadStream :: FileReadStream(FILE *,char *,std :: size_t):断言`fp_! = 0'失败。

     

中止(核心倾销)

我知道这通常意味着无法找到JSON文件,但我确保所有内容都在工作目录中。

这是我的代码:

main.cpp中:

#include <iostream>
#include <unistd.h>
#include <string>
#include <SFML/Graphics.hpp>

// The universal include file.
#include "include.hpp"

int main() {

    // Declaration of the window.
    sf::RenderWindow window(sf::VideoMode(640, 320), "Test Game", sf::Style::Close);

    // Getting the background texture.
    sf::Texture bkgd;
    if(!bkgd.loadFromFile("../textures/generic.png")) {
        ErrorLog("1", "../game.log");
        window.close();
    }

    // Getting the map textures.
    sf::Texture map;
    if(!map.loadFromFile("../textures/textures.png")) {
        ErrorLog("2", "../game.log");
        window.close();
    }

    // Creating the background sprite.
    sf::Sprite bkgdSp;
    bkgdSp.setTexture(bkgd);

    // Local variable to check if fullscreen is activated.
    int fullScreen = 0;

    // The window loop.
    while(window.isOpen()) {

        // Local variable that keeps the current window size.
        sf::Vector2f winSize(window.getSize());

        // Local variables storing the window ratios.
        float scaleX = winSize.x / 640;
        float scaleY = winSize.y / 320;

        // Local variable to store the number of map tiles.
        int mapNum = LoadNumber("../locations.json");

        // Local array for the sprites.
        sf::Sprite mapSp;

        // Local array for the tiles.
        tile mapTile;

        // Load tile information.
        mapTile = LoadTile("../locations.json", 1);

        // Texture rectangle for the current sprite.
        sf::IntRect mapRect(GetFileCoordinates(mapTile.type).x, GetFileCoordinates(mapTile.type).y, GetFileWidth(mapTile.type), GetFileHeight(mapTile.type));

        // Setting the texture for the current sprite.
        mapSp.setTexture(map);
        mapSp.setTextureRect(mapRect);

        // Scaling and repositioning the current sprite.
        mapSp.setScale(scaleX, scaleY);
        mapSp.setPosition(mapTile.x * scaleX, mapTile.y * scaleY);


        // The event loop (only used to close the window.
        sf::Event event;
        while(window.pollEvent(event)) {
            if(event.type == sf::Event::Closed) {
                window.close();
            }
        }

        // Change window size if F1 is pressed.
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::F1)) {
            if(fullScreen == 0) {
                window.create(sf::VideoMode(1280, 640), "Test Game", sf::Style::Close);
                fullScreen = 1;
            }else if(fullScreen == 1) {
                window.create(sf::VideoMode(640, 320), "Test Game", sf::Style::Fullscreen);
                fullScreen = 2;
            }else if(fullScreen == 2) {
                window.create(sf::VideoMode(640, 320), "Test Game", sf::Style::Close);
                fullScreen = 0;
            }
        }

        // Resizes the background to fit the window size.
        bkgdSp.setScale(scaleX, scaleY);

        // Drawing and displaying the window.
        window.clear();

        window.draw(bkgdSp);
        window.draw(mapSp);

        window.display();

        usleep(7000);
    }

    return 0;
}

load.cpp:

#include <iostream>
#include <SFML/System.hpp>
#include "rapidjson/document.h"
#include "rapidjson/filereadstream.h"

// The universal include file.
#include "include.hpp"

using namespace rapidjson;

// Function that loads tile values from the locations file.
tile LoadTile(std::string fileName, int number) {
    tile output;

    FILE* file = fopen(fileName.c_str(), "r");

    char buffer[10000];
    FileReadStream stream(file, buffer, 10000);

    Document doc;
    doc.ParseStream(stream);

    std::string input = std::to_string(number);

    Value& tileNumber = doc[input.c_str()];

    output.x = tileNumber[0]["x"].GetInt();
    output.y = tileNumber[1]["y"].GetInt();
    output.type = tileNumber[2]["type"].GetString();

    return output;
}

// Function that gets the current tile type's x and y coordinates.
sf::Vector2f GetFileCoordinates(std::string type) {
    sf::Vector2f output;

    FILE* file = fopen("../textures.json", "r");

    char buffer[10000];
    FileReadStream stream(file, buffer, 10000);

    Document doc;
    doc.ParseStream(stream);

    Value& typeNumber = doc[type.c_str()];

    output.x = typeNumber[0]["x"].GetInt();
    output.y = typeNumber[1]["y"].GetInt();

    return output;
}

// Function that gets the number of objects in the current map file.
int LoadNumber(std::string fileName) {
    FILE* file = fopen(fileName.c_str(), "r");

    char buffer[10000];
    FileReadStream stream(file, buffer, 10000);

    Document doc;
    doc.ParseStream(stream);

    int objCount = 1;
    std::string strCount = std::to_string(objCount);
    while(doc.HasMember(strCount.c_str())) {
        objCount++;
        strCount = std::to_string(objCount);
    }

    return objCount - 1;
}

// Function that gets the current tile type's width.
int GetFileWidth(std::string type) {
    int output;

    FILE* file = fopen("../textures.json", "r");

    char buffer[10000];
    FileReadStream stream(file, buffer, 10000);

    Document doc;
    doc.ParseStream(stream);

    Value& typeNumber = doc[type.c_str()];

    output = typeNumber[2]["width"].GetInt();

    return output;
}

// Function that gets the current tile type's height.
int GetFileHeight(std::string type) {
    int output;

    FILE* file = fopen("../textures.json", "r");

    char buffer[10000];
    FileReadStream stream(file, buffer, 10000);

    Document doc;
    doc.ParseStream(stream);

    Value& typeNumber = doc[type.c_str()];

    output = typeNumber[3]["height"].GetInt();

    return output;
}

include.hpp:

#include <iostream>
#include <SFML/Graphics.hpp>
#include "rapidjson/document.h"

// Public struct declaring the "tile" data type. Uses the same characteristics as the tile locations file.
struct tile {
    int x;
    int y;
    std::string type;
};

// In load.cpp.
tile LoadTile(std::string fileName, int number);
sf::Vector2f GetFileCoordinates(std::string type);
int LoadNumber(std::string fileName);
int GetFileWidth(std::string type);
int GetFileHeight(std::string type);

// In log.cpp
void ErrorLog(std::string code, std::string fileName);

locations.json:

{
    "1": [{
        "x": 32
    }, {
        "y": 32
    }, {
        "type": "water_c"
    }],

    "2": [{
        "x": 32
    }, {
        "y": 64
    }, {
        "type": "dirt_c"
    }]
}

textures.json:

{
    "grass_c": [{
        "x": 0
    }, {
        "y": 0
    }, {
        "width": 32
    }, {
        "height": 32
    }],

    "water_c": [{
        "x": 32
    }, {
        "y": 0
    }, {
        "width": 32
    }, {
        "height": 32
    }],

    "sand_c": [{
        "x": 64
    }, {
        "y": 0
    }, {
        "width": 32
    }, {
        "height": 32
    }],

    "dirt_c": [{
        "x": 96
    }, {
        "y": 0
    }, {
        "width": 32
    }, {
        "height": 32
    }],

    "wood_c": [{
        "x": 128
    }, {
        "y": 0
    }, {
        "width": 32
    }, {
        "height": 32
    }],

    "brick_c": [{
        "x": 160
    }, {
        "y": 0
    }, {
        "width": 32
    }, {
        "height": 32
    }]
}

任何提及“ErrorLog()”的文件都在另一个已经过测试的文件中。如果有人可以提供帮助,请在Xubuntu 16.10上使用CMake(gcc)进行编译。谢谢。

修改

我已经为我的所有JSON函数添加了新代码:

FILE* file = fopen("../textures.json", "r");
if(file == 0) {
    std::cout << "GetFileHeight failed to load the file." << std::endl;
}

...改变它以适应每个功能。看来,“GetFileHeight”正在导致错误。我想它可能是关于打开文件,而不是在再次阅读之前关闭它?我不确定。

1 个答案:

答案 0 :(得分:1)

由于您的代码的这一部分(或其中一个重复)失败,您的错误似乎发生了:

FILE* file = fopen(fileName.c_str(), "r");

char buffer[10000];
FileReadStream stream(file, buffer, 10000);

您应该始终检查fopen()是否可以实际打开该文件。如果失败,file将设置为0(或NULL为准确),这将触发FileReadStream的构造函数中的断言,因为您正在通过NULL,它不是有效的文件指针(FILE*)。