// // LevelOutputWriter.cpp // auto_fill_jewel_v3 // // Created by Red on 2024/12/10. // #include "LevelOutputWriter.hpp" #include using std::ofstream; using namespace ArduinoJson; int LevelOutputWriter::getGidByFileName(JsonArray &jTileSets, FillGlobalConfig::PlateItem* plate) { static int gid = 0; for (int i = 0; i < jTileSets.size(); i++){ string jsonImgName = jTileSets[i]["image"].as() ; if ( jsonImgName.compare( plate->_pngName ) == 0 ){ return static_cast(jTileSets[i]["firstgid"]); } } gid ++; JsonObject& obj = jTileSets.createNestedObject(); obj["firstgid"] = gid; obj["image"] = plate->_pngName; obj["imageheight"] = plate->_bbhei; obj["imagewidth"] = plate->_bbwid; obj["margin"] = 0; obj["name"] = plate->_name; obj.createNestedObject("properties"); obj["spacing"] = 0; obj["tileheight"] = plate->_bbhei; obj["tilewidth"] = plate->_bbwid; return gid; } bool LevelOutputWriter::writeLevelJson(vector& plateFillResults, vector& plateCenterPointArr, string outfilename) { auto fgc = FillGlobalConfig::getInstance() ; int totalJewelCnt = 0 ; for(auto itp = plateFillResults.begin();itp!=plateFillResults.end();++itp) { int plateId = itp->_plateTypeId ; vector>& frArr = itp->_layersFillResults ; for(auto itfr = frArr.begin(); itfr!=frArr.end();++itfr ) { totalJewelCnt+=itfr->size() ; } } DynamicJsonBuffer jsonBufferTiled; DynamicJsonBuffer jsonBuffer; JsonObject& tiledRoot = jsonBufferTiled.createObject(); JsonObject& root = jsonBuffer.createObject(); tiledRoot["height"] = 18; JsonArray& jLayerArr = tiledRoot.createNestedArray("layers"); JsonObject& lyrObj = jLayerArr.createNestedObject(); lyrObj["draworder"] = "topdown"; lyrObj["height"] = 18; lyrObj["name"] = "Layer"; JsonArray& jObjArr = lyrObj.createNestedArray("objects"); //盘子信息 lyrObj["opacity"] = 1; lyrObj["type"] = "objectgroup"; lyrObj["visible"] = true; lyrObj["width"] = 16; lyrObj["x"] = 0; lyrObj["y"] = 0; tiledRoot["nextobjectid"] = 4; tiledRoot["orientation"] = "orthogonal"; tiledRoot.createNestedArray("properties"); tiledRoot["renderorder"] = "right-down"; tiledRoot["tileheight"] = 40; JsonArray& jTileSets = tiledRoot.createNestedArray("tilesets"); //盘子纹理图 tiledRoot["tilewidth"] = 40; tiledRoot["version"] = 1; tiledRoot["width"] = 16; root.createNestedObject("target");//not used. root["bgtem"] = "no"; //背景redream文件 root["jewel_count"] = totalJewelCnt ; JsonArray& jplatesArr = root.createNestedArray("plates"); int ids = 1; for (int i = 0; i < plateFillResults.size(); i ++){ auto itp = plateFillResults.begin() ; std::advance(itp, i) ; int plateId = itp->_plateTypeId ; JsonObject& tiledPlateObj = jObjArr.createNestedObject(); tiledPlateObj["gid"] = getGidByFileName(jTileSets, fgc->getPlateItemById(plateId)); tiledPlateObj["height"] = 0; tiledPlateObj["id"] = ids; tiledPlateObj["name"] = "plate"; tiledPlateObj.createNestedObject("properties"); tiledPlateObj["rotation"] = 0; tiledPlateObj["type"] = ""; tiledPlateObj["visible"] = true; tiledPlateObj["width"] = 0; float platex = plateCenterPointArr[i].x; float platey = plateCenterPointArr[i].y; tiledPlateObj["x"] = platex - fgc->getPlateItemById(plateId)->_bbwid / 2; tiledPlateObj["y"] = platey - fgc->getPlateItemById(plateId)->_bbhei / 2; vector>& frArr = itp->_layersFillResults ; JsonObject& plateObj = jplatesArr.createNestedObject(); plateObj["typeId"] = plateId ; plateObj["plateId"] = ids++; plateObj["x"] = platex; plateObj["y"] = platey; plateObj["sprite_frame_name"] = fgc->getPlateItemById(plateId)->_pngName; plateObj["sizeX"] = fgc->getPlateItemById(plateId)->_bbwid; plateObj["sizeY"] = fgc->getPlateItemById(plateId)->_bbhei; plateObj["move"] = itp->_moveId ; JsonArray& layerArr = plateObj.createNestedArray("layers"); for(int il = 0 ; il < frArr.size() ; ++il ) { vector& frs = frArr[il]; JsonObject& lyrObj = layerArr.createNestedObject(); lyrObj["rotate"] = 0.0; lyrObj["scale_x"] = 1.0; lyrObj["scale_y"] = 1.0; lyrObj["scale"] = 1.0; lyrObj["sprite_frame_name"] = fgc->getPlateItemById(plateId)->_pngName; lyrObj["lyrId"] = ids++; lyrObj["zorder"] = il+1; JsonArray& posArr = lyrObj.createNestedArray("position"); posArr.add(platex); posArr.add(platey); JsonArray& screwArr = lyrObj.createNestedArray("screws"); for(int ij = 0 ;ij < frs.size();++ ij ) { FillResult& fr = frs[ij]; FillGlobalConfig::JewelItem* jewPtr = fgc->getJewelItemById(fr._jewelTypeId); if( fr._jewelTypeId>=0 ) { // -1 is removed. JsonObject& jobj = screwArr.createNestedObject(); jobj["rotate"] = fr._rotdeg; jobj["scale_x"] = jewPtr->_scale; jobj["scale_y"] = jewPtr->_scale; jobj["csx"] = 0; jobj["csy"] = 0; jobj["scale"] = jewPtr->_scale; jobj["sprite_frame_name"] = jewPtr->_pngName; jobj["screwId"] = ids++; jobj["typeId"] = fr._jewelTypeId ; JsonArray& posArr2 = jobj.createNestedArray("position"); posArr2.add( fr._x ); // 钉子中心在游戏区域的坐标(原点左下角) posArr2.add( fr._y ); } } } } string jsonText ; root.printTo(jsonText); ofstream ofs( outfilename.c_str() ); if( ofs.good()==false ) return false; ofs<