Twinklebear / LPCGame

Working on a C++ tile based 'engine' using SDL
MIT License
18 stars 1 forks source link

Added a TileSet Class #7

Closed btstevens89 closed 11 years ago

btstevens89 commented 11 years ago

The TileSet class stores Tiles and their associated Textures into maps.

Disambiguations

Just to clarify, in this document, from hereon in...

  1. Any reference to 'image' is to purely mean the actual image file. NOT anything related to the Image class.
  2. There are two types of tilenames.
    • The image's tilename. Found in the image's .json file
    • The tileset's full tilenames. The image's name, paired with the image's tilename.
    • If the image name is "../res/img/forest.png", and it's .json file defines a tile named "Grass - Plain", the image's tilename is "Grass - Plain". The full tilename used for querying will be "forest - Grass - Plain".

      Functions

There are 4 main functions that will be used.

Add()

void Add(std::string imageFile) imageFile should be a path to an image file. There should be an accompanying .json file in the same directory that contains the clips for the image. The .json file should include "name", and "solid" attributes for the clips. There should be no "name" collisions.

This function is used to add an image to the TileSet. The SDL_Texture paired with the path to the image in mImages. The tiles in the image's .json file will be paired with their full tilename in mTileSet.

Texture()

SDL_Texture* Texture(std::string tilename) tilename should be the full tilename.

Returns a pointer to it's SDL_Texture.

Solid()

bool Solid(std::string tilename) tilename should be the full tilename.

Returns a bool property of Solid.

Clip()

Recti Clip(std::string tilename) tilename should be the full tilename.

Returns the Recti of where the tile is found in the image.

Other Functions

int Size() returns the amount of tiles in the tileset iterator Begin() returns a reference to the first element in the tileset iterator End() returns a reference to the end of the tileset

Twinklebear commented 11 years ago

Awesome! The only thing i would suggest changing is in TileSet::Add

void TileSet::Add(const std::string &file){
    //Get just the config name
    unsigned int a = file.rfind('.');
    std::string configFile = file.substr(0, a) + ".json";

    //Add this image
    std::shared_ptr<SDL_Texture> newTexture;
    newTexture.reset(Window::LoadTexture(file), SDL_DestroyTexture);
    mImages[file] = newTexture;

    //Parse the .json file
    std::ifstream fileIn((configFile).c_str(), std::ifstream::binary);
    if (fileIn){
        Json::Reader reader;
        Json::Value root;
        if (reader.parse(fileIn, root, false)){
            //Load the config data
            ParseImageJson(root, file);
        }
        else
            //some debug output, this case should throw
            throw std::runtime_error("Failed to parse file: " + configFile);

        fileIn.close();
    }
    else
        throw std::runtime_error("Failed to find file: " + configFile);
}

Everything related to parsing the filename and reading the json file can be done through the JsonHandler class if you take a peek at it. So it can be replaced with

void TileSet::Add(const std::string &file){
    //Add this image
    std::shared_ptr<SDL_Texture> newTexture;
    newTexture.reset(Window::LoadTexture(file), SDL_DestroyTexture);
    mImages[file] = newTexture;

    JsonHandler handler(file);
    //Need to catch potential errors thrown by JsonHandler::Read
    //same possible errors as you have above
    try {
        ParseImageJson(handler.Read(), file);
    }
    catch (const std::runtime_error &e){
        std::cout << e.what() << std::endl;
        //should it rethrow to force a crash? program would probably crash anyways if the 
        //the file failed to read
    }
}

Basically the JsonHandler class exists to make it easier to do these sorts of repeated read/writes of json data, and if you look in the constructor it will make sure the file is a json file if it isn't a json file it will replace the extension "png" for example with "json" and attempt to read a json file by the new name.

You can add this change and update the pull request or I'll merge it and toss in the change, it should be really quick to do.

Anyways, that's my only note. The TileSet stuff is looking pretty great!

btstevens89 commented 11 years ago

Fixed up.

Twinklebear commented 11 years ago

Cool, looks great!