123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- #include <iostream>
- #include <string>
- #include <vector>
- #include "SpriteData.hpp"
- #include "ajson5.h"
- #include "contourdata.h"
- #include "LevelGenerate.hpp"
- #include "FillGlobalConfig.hpp"
- #include "RandomGridFiller.hpp"
- #include "BoostGeometryTools.hpp"
- #include <opencv2/core.hpp>
- #include <opencv2/imgproc.hpp>
- #include <opencv2/highgui.hpp>
- #include <sstream>
- #include <ctime>
- #include <chrono>
- using namespace ArduinoJson;
- using namespace std;
- bool writeLevelJson(vector<tuple<int,vector<vector<FillResult>>>>& resultPlateFillResults,
- vector<ContourData::Point>& resultPlateCenterPointArr,
- string outfilename);
- int getGidByFileName(JsonArray *jTileSets, FillGlobalConfig::PlateItem* plate);
- int main(int argc, const char * argv[]) {
- cout<<"A program to generate level. 2024-11-23"<<endl;
- cout<<"usage:auto_fill_jewel_v3"<<endl;
- cout<<"version v3.0"<<endl ;
- // if( argc!=2 ) {
- // cout<<"缺少参数"<<endl;
- // return 11 ;
- // }
- string outname = "测试关卡100.json" ;
- FillGlobalConfig::getInstance() ; //inited
- vector<tuple<int,vector<vector<FillResult>>>> resultPlateFillResults;
- vector<ContourData::Point> resultPlateCenterPointArr;
- LevelGenerate genv3 ;
- genv3.generate( *FillGlobalConfig::getInstance()->getLevelData(100, 0),
- resultPlateFillResults,
- resultPlateCenterPointArr
- ) ;
- cout<<"write result to "<<outname<<endl;
- writeLevelJson(resultPlateFillResults, resultPlateCenterPointArr, outname);
- // string levelCsvfilename = argv[1] ;
- // LevelInputConfig levelInputConfig ;
- // bool isok = levelInputConfig.readFromCsv(levelCsvfilename) ;
- // LevelGenerate genv3 ;
- // genv3.generate(levelInputConfig) ;
- if(false)
- {//测试6个大的
- const float BIG_JEW_WID = 80 ;
- vector<RandomGridFiller::JewelBox> jewBoxArray ;
- RandomGridFiller::JewelBox jb1,jb2 ;
- jb1._cnt = 3 ;
- jb1._height = BIG_JEW_WID ;
- jb1._width = BIG_JEW_WID*0.67;
- jb1._jewelTypeId = 1 ;
- jb2._cnt = 3*2 ;
- jb2._height = BIG_JEW_WID*0.75 ;
- jb2._width = BIG_JEW_WID*0.75 ;
- jb2._jewelTypeId = 2 ;
- jewBoxArray.push_back(jb1) ;
- jewBoxArray.push_back(jb2) ;
- auto ms0 = std::chrono::system_clock::now().time_since_epoch() ;
- uint64_t ms00 = std::chrono::duration_cast<chrono::milliseconds>(ms0).count() ;
- RandomGridFiller RBFiller ;
- RBFiller._seed = 5 ;
- vector< vector<FillResult> > results(1) ;
- RBFiller.fill(jewBoxArray, 5, 14 , 200, 265, results[0] ) ;
- auto ms1 = std::chrono::system_clock::now().time_since_epoch() ;
- uint64_t ms11 = std::chrono::duration_cast<chrono::milliseconds>(ms1).count() ;
- cout<<"duration(ms) "<<ms11-ms00<<endl;
- for(int ires = 0 ;ires < results.size();++ ires ) {
- cv::Mat plateimage = cv::Mat::zeros( 270, 210, CV_8UC3 );
- for(int ibox = 0 ; ibox < results[ires].size(); ++ ibox ) {
- FillResult& fr = results[ires][ibox] ;
- BoostGeometryTools::BoostPolygon poly1 = BoostGeometryTools::makeRotateNTranslateBox(-fr._width/2, -fr._height/2, fr._width, fr._height, results[ires][ibox]._rotdeg, results[ires][ibox]._x, results[ires][ibox]._y) ;
- vector<cv::Point> cvpoints ;
- for(int ipt = 0 ;ipt < poly1.outer().size();++ ipt ) {
- cv::Point p2 ;
- p2.x = poly1.outer()[ipt].get<0>();
- p2.y = poly1.outer()[ipt].get<1>() ;
- cvpoints.push_back(p2) ;
- }
- cv::polylines(plateimage, cvpoints, true, cv::Scalar(rand()%255,rand()%255,rand()%255));
- }
- //
- stringstream ss ;
- ss<<"win"<<ires ;
- cv::imshow( ss.str().c_str() , plateimage );
- }
- cv::waitKey();
- }
-
-
-
- return 0;
- }
- int getGidByFileName(JsonArray &jTileSets, FillGlobalConfig::PlateItem* plate) {
- static int gid = 0;
- for (int i = 0; i < jTileSets.size(); i++){
- if (jTileSets[i]["image"] == plate->_pngName){
- return static_cast<int>(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 writeLevelJson(vector<tuple<int,vector<vector<FillResult>>>>& resultPlateFillResults,
- vector<ContourData::Point>& resultPlateCenterPointArr,
- string outfilename)
- {
- auto fgc = FillGlobalConfig::getInstance() ;
- int totalJewelCnt = 0 ;
- for(auto itp = resultPlateFillResults.begin();itp!=resultPlateFillResults.end();++itp) {
- int plateId = std::get<0>( *itp ) ;
- vector<vector<FillResult>>& frArr = std::get<1>( *itp );
- 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 < resultPlateFillResults.size(); i ++){
- auto itp = resultPlateFillResults.begin() ;
- std::advance(itp, i) ;
- int plateId = std::get<0>( *itp ) ;
-
- 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 = resultPlateCenterPointArr[i].x;
- float platey = resultPlateCenterPointArr[i].y;
- tiledPlateObj["x"] = platex - fgc->getPlateItemById(plateId)->_bbwid / 2;
- tiledPlateObj["y"] = platey - fgc->getPlateItemById(plateId)->_bbhei / 2;
-
- vector<vector<FillResult>>& frArr = std::get<1>( *itp );
-
- 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;
- JsonArray& layerArr = plateObj.createNestedArray("layers");
- for(int il = 0 ; il < frArr.size() ; ++il ) {
- vector<FillResult>& 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<<jsonText;
- jsonText.clear();
- tiledRoot.printTo(jsonText);
- outfilename.insert(outfilename.size() - 5, "Tiled");
- ofstream ofsTiled( outfilename.c_str() );
- if( ofsTiled.good()==false ) return false;
- ofsTiled<<jsonText;
- return true;
- }
|