2017-03-22 2 views
0

Je crée un moteur de jeu capable de charger des graphiques à partir de fichiers JSON et PNG, et j'ai fait de réels progrès. Le seul problème est, je ne peux pas comprendre comment charger plusieurs sprites à la fois. J'ai essayé beaucoup d'approches différentes, mais c'est celle que je pense qui va marcher. Bien que compilé, bien que, le terminal me donne cette erreur:Échec de l'assertion `fp_! = 0 '(RapidJSON)

Test: /home/thomas/Documents/project-repos/game/rapidjson/filereadstream.h:45: rapidjson::FileReadStream::FileReadStream(FILE*, char*, std::size_t): Assertion `fp_ != 0' failed.

Aborted (core dumped)

Je sais que cela signifie généralement que le fichier JSON ne peut pas être trouvé, mais je me suis assuré que tout est dans le répertoire de travail.

Voici mon code:

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 
    }] 
} 

Toute mention de "ErrorLog()" est dans un autre fichier, qui a déjà été testé. Compiler avec CMake (gcc) sur Xubuntu 16.10 si quelqu'un peut aider. Merci.

EDIT

J'ai ajouté un nouveau code à toutes mes fonctions JSON:

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

... changer pour l'adapter à toutes les fonctions. "GetFileHeight" provoque l'erreur, semble-t-il. Je pense qu'il pourrait s'agir d'ouvrir le fichier, et ne pas le fermer avant de le relire? Je ne suis pas sûr.

+0

"Lors de la compilation, cependant, le terminal me donne cette erreur: ..." Vous voulez dire, comme, la compilation provoque un vidage du noyau?! –

+0

Oui, j'aurais dû être plus précis. Il ne me donne pas d'erreurs de compilation, il me donne une erreur après que l'exécutable a été créé. – 123TQB

Répondre

1

Votre erreur semble se produire en raison de cette partie (ou l'une des répétitions) de votre code défaut:

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

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

Vous devriez toujours vérifier, si fopen() pourrait effectivement ouvrir le fichier. En cas d'échec, file sera défini sur 0 (ou NULL pour être précis), ce qui déclenchera l'assertion dans le constructeur pour FileReadStream, car vous passez NULL, ce qui n'est pas un pointeur de fichier valide (FILE*).