Add in pathfinding abilities to monster movement strategies.

pull/28/head
sigonasr2, Sig, Sigo 2 years ago
parent debf151c46
commit 0529de4bf9
  1. 3
      .vscode/settings.json
  2. 6
      Crawler/Crawler.cpp
  3. 1
      Crawler/Crawler.h
  4. 83
      Crawler/Monster.cpp
  5. 6
      Crawler/Monster.h
  6. 3
      Crawler/Pathfinding.cpp
  7. 2
      Crawler/Player.cpp
  8. 1
      Crawler/Player.h
  9. 1
      Crawler/State.h

@ -87,6 +87,7 @@
"__tree": "cpp",
"bitset": "cpp",
"regex": "cpp",
"valarray": "cpp"
"valarray": "cpp",
"*.inc": "cpp"
}
}

@ -33,6 +33,10 @@ bool Crawler::OnUserCreate(){
InitializeLevel("assets/Campaigns/1_1.tmx",CAMPAIGN_1_1);
#ifdef OLC_PLATFORM_EMSCRIPTEN
ConsoleCaptureStdOut(true);
#endif
ClassData::InitializeClassData();
//Initialize Camera.
@ -1096,7 +1100,7 @@ void Crawler::LoadLevel(MapName map){
}
player.upperLevel=false; //Assume player starts on lower level.
player.SetPos(MAP_DATA[map].MapData.playerSpawnLocation);
player.path.Initialize();
pathfinder.Initialize();
}
vi2d Crawler::GetWorldSize(){

@ -27,6 +27,7 @@ class Crawler : public olc::PixelGameEngine
GFX_Splash_Effect;
public:
Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt;
Pathfinding pathfinder;
private:
std::vector<Effect>foregroundEffects,backgroundEffects;
std::map<MapName,Map>MAP_DATA;

@ -23,6 +23,7 @@ Monster::Monster(vf2d pos,MonsterData data):
}
}
randomFrameOffset=(rand()%1000)/1000.f;
game->pathfinder.Initialize();
}
vf2d&Monster::GetPos(){
return pos;
@ -141,13 +142,23 @@ bool Monster::Update(float fElapsedTime){
state=MOVE_TOWARDS;
hasHitPlayer=false;
}
if(state==MOVE_TOWARDS&&geom2d::line(pos,target).length()>100*fElapsedTime*GetMoveSpdMult()){
SetPosition(pos+geom2d::line(pos,target).vector().norm()*100*fElapsedTime*GetMoveSpdMult());
PerformJumpAnimation();
} else {
if(state==MOVE_TOWARDS){
state=NORMAL;//Revert state once we've finished moving towards target.
UpdateAnimation(MONSTER_DATA[type].GetAnimations()[0]);
switch(state){
case MOVE_TOWARDS:{
if(geom2d::line(pos,target).length()>100*fElapsedTime*GetMoveSpdMult()){
vf2d newPos=pos+geom2d::line(pos,target).vector().norm()*100*fElapsedTime*GetMoveSpdMult();
if(!SetX(newPos.x)||!SetY(newPos.y)){
StartPathfinding(4);
}
PerformJumpAnimation();
} else {
state=NORMAL;//Revert state once we've finished moving towards target.
UpdateAnimation(MONSTER_DATA[type].GetAnimations()[0]);
}
}break;
case PATH_AROUND:{
PathAroundBehavior(fElapsedTime);
}break;
default:{
}
}
}break;
@ -183,12 +194,19 @@ bool Monster::Update(float fElapsedTime){
}
canMove=true;
geom2d::line moveTowardsLine=geom2d::line(pos,target);
bool pathfindingDecision=false;
switch(state){
case MOVE_TOWARDS:{
if(moveTowardsLine.length()>1){
vf2d newPos=pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult();
canMove=SetX(newPos.x)&&SetY(newPos.y);
bool movedX=SetX(newPos.x);
bool movedY=SetY(newPos.y);
pathfindingDecision=movedX|movedY;
canMove=movedX&&movedY;
}
if(!pathfindingDecision){
StartPathfinding(2.5);
}else
if(line.length()<=24*7){
state=NORMAL;
}
@ -202,8 +220,14 @@ bool Monster::Update(float fElapsedTime){
case MOVE_AWAY:{
if(moveTowardsLine.length()>1){
vf2d newPos=pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult();
canMove=SetX(newPos.x)&&SetY(newPos.y);
bool movedX=SetX(newPos.x);
bool movedY=SetY(newPos.y);
pathfindingDecision=movedX|movedY;
canMove=movedX&&movedY;
}
if(!pathfindingDecision){
StartPathfinding(2.5);
}else
if(line.length()>=24*6){
state=NORMAL;
}
@ -214,6 +238,9 @@ bool Monster::Update(float fElapsedTime){
}
PerformJumpAnimation();
}break;
case PATH_AROUND:{
PathAroundBehavior(fElapsedTime);
}break;
default:{
if(attackCooldownTimer==0){
attackCooldownTimer=1;
@ -352,6 +379,44 @@ void Monster::AddBuff(BuffType type,float duration,float intensity){
buffList.push_back(Buff{type,duration,intensity});
}
void Monster::StartPathfinding(float pathingTime){
state=State::PATH_AROUND;
path=game->pathfinder.Solve_AStar(pos,target,12,OnUpperLevel());
if(path.size()>0){
pathIndex=0;
//We gives this mob 5 seconds to figure out a path to the target.
targetAcquireTimer=pathingTime;
}
}
void Monster::PathAroundBehavior(float fElapsedTime){
if(path.size()>0){
//Move towards the new path.
geom2d::line moveTowardsLine=geom2d::line(pos,path[pathIndex]*24);
if(moveTowardsLine.length()>2){
SetPosition(pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult());
if(moveTowardsLine.vector().x>0){
facingDirection=RIGHT;
} else {
facingDirection=LEFT;
}
}else{
if(pathIndex+1>=path.size()){
//We have reached the end of the path!
std::cout<<"Reached the end of the path."<<std::endl;
targetAcquireTimer=0;
}else{
std::cout<<"End of pathing "<<pathIndex<<". Advancing."<<std::endl;
pathIndex++;
std::cout<<" Current Target:"<<path[pathIndex]*24<<std::endl;
}
}
} else {
//We actually can't do anything so just quit.
targetAcquireTimer=0;
}
}
std::vector<Buff>Monster::GetBuffs(BuffType buff){
std::vector<Buff>filteredBuffs;
std::copy_if(buffList.begin(),buffList.end(),std::back_inserter(filteredBuffs),[buff](Buff&b){return b.type==buff;});

@ -80,6 +80,9 @@ struct Monster{
bool hasHitPlayer=false;
bool canMove=true; //Set to false when stuck due to collisions.
bool upperLevel=false;
vf2d pathTarget={};
std::vector<vf2d>path;
int pathIndex=0;
protected:
public:
Monster()=delete;
@ -112,7 +115,8 @@ protected:
void PerformShootAnimation();
bool OnUpperLevel();
void Moved();
void StartPathfinding(float pathingTime);
void PathAroundBehavior(float fElapsedTime);
void AddBuff(BuffType type,float duration,float intensity);
std::vector<Buff>GetBuffs(BuffType buff);
};

@ -5,6 +5,9 @@
INCLUDE_game
void Pathfinding::Initialize(){
if(nodes!=nullptr){
delete[] nodes;
}
nodes = new sNode[game->WORLD_SIZE.x * game->WORLD_SIZE.y];
for (int x = 0; x < game->WORLD_SIZE.x; x++)
for (int y = 0; y < game->WORLD_SIZE.y; y++)

@ -460,6 +460,6 @@ std::vector<Buff>Player::GetBuffs(BuffType buff){
}
bool Player::CanPathfindTo(vf2d pos,vf2d targetPos,float range){
std::vector<vf2d>pathing=path.Solve_AStar(pos,targetPos,8,upperLevel);
std::vector<vf2d>pathing=game->pathfinder.Solve_AStar(pos,targetPos,8,upperLevel);
return pathing.size()>0&&pathing.size()<8;//We'll say 7 tiles or less is close enough to 650 range. Have a little bit of wiggle room.
}

@ -67,7 +67,6 @@ struct Player{
bool SetPos(vf2d pos);
void SetClass(Class cl);
std::vector<Buff>buffList;
Pathfinding path;
protected:
public:
Player();

@ -9,4 +9,5 @@ enum State{
MOVE_AWAY,
BLOCK,
TELEPORT,
PATH_AROUND
};
Loading…
Cancel
Save