generated from sigonasr2/CPlusPlusProjectTemplate
Added ability to create new objects, delete objects, and delete/move collision ranges without changing targets until mouse leaves a previous collisoin target.
This commit is contained in:
parent
2fe116efa7
commit
5255502945
@ -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,35 +127,24 @@ public:
|
|||||||
}
|
}
|
||||||
if(editButton->bChecked){
|
if(editButton->bChecked){
|
||||||
if(GetMouse(Mouse::LEFT).bPressed){
|
if(GetMouse(Mouse::LEFT).bPressed){
|
||||||
#pragma region Select a point on a collision quad.
|
if(highlightedQuad!=nullptr){
|
||||||
for(const Quadrilateral&quad:obj.collisionTiles){
|
#pragma region Select a point on a collision quad.
|
||||||
for(size_t pointInd=0;const vf2d&point:quad){
|
for(size_t pointInd=0;const vf2d&point:*highlightedQuad){
|
||||||
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=highlightedQuad;
|
||||||
editingQuad=const_cast<Quadrilateral*>(&quad);
|
originalQuad=*highlightedQuad;
|
||||||
originalQuad=quad;
|
|
||||||
}
|
|
||||||
goto exitCollisionCheck;
|
goto exitCollisionCheck;
|
||||||
}
|
}
|
||||||
pointInd++;
|
pointInd++;
|
||||||
}
|
}
|
||||||
}
|
#pragma endregion
|
||||||
#pragma endregion
|
|
||||||
for(const Quadrilateral&quad:obj.collisionTiles){
|
dragTranslate=true;
|
||||||
std::array<geom2d::triangle<float>,2>collisionTris{
|
editingQuad=highlightedQuad;
|
||||||
geom2d::triangle<float>{quad[0],quad[1],quad[2]},
|
upperLeftDragOffset=GetSnapPoint()-(*highlightedQuad)[0];
|
||||||
geom2d::triangle<float>{quad[0],quad[2],quad[3]},
|
originalQuad=*editingQuad;
|
||||||
};
|
goto exitCollisionCheck;
|
||||||
for(geom2d::triangle<float>&tri:collisionTris){
|
|
||||||
if(geom2d::overlaps(tri,geom2d::circle<float>(view.ScreenToWorld(GetMousePos()),3.f))){
|
|
||||||
dragTranslate=true;
|
|
||||||
editingQuad=const_cast<Quadrilateral*>(&quad);
|
|
||||||
upperLeftDragOffset=GetSnapPoint()-quad[0];
|
|
||||||
originalQuad=*editingQuad;
|
|
||||||
goto exitCollisionCheck;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
exitCollisionCheck:
|
exitCollisionCheck:
|
||||||
if(EditingQuad&&!dragging){
|
if(EditingQuad&&!dragging){
|
||||||
@ -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,18 +307,30 @@ 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){
|
||||||
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>{(*highlightedQuad)[0],(*highlightedQuad)[1],(*highlightedQuad)[2]},
|
||||||
geom2d::triangle<float>{quad[0],quad[2],quad[3]},
|
geom2d::triangle<float>{(*highlightedQuad)[0],(*highlightedQuad)[2],(*highlightedQuad)[3]},
|
||||||
};
|
};
|
||||||
for(geom2d::triangle<float>&tri:collisionTris){
|
for(geom2d::triangle<float>&tri:collisionTris){
|
||||||
if(geom2d::overlaps(tri,geom2d::circle<float>(view.ScreenToWorld(GetMousePos()),3.f))){
|
if(geom2d::overlaps(tri,geom2d::circle<float>(view.ScreenToWorld(GetMousePos()),3.f))){
|
||||||
highlightedQuad=const_cast<Quadrilateral*>(&quad);
|
|
||||||
goto renderQuads;
|
goto renderQuads;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
highlightedQuad=nullptr;
|
||||||
|
}else{
|
||||||
|
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))){
|
||||||
|
highlightedQuad=const_cast<Quadrilateral*>(&quad);
|
||||||
|
goto renderQuads;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
renderQuads:
|
renderQuads:
|
||||||
for(const Quadrilateral&quad:obj.collisionTiles){
|
for(const Quadrilateral&quad:obj.collisionTiles){
|
||||||
@ -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…
x
Reference in New Issue
Block a user