Refined movement run away code for ranged enemies.

pull/28/head
sigonasr2 1 year ago
parent df1681b051
commit a2308914a2
  1. 8
      Crawler/Crawler.cpp
  2. 137
      Crawler/Monster.cpp
  3. 7
      Crawler/Monster.h
  4. 4
      Crawler/MonsterData.cpp
  5. 1
      Crawler/State.h

@ -5,7 +5,7 @@
#include "DEFINES.h" #include "DEFINES.h"
//192x192 //192x192
const vi2d WINDOW_SIZE={24*8,24*8}; const vi2d WINDOW_SIZE={24*15,24*10};
std::map<AnimationState,Animate2D::FrameSequence>ANIMATION_DATA; std::map<AnimationState,Animate2D::FrameSequence>ANIMATION_DATA;
std::vector<Monster>MONSTER_LIST; std::vector<Monster>MONSTER_LIST;
std::vector<MonsterSpawner>SPAWNER_LIST; std::vector<MonsterSpawner>SPAWNER_LIST;
@ -24,7 +24,7 @@ bool Crawler::OnUserCreate(){
camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow); camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow);
camera.SetTarget(player.GetPos()); camera.SetTarget(player.GetPos());
camera.SetWorldBoundary({0,0},WORLD_SIZE*24); camera.SetWorldBoundary({0,0},WORLD_SIZE*24);
camera.EnableWorldBoundary(true); camera.EnableWorldBoundary(false);
//Graphics //Graphics
GFX_Pl_Sheet.Load("assets/nico-warrior.png"); GFX_Pl_Sheet.Load("assets/nico-warrior.png");
@ -334,7 +334,9 @@ void Crawler::RenderWorld(float fElapsedTime){
Clear({100,180,100}); Clear({100,180,100});
for (int x = view.GetTopLeftTile().x/24-1; x <= view.GetBottomRightTile().x/24; x++){ for (int x = view.GetTopLeftTile().x/24-1; x <= view.GetBottomRightTile().x/24; x++){
for (int y = view.GetTopLeftTile().y/24-1; y <= view.GetBottomRightTile().y/24; y++){ for (int y = view.GetTopLeftTile().y/24-1; y <= view.GetBottomRightTile().y/24; y++){
view.DrawRect(vi2d{x,y}*24,{24,24},VERY_DARK_GREY); if(x>=00&&x<WORLD_SIZE.x&&y>=0&&y<WORLD_SIZE.y){
view.DrawRect(vi2d{x,y}*24,{24,24},VERY_DARK_GREY);
}
} }
} }
std::vector<Monster>monstersBefore,monstersAfter; std::vector<Monster>monstersBefore,monstersAfter;

@ -10,8 +10,8 @@ INCLUDE_DAMAGENUMBER_LIST
INCLUDE_game INCLUDE_game
MonsterData::MonsterData(){} MonsterData::MonsterData(){}
MonsterData::MonsterData(MonsterName type,int hp,int atk,std::vector<AnimationState>animations,float moveSpd,float size,MonsterStrategy strategy): MonsterData::MonsterData(MonsterName type,int hp,int atk,std::vector<AnimationState>animations,float moveSpd,float size,MonsterStrategy strategy,int collisionDmg):
type(type),hp(hp),atk(atk),moveSpd(moveSpd),size(size),strategy(strategy),animations(animations){ type(type),hp(hp),atk(atk),moveSpd(moveSpd),size(size),strategy(strategy),animations(animations),collisionDmg(collisionDmg){
} }
int MonsterData::GetHealth(){ int MonsterData::GetHealth(){
return hp; return hp;
@ -25,6 +25,9 @@ float MonsterData::GetMoveSpdMult(){
float MonsterData::GetSizeMult(){ float MonsterData::GetSizeMult(){
return size; return size;
} }
int MonsterData::GetCollisionDmg(){
return collisionDmg;
}
MonsterName MonsterData::GetType(){ MonsterName MonsterData::GetType(){
return type; return type;
} }
@ -66,6 +69,33 @@ Animate2D::Frame Monster::GetFrame(){
void Monster::UpdateAnimation(AnimationState state){ void Monster::UpdateAnimation(AnimationState state){
animation.ChangeState(internal_animState,state); animation.ChangeState(internal_animState,state);
} }
void Monster::PerformJumpAnimation(){
switch(type){
case SLIME_GREEN:{
animation.ChangeState(internal_animState,AnimationState::GREEN_SLIME_JUMP);
}break;
case SLIME_BLUE:{
animation.ChangeState(internal_animState,AnimationState::BLUE_SLIME_JUMP);
}break;
case SLIME_RED:{
animation.ChangeState(internal_animState,AnimationState::RED_SLIME_JUMP);
}break;
}
}
void Monster::SetX(float x){
if(x-12*size>0&&x+12*size<game->WORLD_SIZE.x*24){
pos.x=x;
} else {
pos.x=std::min(game->WORLD_SIZE.x*24-12*size,std::max(12*size,pos.x));
}
}
void Monster::SetY(float y){
if(y-12*size>0&&y+12*size<game->WORLD_SIZE.y*24){
pos.y=y;
} else {
pos.y=std::min(game->WORLD_SIZE.y*24-12*size,std::max(12*size,pos.y));
}
}
bool Monster::Update(float fElapsedTime){ bool Monster::Update(float fElapsedTime){
if(IsAlive()){ if(IsAlive()){
for(Monster&m:MONSTER_LIST){ for(Monster&m:MONSTER_LIST){
@ -102,23 +132,86 @@ bool Monster::Update(float fElapsedTime){
state=MOVE_TOWARDS; state=MOVE_TOWARDS;
} }
if(state==MOVE_TOWARDS&&geom2d::line(pos,target).length()>100*fElapsedTime*moveSpd){ if(state==MOVE_TOWARDS&&geom2d::line(pos,target).length()>100*fElapsedTime*moveSpd){
pos+=geom2d::line(pos,target).vector().norm()*100*fElapsedTime*moveSpd; SetPosition(pos+geom2d::line(pos,target).vector().norm()*100*fElapsedTime*moveSpd);
switch(type){ PerformJumpAnimation();
case SLIME_GREEN:{
animation.ChangeState(internal_animState,AnimationState::GREEN_SLIME_JUMP);
}break;
case SLIME_RED:{
animation.ChangeState(internal_animState,AnimationState::RED_SLIME_JUMP);
}break;
}
} else { } else {
if(state==MOVE_TOWARDS){ if(state==MOVE_TOWARDS){
state=NORMAL;//Revert state once we've finished moving towards target. state=NORMAL;//Revert state once we've finished moving towards target.
UpdateAnimation(MONSTER_DATA[type].GetAnimations()[0]);
} }
} }
}break; }break;
case SHOOT_AFAR:{ case SHOOT_AFAR:{
targetAcquireTimer=std::max(0.f,targetAcquireTimer-fElapsedTime);
geom2d::line line(pos,game->GetPlayer().GetPos());
if(targetAcquireTimer==0){
targetAcquireTimer=1;
if(line.length()<24*6){
target=line.upoint(-1.2);
if(pos.x-12*size>1&&pos.x+12*size<game->WORLD_SIZE.x*24-1&&
pos.y-12*size>1&&pos.y+12*size<game->WORLD_SIZE.y*24-1){
state=MOVE_AWAY;
} else
if(pos.x-12*size<=1||pos.x+12*size>=game->WORLD_SIZE.x*24-1){
geom2d::line moveTowardsLine=geom2d::line(pos,target);
if(abs(moveTowardsLine.vector().norm().y)>=0.5){
std::cout<<moveTowardsLine.vector().norm().x<<std::endl;
state=MOVE_AWAY;
} else {
state=NORMAL;
}
} else
if(pos.y-12*size<=1||pos.y+12*size>=game->WORLD_SIZE.y*24-1){
geom2d::line moveTowardsLine=geom2d::line(pos,target);
if(abs(moveTowardsLine.vector().norm().x)>=0.5){
std::cout<<moveTowardsLine.vector().norm().x<<std::endl;
state=MOVE_AWAY;
} else {
state=NORMAL;
}
}
} else
if(line.length()>24*7){
target=line.upoint(1.2);
state=MOVE_TOWARDS;
} else {
state=NORMAL;
}
}
geom2d::line moveTowardsLine=geom2d::line(pos,target);
switch(state){
case MOVE_TOWARDS:{
if(moveTowardsLine.length()>1){
SetPosition(pos+moveTowardsLine.vector().norm()*100*fElapsedTime*moveSpd);
}
if(line.length()<=24*7){
state=NORMAL;
}
if(moveTowardsLine.vector().x>0){
facingDirection=RIGHT;
} else {
facingDirection=LEFT;
}
PerformJumpAnimation();
}break;
case MOVE_AWAY:{
if(moveTowardsLine.length()>1){
SetPosition(pos+moveTowardsLine.vector().norm()*100*fElapsedTime*moveSpd);
}
if(line.length()>=24*6){
state=NORMAL;
}
if(moveTowardsLine.vector().x>0){
facingDirection=RIGHT;
} else {
facingDirection=LEFT;
}
PerformJumpAnimation();
}break;
default:{
UpdateAnimation(MONSTER_DATA[type].GetAnimations()[0]);
}
}
}break; }break;
} }
if(vel.x>0){ if(vel.x>0){
@ -131,14 +224,8 @@ bool Monster::Update(float fElapsedTime){
} else { } else {
vel.y=std::min(0.f,vel.y+friction*fElapsedTime); vel.y=std::min(0.f,vel.y+friction*fElapsedTime);
} }
float newX=pos.x+vel.x*fElapsedTime; SetX(pos.x+vel.x*fElapsedTime);
if(newX-12*size>0&&newX+12*size<game->WORLD_SIZE.x*24){ SetY(pos.y+vel.y*fElapsedTime);
pos.x=newX;
}
float newY=pos.y+vel.y*fElapsedTime;
if(newY-12*size>0&&newY+12*size<game->WORLD_SIZE.y*24){
pos.y=newY;
}
} }
if(hp<=0){ if(hp<=0){
deathTimer+=fElapsedTime; deathTimer+=fElapsedTime;
@ -159,12 +246,11 @@ void Monster::Draw(){
} else { } else {
game->view.DrawPartialDecal(GetPos()-vf2d{12,12}*GetSizeMult(),GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult(),GetSizeMult())); game->view.DrawPartialDecal(GetPos()-vf2d{12,12}*GetSizeMult(),GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult(),GetSizeMult()));
} }
if(GetTargetPos()!=vf2d{0,0}){
game->view.DrawLine(GetPos(),GetTargetPos(),RED,0xF4F4F4F4);
game->view.DrawCircle(GetTargetPos(),6,RED);
}
} }
void Monster::Collision(Player&p){ void Monster::Collision(Player&p){
if(MONSTER_DATA[type].GetCollisionDmg()>0){
p.Hurt(MONSTER_DATA[type].GetCollisionDmg());
}
Collision(); Collision();
} }
void Monster::Collision(Monster&m){ void Monster::Collision(Monster&m){
@ -179,7 +265,8 @@ void Monster::SetVelocity(vf2d vel){
this->vel=vel; this->vel=vel;
} }
void Monster::SetPosition(vf2d pos){ void Monster::SetPosition(vf2d pos){
this->pos=pos; SetX(pos.x);
SetY(pos.y);
} }
AnimationState Monster::GetDeathAnimationName(){ AnimationState Monster::GetDeathAnimationName(){
switch(type){ switch(type){

@ -26,16 +26,18 @@ struct MonsterData{
std::vector<AnimationState> animations; std::vector<AnimationState> animations;
MonsterStrategy strategy; MonsterStrategy strategy;
MonsterName type; MonsterName type;
int collisionDmg;
public: public:
MonsterData(); MonsterData();
//When specifying animations, the first one will become the default animation. The last becomes the death animation. //When specifying animations, the first one will become the default animation. The last becomes the death animation.
MonsterData(MonsterName type,int hp,int atk,std::vector<AnimationState>animations,float moveSpd=1.0f,float size=1.0f,MonsterStrategy strategy=RUN_TOWARDS); MonsterData(MonsterName type,int hp,int atk,std::vector<AnimationState>animations,float moveSpd=1.0f,float size=1.0f,MonsterStrategy strategy=RUN_TOWARDS,int collisionDmg=0);
int GetHealth(); int GetHealth();
int GetAttack(); int GetAttack();
float GetMoveSpdMult(); float GetMoveSpdMult();
float GetSizeMult(); float GetSizeMult();
MonsterName GetType(); MonsterName GetType();
MonsterStrategy GetAIStrategy(); MonsterStrategy GetAIStrategy();
int GetCollisionDmg();
std::vector<AnimationState>GetAnimations(){ std::vector<AnimationState>GetAnimations(){
return animations; return animations;
} }
@ -83,6 +85,9 @@ struct Monster{
void Collision(); void Collision();
void SetVelocity(vf2d vel); void SetVelocity(vf2d vel);
void SetPosition(vf2d pos); void SetPosition(vf2d pos);
void SetX(float x);
void SetY(float y);
void PerformJumpAnimation();
}; };
struct MonsterSpawner{ struct MonsterSpawner{

@ -3,8 +3,8 @@
#include "Animation.h" #include "Animation.h"
std::map<MonsterName,MonsterData>MONSTER_DATA={ std::map<MonsterName,MonsterData>MONSTER_DATA={
{SLIME_GREEN,MonsterData(MonsterName::SLIME_GREEN,10,5,{{AnimationState::GREEN_SLIME_IDLE,AnimationState::GREEN_SLIME_JUMP,AnimationState::GREEN_SLIME_ROLL,AnimationState::GREEN_SLIME_DIE,AnimationState::GREEN_SLIME_SPIT}},1.1f,0.8f,MonsterStrategy::RUN_TOWARDS)}, {SLIME_GREEN,MonsterData(MonsterName::SLIME_GREEN,10,5,{{AnimationState::GREEN_SLIME_IDLE,AnimationState::GREEN_SLIME_JUMP,AnimationState::GREEN_SLIME_ROLL,AnimationState::GREEN_SLIME_DIE,AnimationState::GREEN_SLIME_SPIT}},1.1f,0.8f,MonsterStrategy::RUN_TOWARDS,5)},
{SLIME_BLUE,MonsterData(MonsterName::SLIME_BLUE,30,10,{{AnimationState::BLUE_SLIME_IDLE,AnimationState::BLUE_SLIME_JUMP,AnimationState::BLUE_SLIME_ROLL,AnimationState::BLUE_SLIME_DIE,AnimationState::BLUE_SLIME_SPIT}},0.8f,1.0f,MonsterStrategy::SHOOT_AFAR)}, {SLIME_BLUE,MonsterData(MonsterName::SLIME_BLUE,30,10,{{AnimationState::BLUE_SLIME_IDLE,AnimationState::BLUE_SLIME_JUMP,AnimationState::BLUE_SLIME_ROLL,AnimationState::BLUE_SLIME_DIE,AnimationState::BLUE_SLIME_SPIT}},0.8f,1.0f,MonsterStrategy::SHOOT_AFAR)},
{SLIME_RED,MonsterData(MonsterName::SLIME_RED,25,10,{{AnimationState::RED_SLIME_IDLE,AnimationState::RED_SLIME_JUMP,AnimationState::RED_SLIME_ROLL,AnimationState::RED_SLIME_DIE,AnimationState::RED_SLIME_SPIT}},0.95f,1.2f,MonsterStrategy::RUN_TOWARDS)}, {SLIME_RED,MonsterData(MonsterName::SLIME_RED,25,10,{{AnimationState::RED_SLIME_IDLE,AnimationState::RED_SLIME_JUMP,AnimationState::RED_SLIME_ROLL,AnimationState::RED_SLIME_DIE,AnimationState::RED_SLIME_SPIT}},0.95f,1.2f,MonsterStrategy::RUN_TOWARDS,10)},
//{SLIME_YELLOW,{}}, //{SLIME_YELLOW,{}},
}; };

@ -4,4 +4,5 @@ enum State{
NORMAL, NORMAL,
SPIN, SPIN,
MOVE_TOWARDS, MOVE_TOWARDS,
MOVE_AWAY,
}; };
Loading…
Cancel
Save