Add in pathfinding abilities to monster movement strategies.
This commit is contained in:
parent
debf151c46
commit
0529de4bf9
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -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…
x
Reference in New Issue
Block a user