geom2D-Update #29

Merged
sigonasr2 merged 4 commits from geom2D-Update into master 11 months ago
  1. 69
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 4
      Adventures in Lestoria/AdventuresInLestoria.h
  3. 6
      Adventures in Lestoria/Map.h
  4. 28
      Adventures in Lestoria/Monster.cpp
  5. 48
      Adventures in Lestoria/Pathfinding.cpp
  6. 2
      Adventures in Lestoria/Pathfinding.h
  7. 4
      Adventures in Lestoria/Player.cpp
  8. 4
      Adventures in Lestoria/TSXParser.h
  9. 2
      Adventures in Lestoria/Version.h
  10. 3
      Adventures in Lestoria/assets/config/configuration.txt
  11. 2
      Adventures in Lestoria/assets/maps/Decorations_c1_No_Shadow24x24.tsx
  12. 4
      Adventures in Lestoria/olcPGEX_TransformedView.h
  13. 19
      Adventures in Lestoria/olcPixelGameEngine.h
  14. BIN
      x64/Release/Adventures in Lestoria.exe

@ -802,8 +802,8 @@ void AiL::RenderWorld(float fElapsedTime){
count++;
}
if(player->teleportAnimationTimer>0){
playerScale.x=120*float(abs(pow(player->teleportAnimationTimer-0.175f,3)));
pos=player->teleportStartPosition.lerp(player->teleportTarget,(0.35f-player->teleportAnimationTimer)/0.35f);
playerScale.x=120*float(abs(pow(player->teleportAnimationTimer-"Wizard.Right Click Ability.AnimationTime"_F/2,3)));
pos=player->teleportStartPosition.lerp(player->teleportTarget,("Wizard.Right Click Ability.AnimationTime"_F-player->teleportAnimationTimer)/"Wizard.Right Click Ability.AnimationTime"_F);
}
const std::vector<Buff>attackBuffs=player->GetStatBuffs({"Attack","Attack %"});
view.DrawPartialRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale,attackBuffs.size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*attackBuffs[0].duration))),uint8_t(255*abs(sin(1.4*attackBuffs[0].duration)))}:WHITE);
@ -898,9 +898,9 @@ void AiL::RenderWorld(float fElapsedTime){
#ifdef _DEBUG
if("debug_collision_boxes"_I){
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
view.FillRectDecal(vi2d{x,y}*GetCurrentMapData().tilewidth+collision.pos,collision.size,{0,0,0,128});
view.DrawRectDecal(vi2d{x,y}*GetCurrentMapData().tilewidth+collision.pos,collision.size,GREY);
geom2d::rect<float>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
view.FillRectDecal(vf2d{float(x),float(y)}*float(GetCurrentMapData().tilewidth)+collision.pos,collision.size,{0,0,0,128});
view.DrawRectDecal(vf2d{float(x),float(y)}*float(GetCurrentMapData().tilewidth)+collision.pos,collision.size,GREY);
}
}
#endif
@ -926,9 +926,9 @@ void AiL::RenderWorld(float fElapsedTime){
#ifdef _DEBUG
if("debug_collision_boxes"_I){
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
view.FillRectDecal(vi2d{x,y}*GetCurrentMapData().tilewidth+collision.pos,collision.size,{0,0,0,128});
view.DrawRectDecal(vi2d{x,y}*GetCurrentMapData().tilewidth+collision.pos,collision.size,GREY);
geom2d::rect<float>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
view.FillRectDecal(vf2d{float(x),float(y)}*float(GetCurrentMapData().tilewidth)+collision.pos,collision.size,{0,0,0,128});
view.DrawRectDecal(vf2d{float(x),float(y)}*float(GetCurrentMapData().tilewidth)+collision.pos,collision.size,GREY);
}
}
#endif
@ -948,6 +948,17 @@ void AiL::RenderWorld(float fElapsedTime){
}
}break;
}
for(int y2=0;y2<2;y2++){
for(int x2=0;x2<2;x2++){
vf2d tilePos=vf2d{float(x),float(y)}*24;
vf2d gridPos=tilePos+pathfinder.gridSpacing*vf2d{float(x2),float(y2)};
Pixel col=RED;
if(!pathfinder.nodes[gridPos].bObstacle&&!pathfinder.nodes[gridPos].bObstacleUpper){
col=GREEN;
}
view.FillRectDecal(gridPos,pathfinder.gridSpacing,{col.r,col.g,col.b,128});
}
}
}else{
if(GetCurrentMap().backdrop.length()>0){
vf2d tileWorldPos=vi2d{x,y}*GetCurrentMapData().tilewidth;
@ -1067,11 +1078,19 @@ void AiL::RenderWorld(float fElapsedTime){
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
geom2d::rect<float>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
distToPlayer/=4;
if(distToPlayer<1){distToPlayer=1;}
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
#ifdef _DEBUG
if("debug_collision_boxes_snapping"_I){
if(fmod(tile->pos.x+collision.pos.x,1.f)!=0.f||fmod(tile->pos.y+collision.pos.y,1.f)!=0.f){
view.DrawShadowStringPropDecal(tile->pos+collision.pos-vf2d{0,24},(tile->pos+collision.pos).str(),RED,BLACK,{0.5f,1.f},24.f);
view.DrawShadowStringPropDecal(tile->pos+collision.pos+vf2d{0,24},((tile->pos+collision.pos)+(collision.size)).str(),GREEN,BLACK,{0.5f,1.f},24.f);
}
}
#endif
}
}
#pragma endregion
@ -1092,11 +1111,19 @@ void AiL::RenderWorld(float fElapsedTime){
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
geom2d::rect<float>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
distToPlayer/=4;
if(distToPlayer<1){distToPlayer=1;}
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))});
#ifdef _DEBUG
if("debug_collision_boxes_snapping"_I){
if(fmod(tile->pos.x+collision.pos.x,1.f)!=0.f||fmod(tile->pos.y+collision.pos.y,1.f)!=0.f){
view.DrawShadowStringPropDecal(tile->pos+collision.pos-vf2d{0,24},(tile->pos+collision.pos).str(),RED,BLACK,{0.5f,1.f},24.f);
view.DrawShadowStringPropDecal(tile->pos+collision.pos+vf2d{0,24},((tile->pos+collision.pos)+(collision.size)).str(),GREEN,BLACK,{0.5f,1.f},24.f);
}
}
#endif
}
}
#pragma endregion
@ -1124,9 +1151,9 @@ void AiL::RenderWorld(float fElapsedTime){
#ifdef _DEBUG
if("debug_collision_boxes"_I){
if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
view.FillRectDecal(vi2d{x,y}*game->GetCurrentMapData().tilewidth+collision.pos,collision.size,{0,0,0,128});
view.DrawRectDecal(vi2d{x,y}*game->GetCurrentMapData().tilewidth+collision.pos,collision.size,GREY);
geom2d::rect<float>collision=tileSheet.tileset->collision[tileSheetIndex].collision;
view.FillRectDecal(vf2d{float(x),float(y)}*float(game->GetCurrentMapData().tilewidth)+collision.pos,collision.size,{0,0,0,128});
view.DrawRectDecal(vf2d{float(x),float(y)}*float(game->GetCurrentMapData().tilewidth)+collision.pos,collision.size,GREY);
}
}
#endif
@ -1210,7 +1237,7 @@ void AiL::RenderWorld(float fElapsedTime){
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
geom2d::rect<float>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
distToPlayer/=4;
if(distToPlayer<1){distToPlayer=1;}
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
@ -1235,7 +1262,7 @@ void AiL::RenderWorld(float fElapsedTime){
RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)});
float distToPlayer=geom2d::line<float>(player->GetPos(),tile->pos+vf2d{12,12}).length();
if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){
geom2d::rect<int>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
geom2d::rect<float>collision=tile->tileSheet.tileset->collision[tile->tileID].collision;
distToPlayer/=4;
if(distToPlayer<1){distToPlayer=1;}
view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))});
@ -1895,7 +1922,7 @@ TilesheetData AiL::GetTileSheet(MapName map,int tileID){
}
bool AiL::HasTileCollision(MapName map,vf2d pos,bool upperLevel){
geom2d::rect<int>collisionRect=GetTileCollision(map,pos,upperLevel);
geom2d::rect<float>collisionRect=GetTileCollision(map,pos,upperLevel);
vi2d collisionRectSnapPos=vi2d{pos/float(game->GetCurrentMapData().tilewidth)}*game->GetCurrentMapData().tilewidth;
collisionRect.pos+=collisionRectSnapPos;
return geom2d::overlaps(collisionRect,pos);
@ -1905,7 +1932,7 @@ bool AiL::IsBridgeLayer(LayerTag&layer){
return layer.tag.data.find("class")!=layer.tag.data.end()&&layer.tag.data["class"]=="Bridge";
}
geom2d::rect<int>AiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){
geom2d::rect<float>AiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){
if(pos.x<0||pos.y<0||pos.x>=GetCurrentMapData().width*game->GetCurrentMapData().tilewidth||pos.y>=GetCurrentMapData().height*game->GetCurrentMapData().tilewidth)return NO_COLLISION;
if(GetCurrentMap().optimizedTile)return NO_COLLISION; //Overworld map has no collision.
@ -1919,13 +1946,13 @@ geom2d::rect<int>AiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){
break;
}
}
if(!hasTerrain)return geom2d::rect<int>({0,0},{GetCurrentMapData().tilewidth,GetCurrentMapData().tilewidth}); //We assume no terrain means we can't walk on this.
if(!hasTerrain)return geom2d::rect<float>({0.f,0.f},{float(GetCurrentMapData().tilewidth),float(GetCurrentMapData().tilewidth)}); //We assume no terrain means we can't walk on this.
#pragma region Lower Bridge Collision Check
if(!upperLevel){ //We are looking for lower bridge collisions.
for(ZoneData&zone:MAP_DATA[map].ZoneData["LowerBridgeCollision"]){
if(geom2d::contains(zone.zone,pos)){
return {{0,0},{game->GetCurrentMapData().tilewidth,game->GetCurrentMapData().tilewidth}};
return {{0,0},{float(game->GetCurrentMapData().tilewidth),float(game->GetCurrentMapData().tilewidth)}};
}
}
}
@ -1940,13 +1967,13 @@ geom2d::rect<int>AiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){
return NO_COLLISION;
}
}
geom2d::rect<int>foundRect=NO_COLLISION;
geom2d::rect<float>foundRect=NO_COLLISION;
for(int counter=0;LayerTag&layer:MAP_DATA[map].LayerData){
//auto HasNoClass=[&](){return layer.tag.data.find("class")==layer.tag.data.end();};
if(counter!=bridgeLayerIndex){
int tileID=layer.tiles[int(pos.y)/GetCurrentMapData().tilewidth][int(pos.x)/GetCurrentMapData().tilewidth]-1;
if(tileID!=-1&&GetTileSheet(map,tileID%1000000).tileset->collision.find(tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1)!=GetTileSheet(map,tileID%1000000).tileset->collision.end()){
geom2d::rect<int>collisionRect=GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision;
geom2d::rect<float>collisionRect=GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision;
if(foundRect.pos==NO_COLLISION.pos&&foundRect.size==NO_COLLISION.size){
foundRect=collisionRect;
}else{

@ -133,7 +133,7 @@ public:
bool OnUserUpdate(float fElapsedTime) override;
bool OnUserDestroy() override;
public:
geom2d::rect<int>NO_COLLISION={};
geom2d::rect<float>NO_COLLISION={{0.f,0.f,},{0.f,0.f}};
TileTransformedView view;
void InitializeLevel(std::string mapFile,MapName map);
void LoadLevel(MapName map);
@ -166,7 +166,7 @@ public:
//tileID is the tile number from the tilesets.
TilesheetData GetTileSheet(MapName map,int tileID);
//Gets the rectangle of the tile collision at this tile. If upperLevel is set to true, the collision tile must be in a Bridge class layer for the tile to hit. Also, zones containing LowerBridgeCollision will apply when upperLevel is set to false.
geom2d::rect<int>GetTileCollision(MapName map,vf2d pos,bool upperLevel=false);
geom2d::rect<float>GetTileCollision(MapName map,vf2d pos,bool upperLevel=false);
//Checks if the point resides inside of a collision tile.
bool HasTileCollision(MapName map,vf2d pos,bool upperLevel=false);
const MapName&GetCurrentLevel()const;

@ -50,7 +50,7 @@ public:
};
struct TileCollisionData{
geom2d::rect<int>collision;
geom2d::rect<float>collision;
};
struct TilesetData{
@ -59,7 +59,7 @@ struct TilesetData{
bool isTerrain=false;
std::map<int,XMLTag>foregroundTiles;
std::map<int,XMLTag>upperForegroundTiles;
std::map<int,TileCollisionData>collision;
std::map<float,TileCollisionData>collision;
std::map<int,XMLTag>staircaseTiles;
std::map<int,std::vector<int>>animationData;
std::set<int>reflectiveData;
@ -75,7 +75,7 @@ struct TilesheetData{
struct TileRenderData{
TilesheetData tileSheet;
vi2d pos;
vf2d pos;
vi2d tileSheetPos;
int tileID;
int layerID;

@ -116,8 +116,8 @@ void Monster::PerformIdleAnimation(){
bool Monster::SetX(float x){
vf2d newPos={x,pos.y};
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
geom2d::rect<int>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
if(collisionRect.pos==vi2d{0,0}&&collisionRect.size==vi2d{1,1}){
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
if(collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size){
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
Moved();
return true;
@ -135,8 +135,8 @@ bool Monster::SetX(float x){
bool Monster::SetY(float y){
vf2d newPos={pos.x,y};
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
geom2d::rect<int>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
if(collisionRect.pos==vi2d{0,0}&&collisionRect.size==vi2d{1,1}){
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
if(collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size){
pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
Moved();
return true;
@ -235,6 +235,18 @@ void Monster::Draw(){
}
game->view.DrawPartialRotatedDecal(GetPos()-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),0,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*(GetFacingDirection()==RIGHT?-1:1),GetSizeMult()),GetBuffs(BuffType::SLOWDOWN).size()>0?Pixel{uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(128+127*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration)))}:WHITE);
for(float index=0.f;index<path.points.size();index+=0.01f){
Pixel col=DARK_GREY;
if(index<pathIndex){
col=VERY_DARK_GREY;
}
if(index>pathIndex+1){
col=GREY;
}
game->view.FillRectDecal(path.GetSplinePoint(index).pos,{1,1},col);
}
for(size_t counter=0;Pathfinding::sPoint2D&point:path.points){
Pixel col=CYAN;
if(counter<pathIndex){
@ -243,7 +255,7 @@ void Monster::Draw(){
if(counter>pathIndex+1){
col=YELLOW;
}
game->view.FillRectDecal(point.pos*float(game->GetCurrentMapData().tilewidth),{3,3},col);
game->view.FillRectDecal(point.pos,{3,3},col);
counter++;
}
}
@ -266,6 +278,7 @@ void Monster::Collision(Monster&m){
void Monster::Collision(){
if(strategy=="Run Towards"&&GetState()==State::MOVE_TOWARDS&&util::random(float(Monster::STRATEGY::_GetInt(*this,"BumpStopChance",strategy)))<1){//The run towards strategy causes state to return to normal upon a collision.
SetState(State::NORMAL);
targetAcquireTimer=0;
}
}
void Monster::SetVelocity(vf2d vel){
@ -423,11 +436,12 @@ void Monster::PathAroundBehavior(float fElapsedTime){
facingDirection=LEFT;
}
}else{
if(size_t(pathIndex+1)>=path.points.size()){
if(pathIndex>=path.points.size()){
//We have reached the end of the path!
pathIndex=0;
targetAcquireTimer=0;
}else{
pathIndex+=0.2f;
pathIndex+=0.5f;
}
}
} else {

@ -41,19 +41,29 @@ All rights reserved.
INCLUDE_game
const vi2d Pathfinding::gridSpacing=vf2d{12,12};
void Pathfinding::Initialize(){
nodes.clear();
sNode*lastNodeAdded=nullptr;
for (int x = 0; x < game->GetCurrentMapData().width; x+=gridSpacing.x)
for (int y = 0; y < game->GetCurrentMapData().height; y+=gridSpacing.y)
for (int x = 0; x < game->GetCurrentMapData().width*24; x+=gridSpacing.x)
for (int y = 0; y < game->GetCurrentMapData().height*24; y+=gridSpacing.y)
{
sNode&node=nodes[{x,y}];
node.x = x; // ...because we give each node its own coordinates
node.y = y; // ...because we give each node its own coordinates
geom2d::rect<int>tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x*gridSpacing.x),float(y*gridSpacing.y)});
node.bObstacle = tile.pos!=game->NO_COLLISION.pos||tile.size!=game->NO_COLLISION.size;
tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x*gridSpacing.x),float(y*gridSpacing.y)},true);
node.bObstacleUpper = tile.pos!=game->NO_COLLISION.pos||tile.size!=game->NO_COLLISION.size;
geom2d::rect<float>tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)});
if(tile.pos==game->NO_COLLISION.pos&&tile.size==game->NO_COLLISION.size){
node.bObstacle=false;
}else{
node.bObstacle=geom2d::overlaps(vf2d{fmodf(x+gridSpacing.x/2,24),fmodf(y+gridSpacing.y/2,24)},tile);
}
tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)},true);
if(tile.pos==game->NO_COLLISION.pos&&tile.size==game->NO_COLLISION.size){
node.bObstacleUpper=false;
}else{
node.bObstacleUpper=geom2d::overlaps(vf2d{fmodf(x,24),fmodf(y,24)},tile);
}
node.parent = nullptr;
node.bVisited = false;
if(nodes.size()==1){//This is the first node added, set as the start node.
@ -63,24 +73,28 @@ void Pathfinding::Initialize(){
}
for (auto&[key,node]:nodes){
if(nodes.find({node.x,node.y-1})!=nodes.end()){
node.vecNeighbours.push_back(&node);
if(nodes.find({node.x,node.y-gridSpacing.y})!=nodes.end()){
node.vecNeighbours.push_back(&nodes[{node.x,node.y-gridSpacing.y}]);
}
if(nodes.find({node.x,node.y+1})!=nodes.end()){
node.vecNeighbours.push_back(&node);
if(nodes.find({node.x,node.y+gridSpacing.y})!=nodes.end()){
node.vecNeighbours.push_back(&nodes[{node.x,node.y+gridSpacing.y}]);
}
if(nodes.find({node.x-1,node.y})!=nodes.end()){
node.vecNeighbours.push_back(&node);
if(nodes.find({node.x-gridSpacing.x,node.y})!=nodes.end()){
node.vecNeighbours.push_back(&nodes[{node.x-gridSpacing.x,node.y}]);
}
if(nodes.find({node.x+1,node.y})!=nodes.end()){
node.vecNeighbours.push_back(&node);
if(nodes.find({node.x+gridSpacing.x,node.y})!=nodes.end()){
node.vecNeighbours.push_back(&nodes[{node.x+gridSpacing.x,node.y}]);
}
}
}
std::vector<vf2d> Pathfinding::Solve_AStar(vf2d startPos,vf2d endPos,float maxRange,bool upperLevel){
float dist=float(sqrt(pow(endPos.x-startPos.x,2)+pow(endPos.y-startPos.y,2)));
if(dist>maxRange*game->GetCurrentMapData().tilewidth)return {};
if(dist>maxRange*game->GetCurrentMapData().tilewidth)return{};
startPos=vi2d(startPos/gridSpacing.x)*gridSpacing.x;
endPos=vi2d(endPos/gridSpacing.x)*gridSpacing.x;
if(nodes.find(startPos)==nodes.end())return{};
if(nodes.find(endPos)==nodes.end())return{};
@ -133,7 +147,7 @@ std::vector<vf2d> Pathfinding::Solve_AStar(vf2d startPos,vf2d endPos,float maxRa
nodeCurrent->bVisited = true;
for (auto nodeNeighbour : nodeCurrent->vecNeighbours)
{
if (!nodeNeighbour->bVisited && ((!upperLevel && nodeNeighbour->bObstacle == 0)||(upperLevel && nodeNeighbour->bObstacleUpper==0)))
if (!nodeNeighbour->bVisited && ((!upperLevel && !nodeNeighbour->bObstacle)||(upperLevel && !nodeNeighbour->bObstacleUpper)))
listNotTestedNodes.push_back(nodeNeighbour);
float fPossiblyLowerGoal = nodeCurrent->fLocalGoal + distance(nodeCurrent, nodeNeighbour);
@ -178,7 +192,7 @@ Pathfinding::sSpline Pathfinding::Solve_WalkPath(vf2d startPos,vf2d endPos,float
void Pathfinding::sSpline::Initialize(const std::vector<vf2d>&points){
this->points.clear();
for(const vf2d&point:points){
this->points.push_back({point});
this->points.push_back({vf2d{point}+gridSpacing/2});
}
fTotalSplineLength=0.f;
for (int i = 0; i < this->points.size(); i++)

@ -77,7 +77,7 @@ struct Pathfinding{
sNode *nodeStart = nullptr;
sNode *nodeEnd = nullptr;
const vi2d gridSpacing = {12,12}; //Decrease this for more precision
const static vi2d gridSpacing; //Decrease this for more precision
void Initialize();
//maxRange in tiles. Returns the path as points.

@ -107,7 +107,7 @@ void Player::ForceSetPos(vf2d pos){
bool Player::SetX(float x){
vf2d newPos={x,pos.y};
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
geom2d::rect<int>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
#pragma region lambdas
auto NoTileCollisionExistsHere=[&](){return collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size;};
#pragma endregion
@ -133,7 +133,7 @@ bool Player::SetX(float x){
bool Player::SetY(float y){
vf2d newPos={pos.x,y};
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
geom2d::rect<int>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
#pragma region lambdas
auto NoTileCollisionExistsHere=[&](){return collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size;};
#pragma endregion

@ -51,7 +51,7 @@ struct Tileset{
bool isTerrain=false;
std::map<int,XMLTag> ForegroundTileData;
std::map<int,XMLTag> UpperForegroundTileData;
std::map<int,TileCollisionData> CollisionData;
std::map<float,TileCollisionData> CollisionData;
std::map<int,XMLTag> StaircaseData;
std::map<int,std::vector<int>> AnimationData;
std::set<int> ReflectiveData;
@ -178,7 +178,7 @@ class TSXParser{
} else
if (newTag.tag=="object"&&previousTag=="tile"){
TileCollisionData data;
data.collision=geom2d::rect<int>{{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}};
data.collision=geom2d::rect<float>{{newTag.GetFloat("x"),newTag.GetFloat("y")},{newTag.GetFloat("width"),newTag.GetFloat("height")}};
if(parsedTilesetInfo.CollisionData.count(previousTagID)){
#ifdef _DEBUG
if(_DEBUG_MAP_LOAD_INFO)ERR("WARNING! There was already collision data defined for tile "<<previousTagID<<"!");

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 5618
#define VERSION_BUILD 5681
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -128,6 +128,9 @@ debug_player_info = 0
# Shows collision boxes of tiles.
debug_collision_boxes = 0
# Shows collision boxe snapping of floating point-based tiles.
debug_collision_boxes_snapping = 0
# Shows pathfinding debugging
debug_pathfinding = 0

@ -760,7 +760,7 @@
</tile>
<tile id="591" type="ForegroundTile">
<objectgroup draworder="index" id="2">
<object id="1" x="7.36364" y="4.90909" width="17" height="19.2727"/>
<object id="1" x="7.36364" y="4.90909" width="16.6364" height="19.0909"/>
</objectgroup>
</tile>
<tile id="592" type="ForegroundTile">

@ -644,12 +644,12 @@ namespace olc
void TransformedView::FillRectDecal(const olc::vf2d & pos, const olc::vf2d & size, const olc::Pixel col)
{
pge->FillRectDecal(WorldToScreen(pos), (size * m_vWorldScale).ceil(), col);
pge->FillRectDecal(WorldToScreen(pos), size * m_vWorldScale, col);
}
void TransformedView::DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col)
{
pge->DrawRectDecal(WorldToScreen(pos), (size * m_vWorldScale).ceil(), col);
pge->DrawRectDecal(WorldToScreen(pos), size * m_vWorldScale, col);
}
void TransformedView::DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p)

@ -3,7 +3,7 @@
olcPixelGameEngine.h
+-------------------------------------------------------------+
| OneLoneCoder Pixel Game Engine v2.23 |
| OneLoneCoder Pixel Game Engine v2.24 |
| "What do you need? Pixels... Lots of Pixels..." - javidx9 |
+-------------------------------------------------------------+
@ -197,11 +197,11 @@ Anonymous Pirate...Return To Monkey Island
Special thanks to my Patreons too - I wont name you on here, but I've
certainly enjoyed my tea and flapjacks :D
- In Memory of SaladinAkara 25.06.2023 -
Author
~~~~~~
David Barr, aka javidx9, (c) OneLoneCoder 2018, 2019, 2020, 2021, 2022
David Barr, aka javidx9, (c) OneLoneCoder 2018, 2019, 2020, 2021, 2022, 2023, 2024
*/
#pragma endregion
@ -322,6 +322,7 @@ Fix Pixel -= operator (thanks Au Lit)
2.22: = Fix typo on dragged file buffers for unicode builds
2.23: Fixed Emscripten host sizing errors - Thanks Moros
Fixed v2d_generic.clamp() function
2.24: Fix FillTexturedTriangle() to remove const-ref
!! Apple Platforms will not see these updates immediately - Sorry, I dont have a mac to test... !!
!! Volunteers willing to help appreciated, though PRs are manually integrated with credit !!
@ -404,7 +405,7 @@ return 0;
#include "olcUTIL_Geometry2D.h"
#pragma endregion
#define PGE_VER 223
#define PGE_VER 224
// O------------------------------------------------------------------------------O
// | COMPILER CONFIGURATION ODDITIES |
@ -1115,7 +1116,7 @@ namespace olc
void FillTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, Pixel p = olc::WHITE);
void FillTriangle(const olc::vi2d& pos1, const olc::vi2d& pos2, const olc::vi2d& pos3, Pixel p = olc::WHITE);
// Fill a textured and coloured triangle
void FillTexturedTriangle(const std::vector<olc::vf2d>& vPoints, std::vector<olc::vf2d> vTex, std::vector<olc::Pixel> vColour, olc::Sprite* sprTex);
void FillTexturedTriangle(std::vector<olc::vf2d> vPoints, std::vector<olc::vf2d> vTex, std::vector<olc::Pixel> vColour, olc::Sprite* sprTex);
void FillTexturedPolygon(const std::vector<olc::vf2d>& vPoints, const std::vector<olc::vf2d>& vTex, const std::vector<olc::Pixel>& vColour, olc::Sprite* sprTex, olc::DecalStructure structure = olc::DecalStructure::LIST);
// Draws an entire sprite at location (x,y)
void DrawSprite(int32_t x, int32_t y, Sprite* sprite, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE, std::function<Pixel(Pixel&)>colorFunc=[](Pixel&in){return in;});
@ -2311,8 +2312,8 @@ namespace olc
auto rol = [&](void) { pattern = (pattern << 1) | (pattern >> 31); return pattern & 1; };
olc::vi2d p1(x1, y1), p2(x2, y2);
//if (!ClipLineToScreen(p1, p2))
// return;
if (!ClipLineToScreen(p1, p2))
return;
x1 = p1.x; y1 = p1.y;
x2 = p2.x; y2 = p2.y;
@ -2706,7 +2707,7 @@ namespace olc
}
}
void PixelGameEngine::FillTexturedTriangle(const std::vector<olc::vf2d>& vPoints, std::vector<olc::vf2d> vTex, std::vector<olc::Pixel> vColour, olc::Sprite* sprTex)
void PixelGameEngine::FillTexturedTriangle(std::vector<olc::vf2d> vPoints, std::vector<olc::vf2d> vTex, std::vector<olc::Pixel> vColour, olc::Sprite* sprTex)
{
olc::vi2d p1 = vPoints[0];
olc::vi2d p2 = vPoints[1];
@ -3149,7 +3150,7 @@ namespace olc
di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f };
di.uv[i] = uv[i];
di.tint[i] = tint;
di.w[i] = 1.0f;
di.w[i] = depth[i];
}
di.mode = nDecalMode;
di.structure = nDecalStructure;

Loading…
Cancel
Save