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",
|
"__tree": "cpp",
|
||||||
"bitset": "cpp",
|
"bitset": "cpp",
|
||||||
"regex": "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);
|
InitializeLevel("assets/Campaigns/1_1.tmx",CAMPAIGN_1_1);
|
||||||
|
|
||||||
|
#ifdef OLC_PLATFORM_EMSCRIPTEN
|
||||||
|
ConsoleCaptureStdOut(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
ClassData::InitializeClassData();
|
ClassData::InitializeClassData();
|
||||||
|
|
||||||
//Initialize Camera.
|
//Initialize Camera.
|
||||||
@ -1096,7 +1100,7 @@ void Crawler::LoadLevel(MapName map){
|
|||||||
}
|
}
|
||||||
player.upperLevel=false; //Assume player starts on lower level.
|
player.upperLevel=false; //Assume player starts on lower level.
|
||||||
player.SetPos(MAP_DATA[map].MapData.playerSpawnLocation);
|
player.SetPos(MAP_DATA[map].MapData.playerSpawnLocation);
|
||||||
player.path.Initialize();
|
pathfinder.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
vi2d Crawler::GetWorldSize(){
|
vi2d Crawler::GetWorldSize(){
|
||||||
|
|||||||
@ -27,6 +27,7 @@ class Crawler : public olc::PixelGameEngine
|
|||||||
GFX_Splash_Effect;
|
GFX_Splash_Effect;
|
||||||
public:
|
public:
|
||||||
Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt;
|
Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt;
|
||||||
|
Pathfinding pathfinder;
|
||||||
private:
|
private:
|
||||||
std::vector<Effect>foregroundEffects,backgroundEffects;
|
std::vector<Effect>foregroundEffects,backgroundEffects;
|
||||||
std::map<MapName,Map>MAP_DATA;
|
std::map<MapName,Map>MAP_DATA;
|
||||||
|
|||||||
@ -23,6 +23,7 @@ Monster::Monster(vf2d pos,MonsterData data):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
randomFrameOffset=(rand()%1000)/1000.f;
|
randomFrameOffset=(rand()%1000)/1000.f;
|
||||||
|
game->pathfinder.Initialize();
|
||||||
}
|
}
|
||||||
vf2d&Monster::GetPos(){
|
vf2d&Monster::GetPos(){
|
||||||
return pos;
|
return pos;
|
||||||
@ -141,13 +142,23 @@ bool Monster::Update(float fElapsedTime){
|
|||||||
state=MOVE_TOWARDS;
|
state=MOVE_TOWARDS;
|
||||||
hasHitPlayer=false;
|
hasHitPlayer=false;
|
||||||
}
|
}
|
||||||
if(state==MOVE_TOWARDS&&geom2d::line(pos,target).length()>100*fElapsedTime*GetMoveSpdMult()){
|
switch(state){
|
||||||
SetPosition(pos+geom2d::line(pos,target).vector().norm()*100*fElapsedTime*GetMoveSpdMult());
|
case MOVE_TOWARDS:{
|
||||||
PerformJumpAnimation();
|
if(geom2d::line(pos,target).length()>100*fElapsedTime*GetMoveSpdMult()){
|
||||||
} else {
|
vf2d newPos=pos+geom2d::line(pos,target).vector().norm()*100*fElapsedTime*GetMoveSpdMult();
|
||||||
if(state==MOVE_TOWARDS){
|
if(!SetX(newPos.x)||!SetY(newPos.y)){
|
||||||
state=NORMAL;//Revert state once we've finished moving towards target.
|
StartPathfinding(4);
|
||||||
UpdateAnimation(MONSTER_DATA[type].GetAnimations()[0]);
|
}
|
||||||
|
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;
|
}break;
|
||||||
@ -183,12 +194,19 @@ bool Monster::Update(float fElapsedTime){
|
|||||||
}
|
}
|
||||||
canMove=true;
|
canMove=true;
|
||||||
geom2d::line moveTowardsLine=geom2d::line(pos,target);
|
geom2d::line moveTowardsLine=geom2d::line(pos,target);
|
||||||
|
bool pathfindingDecision=false;
|
||||||
switch(state){
|
switch(state){
|
||||||
case MOVE_TOWARDS:{
|
case MOVE_TOWARDS:{
|
||||||
if(moveTowardsLine.length()>1){
|
if(moveTowardsLine.length()>1){
|
||||||
vf2d newPos=pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult();
|
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){
|
if(line.length()<=24*7){
|
||||||
state=NORMAL;
|
state=NORMAL;
|
||||||
}
|
}
|
||||||
@ -202,8 +220,14 @@ bool Monster::Update(float fElapsedTime){
|
|||||||
case MOVE_AWAY:{
|
case MOVE_AWAY:{
|
||||||
if(moveTowardsLine.length()>1){
|
if(moveTowardsLine.length()>1){
|
||||||
vf2d newPos=pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult();
|
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){
|
if(line.length()>=24*6){
|
||||||
state=NORMAL;
|
state=NORMAL;
|
||||||
}
|
}
|
||||||
@ -214,6 +238,9 @@ bool Monster::Update(float fElapsedTime){
|
|||||||
}
|
}
|
||||||
PerformJumpAnimation();
|
PerformJumpAnimation();
|
||||||
}break;
|
}break;
|
||||||
|
case PATH_AROUND:{
|
||||||
|
PathAroundBehavior(fElapsedTime);
|
||||||
|
}break;
|
||||||
default:{
|
default:{
|
||||||
if(attackCooldownTimer==0){
|
if(attackCooldownTimer==0){
|
||||||
attackCooldownTimer=1;
|
attackCooldownTimer=1;
|
||||||
@ -352,6 +379,44 @@ void Monster::AddBuff(BuffType type,float duration,float intensity){
|
|||||||
buffList.push_back(Buff{type,duration,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>Monster::GetBuffs(BuffType buff){
|
||||||
std::vector<Buff>filteredBuffs;
|
std::vector<Buff>filteredBuffs;
|
||||||
std::copy_if(buffList.begin(),buffList.end(),std::back_inserter(filteredBuffs),[buff](Buff&b){return b.type==buff;});
|
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 hasHitPlayer=false;
|
||||||
bool canMove=true; //Set to false when stuck due to collisions.
|
bool canMove=true; //Set to false when stuck due to collisions.
|
||||||
bool upperLevel=false;
|
bool upperLevel=false;
|
||||||
|
vf2d pathTarget={};
|
||||||
|
std::vector<vf2d>path;
|
||||||
|
int pathIndex=0;
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
Monster()=delete;
|
Monster()=delete;
|
||||||
@ -112,7 +115,8 @@ protected:
|
|||||||
void PerformShootAnimation();
|
void PerformShootAnimation();
|
||||||
bool OnUpperLevel();
|
bool OnUpperLevel();
|
||||||
void Moved();
|
void Moved();
|
||||||
|
void StartPathfinding(float pathingTime);
|
||||||
|
void PathAroundBehavior(float fElapsedTime);
|
||||||
void AddBuff(BuffType type,float duration,float intensity);
|
void AddBuff(BuffType type,float duration,float intensity);
|
||||||
std::vector<Buff>GetBuffs(BuffType buff);
|
std::vector<Buff>GetBuffs(BuffType buff);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,6 +5,9 @@
|
|||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
|
|
||||||
void Pathfinding::Initialize(){
|
void Pathfinding::Initialize(){
|
||||||
|
if(nodes!=nullptr){
|
||||||
|
delete[] nodes;
|
||||||
|
}
|
||||||
nodes = new sNode[game->WORLD_SIZE.x * game->WORLD_SIZE.y];
|
nodes = new sNode[game->WORLD_SIZE.x * game->WORLD_SIZE.y];
|
||||||
for (int x = 0; x < game->WORLD_SIZE.x; x++)
|
for (int x = 0; x < game->WORLD_SIZE.x; x++)
|
||||||
for (int y = 0; y < game->WORLD_SIZE.y; y++)
|
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){
|
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.
|
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);
|
bool SetPos(vf2d pos);
|
||||||
void SetClass(Class cl);
|
void SetClass(Class cl);
|
||||||
std::vector<Buff>buffList;
|
std::vector<Buff>buffList;
|
||||||
Pathfinding path;
|
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
Player();
|
Player();
|
||||||
|
|||||||
@ -9,4 +9,5 @@ enum State{
|
|||||||
MOVE_AWAY,
|
MOVE_AWAY,
|
||||||
BLOCK,
|
BLOCK,
|
||||||
TELEPORT,
|
TELEPORT,
|
||||||
|
PATH_AROUND
|
||||||
};
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user