Added ability to create new objects, delete objects, and delete/move collision ranges without changing targets until mouse leaves a previous collisoin target.

master
sigonasr2 9 months ago
parent 2fe116efa7
commit 5255502945
  1. 126
      TiledCollisionEditor/main.cpp
  2. 2
      TiledCollisionEditor/olcPGEX_QuickGUI.h

@ -22,9 +22,11 @@ class TiledCollisionEditor : public olc::PixelGameEngine
bool dragging=false; bool dragging=false;
bool dragTranslate=false; bool dragTranslate=false;
vf2d upperLeftDragOffset{}; vf2d upperLeftDragOffset{};
Quadrilateral*highlightedQuad=nullptr;
bool dragNewObj=false; bool dragNewObj=false;
vi2d upperLeftObjTile{}; vi2d upperLeftObjTile{};
vi2d lowerRightObjTile{};
Renderable circle; Renderable circle;
Renderable createNewButtonImg; Renderable createNewButtonImg;
@ -70,6 +72,7 @@ public:
createNewButton->hotkey=Q; createNewButton->hotkey=Q;
editButton=new ImageCheckBox{gui,editButtonImg,true,vf2d{40.f,ScreenHeight()-36.f},{32.f,32.f},{4,4},{32,32}}; editButton=new ImageCheckBox{gui,editButtonImg,true,vf2d{40.f,ScreenHeight()-36.f},{32.f,32.f},{4,4},{32,32}};
editButton->hotkey=E; editButton->hotkey=E;
return true; return true;
} }
@ -77,6 +80,13 @@ public:
const Tileset&tileset=tilesets[activeTileset]; const Tileset&tileset=tilesets[activeTileset];
if(selectedObj.length()>0){ if(selectedObj.length()>0){
if(GetKey(DEL).bPressed){
tilesets[activeTileset].objects.erase(selectedObj);
selectedObj="";
return;
}
for(int y=0;y<tileset.tilecount/tileset.columns;y++){ for(int y=0;y<tileset.tilecount/tileset.columns;y++){
for(int x=0;x<tileset.columns;x++){ for(int x=0;x<tileset.columns;x++){
if(!geom2d::contains(tileset.objects.at(selectedObj).bounds,vf2d{float(x*tileset.tilewidth)+tileset.tilewidth/2,float(y*tileset.tileheight)+tileset.tileheight/2})){ if(!geom2d::contains(tileset.objects.at(selectedObj).bounds,vf2d{float(x*tileset.tilewidth)+tileset.tilewidth/2,float(y*tileset.tileheight)+tileset.tileheight/2})){
@ -117,36 +127,25 @@ public:
} }
if(editButton->bChecked){ if(editButton->bChecked){
if(GetMouse(Mouse::LEFT).bPressed){ if(GetMouse(Mouse::LEFT).bPressed){
if(highlightedQuad!=nullptr){
#pragma region Select a point on a collision quad. #pragma region Select a point on a collision quad.
for(const Quadrilateral&quad:obj.collisionTiles){ for(size_t pointInd=0;const vf2d&point:*highlightedQuad){
for(size_t pointInd=0;const vf2d&point:quad){
if(geom2d::line<float>(point,view.ScreenToWorld(GetMousePos())).length()<4){ if(geom2d::line<float>(point,view.ScreenToWorld(GetMousePos())).length()<4){
if(GetMouse(Mouse::LEFT).bPressed){
editingPoint=pointInd; editingPoint=pointInd;
editingQuad=const_cast<Quadrilateral*>(&quad); editingQuad=highlightedQuad;
originalQuad=quad; originalQuad=*highlightedQuad;
}
goto exitCollisionCheck; goto exitCollisionCheck;
} }
pointInd++; pointInd++;
} }
}
#pragma endregion #pragma endregion
for(const Quadrilateral&quad:obj.collisionTiles){
std::array<geom2d::triangle<float>,2>collisionTris{
geom2d::triangle<float>{quad[0],quad[1],quad[2]},
geom2d::triangle<float>{quad[0],quad[2],quad[3]},
};
for(geom2d::triangle<float>&tri:collisionTris){
if(geom2d::overlaps(tri,geom2d::circle<float>(view.ScreenToWorld(GetMousePos()),3.f))){
dragTranslate=true; dragTranslate=true;
editingQuad=const_cast<Quadrilateral*>(&quad); editingQuad=highlightedQuad;
upperLeftDragOffset=GetSnapPoint()-quad[0]; upperLeftDragOffset=GetSnapPoint()-(*highlightedQuad)[0];
originalQuad=*editingQuad; originalQuad=*editingQuad;
goto exitCollisionCheck; goto exitCollisionCheck;
} }
}
}
exitCollisionCheck: exitCollisionCheck:
if(EditingQuad&&!dragging){ if(EditingQuad&&!dragging){
(*editingQuad)[editingPoint]=GetSnapPoint(); (*editingQuad)[editingPoint]=GetSnapPoint();
@ -174,23 +173,8 @@ public:
} }
if(GetMouse(Mouse::RIGHT).bPressed&&!EditingQuad&&!dragTranslate){ if(GetMouse(Mouse::RIGHT).bPressed&&!EditingQuad&&!dragTranslate){
std::vector<Quadrilateral*>quadsToBeRemoved; if(highlightedQuad!=nullptr){
for(const Quadrilateral&quad:obj.collisionTiles){ std::erase_if(tilesets[activeTileset].objects[selectedObj].collisionTiles,[&](Quadrilateral&q){return &q==highlightedQuad;});
std::array<geom2d::triangle<float>,2>collisionTris{
geom2d::triangle<float>{quad[0],quad[1],quad[2]},
geom2d::triangle<float>{quad[0],quad[2],quad[3]},
};
for(geom2d::triangle<float>&tri:collisionTris){
if(geom2d::overlaps(tri,geom2d::circle<float>(view.ScreenToWorld(GetMousePos()),3.f))){
//Delete this quad, the mouse is overlapping it!
quadsToBeRemoved.push_back(const_cast<Quadrilateral*>(&quad));
break;
}
}
}
for(Quadrilateral*quad:quadsToBeRemoved){
std::erase_if(tilesets[activeTileset].objects[selectedObj].collisionTiles,[&](Quadrilateral&q){return &q==quad;});
} }
} }
@ -215,18 +199,26 @@ public:
void NewObjectUpdate(){ void NewObjectUpdate(){
const Tileset&tileset=tilesets[activeTileset]; const Tileset&tileset=tilesets[activeTileset];
if(GetMouse(Mouse::LEFT).bPressed){
vf2d worldCoords=view.ScreenToWorld(GetMousePos());
upperLeftObjTile=vi2d{int(round(worldCoords.x/tileset.tilewidth)*tileset.tilewidth),int(round(worldCoords.y/tileset.tileheight)*tileset.tileheight)};
dragNewObj=true;
}
if(GetMouse(Mouse::LEFT).bReleased){ if(GetMouse(Mouse::LEFT).bReleased){
dragNewObj=false; dragNewObj=false;
vf2d worldCoords=view.ScreenToWorld(GetMousePos()); vf2d worldCoords=view.ScreenToWorld(GetMousePos());
vi2d lowerRightObjTile=vi2d{int(round(worldCoords.x/tileset.tilewidth)*tileset.tilewidth),int(round(worldCoords.y/tileset.tileheight)*tileset.tileheight)}; vi2d newUpperLeftTile=upperLeftObjTile;
vi2d newLowerRightTile=lowerRightObjTile;
geom2d::rect<int>newObjRect{upperLeftObjTile,lowerRightObjTile-upperLeftObjTile}; if(worldCoords.x<upperLeftObjTile.x){
newLowerRightTile.x=int(floor(worldCoords.x/tileset.tilewidth)*tileset.tilewidth);
std::swap(newUpperLeftTile.x,newLowerRightTile.x);
}
if(worldCoords.y<upperLeftObjTile.y){
newLowerRightTile.y=int(floor(worldCoords.y/tileset.tileheight)*tileset.tileheight);
std::swap(newUpperLeftTile.y,newLowerRightTile.y);
}
if(newLowerRightTile.x==newUpperLeftTile.x)newLowerRightTile.x+=tileset.tilewidth;
if(newLowerRightTile.y==newUpperLeftTile.y)newLowerRightTile.y+=tileset.tileheight;
geom2d::rect<int>newObjRect{newUpperLeftTile,newLowerRightTile-newUpperLeftTile};
const Tileset&tileset=tilesets[activeTileset]; const Tileset&tileset=tilesets[activeTileset];
//Check for intersection with other objects, if found then we deny creating this object this way. //Check for intersection with other objects, if found then we deny creating this object this way.
@ -244,10 +236,10 @@ public:
TilesetObject&newObj=tilesets[activeTileset].objects[objName]; TilesetObject&newObj=tilesets[activeTileset].objects[objName];
newObj.name=objName; newObj.name=objName;
for(int y=0;y<newObjRect.size.y;y++){ for(int y=0;y<newObjRect.size.y/tileset.tileheight;y++){
for(int x=0;x<newObjRect.size.x;x++){ for(int x=0;x<newObjRect.size.x/tileset.tilewidth;x++){
int tileX=upperLeftObjTile.x/tileset.tilewidth+x; int tileX=newUpperLeftTile.x/tileset.tilewidth+x;
int tileY=upperLeftObjTile.y/tileset.tileheight+y; int tileY=newUpperLeftTile.y/tileset.tileheight+y;
int tileID=tileY*tileset.columns+tileX; int tileID=tileY*tileset.columns+tileX;
newObj.AddTile(tileset,tileID); newObj.AddTile(tileset,tileID);
} }
@ -292,6 +284,13 @@ public:
if(editButton->bPressed)createNewButton->bChecked=false; if(editButton->bPressed)createNewButton->bChecked=false;
if(GetMouseY()<ScreenHeight()-36||GetMouseX()>72){ if(GetMouseY()<ScreenHeight()-36||GetMouseX()>72){
if(selectedObj.length()==0){
if(GetMouse(Mouse::LEFT).bPressed){
vf2d worldCoords=view.ScreenToWorld(GetMousePos());
upperLeftObjTile=vi2d{int(floor(worldCoords.x/tileset.tilewidth)*tileset.tilewidth),int(floor(worldCoords.y/tileset.tileheight)*tileset.tileheight)};
dragNewObj=true;
}
}
if(!dragNewObj){ if(!dragNewObj){
Update(); Update();
}else{ }else{
@ -308,7 +307,18 @@ public:
if(selectedObj.length()>0&&!dragNewObj){ if(selectedObj.length()>0&&!dragNewObj){
const TilesetObject&obj=tileset.objects.at(selectedObj); const TilesetObject&obj=tileset.objects.at(selectedObj);
Quadrilateral*highlightedQuad=nullptr; if(highlightedQuad!=nullptr){
std::array<geom2d::triangle<float>,2>collisionTris{
geom2d::triangle<float>{(*highlightedQuad)[0],(*highlightedQuad)[1],(*highlightedQuad)[2]},
geom2d::triangle<float>{(*highlightedQuad)[0],(*highlightedQuad)[2],(*highlightedQuad)[3]},
};
for(geom2d::triangle<float>&tri:collisionTris){
if(geom2d::overlaps(tri,geom2d::circle<float>(view.ScreenToWorld(GetMousePos()),3.f))){
goto renderQuads;
}
}
highlightedQuad=nullptr;
}else{
for(const Quadrilateral&quad:obj.collisionTiles){ for(const Quadrilateral&quad:obj.collisionTiles){
std::array<geom2d::triangle<float>,2>collisionTris{ std::array<geom2d::triangle<float>,2>collisionTris{
geom2d::triangle<float>{quad[0],quad[1],quad[2]}, geom2d::triangle<float>{quad[0],quad[1],quad[2]},
@ -321,6 +331,7 @@ public:
} }
} }
} }
}
renderQuads: renderQuads:
for(const Quadrilateral&quad:obj.collisionTiles){ for(const Quadrilateral&quad:obj.collisionTiles){
std::vector<vf2d>points; std::vector<vf2d>points;
@ -347,11 +358,26 @@ public:
}else }else
if(dragNewObj){ if(dragNewObj){
vf2d worldCoords=view.ScreenToWorld(GetMousePos()); vf2d worldCoords=view.ScreenToWorld(GetMousePos());
vi2d lowerRightObjTile=vi2d{int(round(worldCoords.x/tileset.tilewidth)*tileset.tilewidth),int(round(worldCoords.y/tileset.tileheight)*tileset.tileheight)}; lowerRightObjTile=vi2d{int(ceil(worldCoords.x/tileset.tilewidth)*tileset.tilewidth),int(ceil(worldCoords.y/tileset.tileheight)*tileset.tileheight)};
vi2d newUpperLeftTile=upperLeftObjTile;
vi2d newLowerRightTile=lowerRightObjTile;
if(worldCoords.x<upperLeftObjTile.x){
newLowerRightTile.x=int(floor(worldCoords.x/tileset.tilewidth)*tileset.tilewidth);
std::swap(newUpperLeftTile.x,newLowerRightTile.x);
}
if(worldCoords.y<upperLeftObjTile.y){
newLowerRightTile.y=int(floor(worldCoords.y/tileset.tileheight)*tileset.tileheight);
std::swap(newUpperLeftTile.y,newLowerRightTile.y);
}
if(newLowerRightTile.x==newUpperLeftTile.x)newLowerRightTile.x+=tileset.tilewidth;
if(newLowerRightTile.y==newUpperLeftTile.y)newLowerRightTile.y+=tileset.tileheight;
Pixel overlayCol={0,0,255,160}; Pixel overlayCol={0,0,255,160};
geom2d::rect<int>newObjRect{upperLeftObjTile,lowerRightObjTile-upperLeftObjTile}; geom2d::rect<int>newObjRect{newUpperLeftTile,newLowerRightTile-newUpperLeftTile};
for(auto&[name,obj]:tileset.objects){ for(auto&[name,obj]:tileset.objects){
geom2d::rect<float>offsetBounds{obj.bounds.pos+vf2d{0.5f,0.5f},obj.bounds.size-vf2d{1.f,1.f}}; geom2d::rect<float>offsetBounds{obj.bounds.pos+vf2d{0.5f,0.5f},obj.bounds.size-vf2d{1.f,1.f}};
@ -361,7 +387,7 @@ public:
} }
} }
view.FillRectDecal(upperLeftObjTile,lowerRightObjTile-upperLeftObjTile,overlayCol); view.FillRectDecal(newObjRect.pos,newObjRect.size,overlayCol);
} }
for(auto&[objName,obj]:tileset.objects){ for(auto&[objName,obj]:tileset.objects){

@ -1029,6 +1029,8 @@ namespace olc::QuickGUI
bHeld = false; bHeld = false;
} }
if(fMax<fMin)std::swap(fMax,fMin);
fValue = std::clamp(fValue, fMin, fMax); fValue = std::clamp(fValue, fMin, fMax);
m_fTransition = std::clamp(m_fTransition, 0.0f, 1.0f); m_fTransition = std::clamp(m_fTransition, 0.0f, 1.0f);
} }

Loading…
Cancel
Save