Cleaned up pathfinding algorithms.
This commit is contained in:
parent
0d95dec2a7
commit
c18418c4ce
@ -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);
|
||||
@ -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;
|
||||
|
@ -117,7 +117,7 @@ bool Monster::SetX(float x){
|
||||
vf2d newPos={x,pos.y};
|
||||
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
||||
if(collisionRect.pos==vi2d{0,0}&&collisionRect.size==vi2d{1,1}){
|
||||
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;
|
||||
@ -136,7 +136,7 @@ bool Monster::SetY(float y){
|
||||
vf2d newPos={pos.x,y};
|
||||
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
||||
if(collisionRect.pos==vi2d{0,0}&&collisionRect.size==vi2d{1,1}){
|
||||
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;
|
||||
@ -234,6 +234,18 @@ void Monster::Draw(){
|
||||
game->view.DrawDecal(GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK);
|
||||
}
|
||||
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;
|
||||
@ -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<float>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.
|
||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 1
|
||||
#define VERSION_BUILD 5648
|
||||
#define VERSION_BUILD 5681
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user