generated from sigonasr2/CPlusPlusProjectTemplate
Implemented TSX exporting for expanded tile hitboxes.
This commit is contained in:
parent
4defd6d5ea
commit
d9107f3077
@ -53,12 +53,10 @@ class TSXParser{
|
|||||||
inline Tileset&GetData(){
|
inline Tileset&GetData(){
|
||||||
return parsedTilesetInfo;
|
return parsedTilesetInfo;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
|
|
||||||
class NonObject{
|
std::vector<XMLTag>originalData;
|
||||||
public:
|
std::vector<NonObject>nonObjects;
|
||||||
std::vector<XMLTag>tags;
|
private:
|
||||||
};
|
|
||||||
|
|
||||||
enum NextObjectType{
|
enum NextObjectType{
|
||||||
OBJECT,
|
OBJECT,
|
||||||
@ -67,8 +65,6 @@ class TSXParser{
|
|||||||
};
|
};
|
||||||
|
|
||||||
Tileset parsedTilesetInfo;
|
Tileset parsedTilesetInfo;
|
||||||
std::vector<XMLTag>originalData;
|
|
||||||
std::vector<NonObject>nonObjects;
|
|
||||||
int previousTagID;
|
int previousTagID;
|
||||||
std::string currentObj;
|
std::string currentObj;
|
||||||
NextObjectType nextObjType;
|
NextObjectType nextObjType;
|
||||||
@ -137,6 +133,7 @@ class TSXParser{
|
|||||||
if(newTag.data["name"]=="Name"){
|
if(newTag.data["name"]=="Name"){
|
||||||
std::string objectName=newTag.data["value"];
|
std::string objectName=newTag.data["value"];
|
||||||
currentObj=objectName;
|
currentObj=objectName;
|
||||||
|
parsedTilesetInfo.objects[objectName].name=objectName;
|
||||||
parsedTilesetInfo.objects[objectName].AddTile(parsedTilesetInfo,previousTagID);
|
parsedTilesetInfo.objects[objectName].AddTile(parsedTilesetInfo,previousTagID);
|
||||||
parsedTilesetInfo.objects[objectName].perspectiveObj=nextObjType==PERSPECTIVEOBJECT;
|
parsedTilesetInfo.objects[objectName].perspectiveObj=nextObjType==PERSPECTIVEOBJECT;
|
||||||
}
|
}
|
||||||
@ -170,6 +167,11 @@ class TSXParser{
|
|||||||
findComma=!findComma;
|
findComma=!findComma;
|
||||||
}
|
}
|
||||||
if(pointCount<3)ERR("WARNING! Trying to parse a shape that has less than 4 sides!");
|
if(pointCount<3)ERR("WARNING! Trying to parse a shape that has less than 4 sides!");
|
||||||
|
|
||||||
|
for(vf2d&point:collisionQuad){ //Reposition the bounds so they are at the correct location.
|
||||||
|
point+=parsedTilesetInfo.objects[currentObj].bounds.pos;
|
||||||
|
}
|
||||||
|
|
||||||
parsedTilesetInfo.objects[currentObj].collisionTiles.push_back(collisionQuad);
|
parsedTilesetInfo.objects[currentObj].collisionTiles.push_back(collisionQuad);
|
||||||
}else
|
}else
|
||||||
if (newTag.tag=="tile"){
|
if (newTag.tag=="tile"){
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -76,3 +76,31 @@ void TilesetObject::AddTile(const Tileset&tileset,int tileID){
|
|||||||
this->upperLeftTileId=upperLeftTileId;
|
this->upperLeftTileId=upperLeftTileId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<int,std::string>>TilesetObject::OutputTag(const Tileset&activeTileset)const{
|
||||||
|
std::vector<std::pair<int,std::string>>tileID_tileStr;
|
||||||
|
|
||||||
|
for(int y=bounds.pos.y;y<bounds.bottom().end.y;y+=activeTileset.tileheight){
|
||||||
|
for(int x=bounds.pos.x;x<bounds.right().end.x;x+=activeTileset.tilewidth){
|
||||||
|
std::string finalStr="";
|
||||||
|
int tileID=(y/activeTileset.tileheight)*activeTileset.columns+(x/activeTileset.tilewidth);
|
||||||
|
finalStr+=std::format("<tile id=\"{}\" type=\"{}\">",tileID,perspectiveObj?"PerspectiveObject":"Object")+"\n";
|
||||||
|
finalStr+="<properties>\n";
|
||||||
|
finalStr+=std::format("<property name=\"Name\" value=\"{}\"/>",name)+"\n";
|
||||||
|
finalStr+="</properties>\n";
|
||||||
|
if(tileID==upperLeftTileId){ //Only the upper left tile will store the collision.
|
||||||
|
finalStr+="<objectgroup draworder=\"index\" id=\"1\">\n";
|
||||||
|
for(int id=1;const Quadrilateral&quad:collisionTiles){
|
||||||
|
finalStr+=std::format("<object id=\"{}\" x=\"0\" y=\"0\">",id)+"\n";
|
||||||
|
finalStr+=std::format("<polygon points=\"{},{} {},{} {},{} {},{}\"/>",quad[0].x-bounds.pos.x,quad[0].y-bounds.pos.y,quad[1].x-bounds.pos.x,quad[1].y-bounds.pos.y,quad[2].x-bounds.pos.x,quad[2].y-bounds.pos.y,quad[3].x-bounds.pos.x,quad[3].y-bounds.pos.y)+"\n";
|
||||||
|
finalStr+="</object>\n";
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
finalStr+="</objectgroup>\n";
|
||||||
|
}
|
||||||
|
finalStr+="</tile>\n";
|
||||||
|
tileID_tileStr.push_back({tileID,finalStr});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tileID_tileStr;
|
||||||
|
}
|
@ -52,4 +52,5 @@ public:
|
|||||||
geom2d::rect<int>bounds;
|
geom2d::rect<int>bounds;
|
||||||
std::vector<Quadrilateral>collisionTiles;
|
std::vector<Quadrilateral>collisionTiles;
|
||||||
void AddTile(const Tileset&tileset,int tileID);
|
void AddTile(const Tileset&tileset,int tileID);
|
||||||
|
std::vector<std::pair<int,std::string>>OutputTag(const Tileset&activeTileset)const;
|
||||||
};
|
};
|
@ -49,20 +49,20 @@ std::string XMLTag::str(){
|
|||||||
return tag+"\n";
|
return tag+"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
int XMLTag::GetInteger(std::string dataTag){
|
int XMLTag::GetInteger(std::string dataTag)const{
|
||||||
return std::stoi(data[dataTag]);
|
return std::stoi(data.at(dataTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
float XMLTag::GetFloat(std::string dataTag){
|
float XMLTag::GetFloat(std::string dataTag)const{
|
||||||
return std::stof(data[dataTag]);
|
return std::stof(data.at(dataTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
double XMLTag::GetDouble(std::string dataTag){
|
double XMLTag::GetDouble(std::string dataTag)const{
|
||||||
return std::stod(data[dataTag]);
|
return std::stod(data.at(dataTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XMLTag::GetBool(std::string dataTag){
|
bool XMLTag::GetBool(std::string dataTag)const{
|
||||||
if (data[dataTag]=="0"||data[dataTag]=="false") {
|
if (data.at(dataTag)=="0"||data.at(dataTag)=="false") {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
@ -73,12 +73,23 @@ std::string XMLTag::GetString(std::string dataTag){
|
|||||||
return data[dataTag];
|
return data[dataTag];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string XMLTag::OutputTag(std::string ending){
|
std::string XMLTag::OutputTag(std::string ending)const{
|
||||||
std::string finalStr{"<"};
|
std::string finalStr{"<"};
|
||||||
finalStr+=tag+" ";
|
finalStr+=tag+" ";
|
||||||
for(auto&[name,value]:data){
|
for(auto&[name,value]:data){
|
||||||
finalStr+=name+"=\""+value+"\"";
|
finalStr+=name+"=\""+value+"\" ";
|
||||||
}
|
}
|
||||||
finalStr+=ending;
|
finalStr+=ending;
|
||||||
return finalStr;
|
return finalStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<int,std::string>NonObject::OutputTag()const{
|
||||||
|
std::string finalStr;
|
||||||
|
finalStr+=tags[0].OutputTag()+"\n";
|
||||||
|
finalStr+="<properties>\n";
|
||||||
|
for(int i=1;i<tags.size();i++){
|
||||||
|
finalStr+=tags[i].OutputTag()+"\n";
|
||||||
|
}
|
||||||
|
finalStr+="</properties>\n";
|
||||||
|
return {tags[0].GetInteger("id"),finalStr};
|
||||||
|
}
|
@ -38,6 +38,7 @@ All rights reserved.
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct XMLTag{
|
struct XMLTag{
|
||||||
std::string tag;
|
std::string tag;
|
||||||
@ -45,10 +46,18 @@ struct XMLTag{
|
|||||||
const std::string FormatTagData(std::map<std::string,std::string>tiles);
|
const std::string FormatTagData(std::map<std::string,std::string>tiles);
|
||||||
friend std::ostream& operator << (std::ostream& os, XMLTag& rhs);
|
friend std::ostream& operator << (std::ostream& os, XMLTag& rhs);
|
||||||
std::string str();
|
std::string str();
|
||||||
int GetInteger(std::string dataTag);
|
int GetInteger(std::string dataTag)const;
|
||||||
float GetFloat(std::string dataTag);
|
float GetFloat(std::string dataTag)const;
|
||||||
double GetDouble(std::string dataTag);
|
double GetDouble(std::string dataTag)const;
|
||||||
bool GetBool(std::string dataTag);
|
bool GetBool(std::string dataTag)const;
|
||||||
std::string GetString(std::string dataTag);
|
std::string GetString(std::string dataTag);
|
||||||
std::string OutputTag(std::string ending=">");
|
std::string OutputTag(std::string ending=">")const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class NonObject{
|
||||||
|
public:
|
||||||
|
std::vector<XMLTag>tags;
|
||||||
|
std::pair<int,std::string>OutputTag()const;
|
||||||
};
|
};
|
@ -3,6 +3,7 @@
|
|||||||
#include "olcPGEX_TransformedView.h"
|
#include "olcPGEX_TransformedView.h"
|
||||||
#include "olcUTIL_Camera2D.h"
|
#include "olcUTIL_Camera2D.h"
|
||||||
#include "olcPGEX_QuickGUI.h"
|
#include "olcPGEX_QuickGUI.h"
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
using namespace olc;
|
using namespace olc;
|
||||||
using namespace olc::utils;
|
using namespace olc::utils;
|
||||||
@ -78,12 +79,50 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SaveFile(){
|
void SaveFile(){
|
||||||
std::ofstream file{activeTileset};
|
std::stringstream file;
|
||||||
if(file.good()){
|
if(file.good()){
|
||||||
|
const std::vector<XMLTag>originalData=parsedMap.originalData;
|
||||||
|
const std::vector<NonObject>nonObjects=parsedMap.nonObjects;
|
||||||
|
auto xmlTag=std::find_if(originalData.begin(),originalData.end(),[](const XMLTag tag){return tag.tag=="?xml";});
|
||||||
|
file<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<std::endl;
|
||||||
|
|
||||||
|
const Tileset&activeSet=tilesets.at(activeTileset);
|
||||||
|
file<<std::format("<tileset name=\"{}\" tilewidth=\"{}\" tileheight=\"{}\" tilecount=\"{}\" columns=\"{}\">",
|
||||||
|
activeSet.name,activeSet.tilewidth,activeSet.tileheight,(activeSet.imagewidth/activeSet.tilewidth)*(activeSet.imageheight/activeSet.tileheight),activeSet.columns)<<std::endl;
|
||||||
|
|
||||||
|
auto transformationsTag=std::find_if(originalData.begin(),originalData.end(),[](const XMLTag tag){return tag.tag=="transformations";});
|
||||||
|
file<<(*transformationsTag).OutputTag("/>")<<std::endl;
|
||||||
|
|
||||||
|
file<<std::format("<image source=\"{}\" width=\"{}\" height=\"{}\"/>",
|
||||||
|
activeSet.filename,activeSet.imagewidth,activeSet.imageheight)<<std::endl;
|
||||||
|
|
||||||
|
std::vector<std::pair<int,std::string>>tiles;
|
||||||
|
|
||||||
|
for(auto&[name,obj]:activeSet.objects){
|
||||||
|
const std::vector<std::pair<int,std::string>>objTiles{obj.OutputTag(activeSet)};
|
||||||
|
tiles.insert(tiles.end(),objTiles.begin(),objTiles.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const NonObject&obj:nonObjects){
|
||||||
|
tiles.push_back(obj.OutputTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(tiles.begin(),tiles.end(),[](const std::pair<int,std::string>tileData1,const std::pair<int,std::string>tileData2){
|
||||||
|
return tileData1.first<tileData2.first;
|
||||||
|
});
|
||||||
|
|
||||||
|
for(auto&[tileID,str]:tiles){
|
||||||
|
file<<str<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
file<<"</tileset>"<<std::endl;
|
||||||
}else{
|
}else{
|
||||||
std::cout<<"WARNING! File not available for saving! Failed to save!"<<std::endl;
|
std::cout<<"WARNING! File not available for saving! Failed to save!"<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ofstream saveFile{activeTileset};
|
||||||
|
saveFile<<file.str()<<std::endl;
|
||||||
|
saveFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(){
|
void Update(){
|
||||||
@ -186,6 +225,10 @@ public:
|
|||||||
if(GetMouse(Mouse::RIGHT).bPressed&&!EditingQuad&&!dragTranslate){
|
if(GetMouse(Mouse::RIGHT).bPressed&&!EditingQuad&&!dragTranslate){
|
||||||
if(highlightedQuad!=nullptr){
|
if(highlightedQuad!=nullptr){
|
||||||
std::erase_if(tilesets[activeTileset].objects[selectedObj].collisionTiles,[&](Quadrilateral&q){return &q==highlightedQuad;});
|
std::erase_if(tilesets[activeTileset].objects[selectedObj].collisionTiles,[&](Quadrilateral&q){return &q==highlightedQuad;});
|
||||||
|
editingPoint=4;
|
||||||
|
dragging=false;
|
||||||
|
editingQuad=nullptr;
|
||||||
|
dragTranslate=false;
|
||||||
SaveFile();
|
SaveFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user