diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 34c51883..7434a5ef 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -128,6 +128,9 @@ void Crawler::InitializeAnimations(){ if(state==4){//These are death animations. anim=Animate2D::FrameSequence(0.1f,Animate2D::Style::OneShot); } + if(state==2){//These are death animations. + anim=Animate2D::FrameSequence(0.06f); + } for (int frame=0;frame<10;frame++){ anim.AddFrame({&GFX_Slime_Sheet,{vi2d{frame,state+5*slime}*24,{24,24}}}); } @@ -173,53 +176,54 @@ void Crawler::HandleUserInput(float fElapsedTime){ if(GetKey(SPACE).bPressed&&player.GetState()==State::NORMAL&&player.GetGroundSlamCooldown()==0){ player.Spin(Player::GROUND_SLAM_SPIN_TIME,14*PI); } - if(RightHeld()){ - if(player.GetPos().x+12+fElapsedTime*100*player.GetMoveSpdMult()0){ - player.SetX(player.GetX()-fElapsedTime*100*player.GetMoveSpdMult()); - } else { - player.SetX(12); - } - if(setIdleAnimation){ - player.SetFacingDirection(LEFT); - player.UpdateAnimation(AnimationState::WALK_W); - } - setIdleAnimation=false; - } - if(UpHeld()){ - if(player.GetPos().y-12+fElapsedTime*100*player.GetMoveSpdMult()>0){ - player.SetY(player.GetY()-fElapsedTime*100*player.GetMoveSpdMult()); - } else { - player.SetY(12); + if(player.GetVelocity()==vf2d{0,0}){ + if(RightHeld()){ + if(player.GetPos().x+12*player.GetSizeMult()+fElapsedTime*100*player.GetMoveSpdMult()0){ + player.SetX(player.GetX()-fElapsedTime*100*player.GetMoveSpdMult()); + } else { + player.SetX(12); + } + if(setIdleAnimation){ + player.SetFacingDirection(LEFT); + player.UpdateAnimation(AnimationState::WALK_W); + } + setIdleAnimation=false; } - setIdleAnimation=false; - } - if(DownHeld()){ - if(player.GetPos().y+12+fElapsedTime*100*player.GetMoveSpdMult()0){ + player.SetY(player.GetY()-fElapsedTime*100*player.GetMoveSpdMult()); + } else { + player.SetY(12); + } + if(setIdleAnimation){ + player.SetFacingDirection(UP); + player.UpdateAnimation(AnimationState::WALK_N); + } + setIdleAnimation=false; } - if(setIdleAnimation){ - player.SetFacingDirection(DOWN); - player.UpdateAnimation(AnimationState::WALK_S); + if(DownHeld()){ + if(player.GetPos().y+12*player.GetSizeMult()+fElapsedTime*100*player.GetMoveSpdMult()Decal(),m.GetFrame().GetSourceRect().pos,m.GetFrame().GetSourceRect().size,vf2d(m.GetSizeMult(),m.GetSizeMult())); + m.Draw(); } view.DrawPartialRotatedDecal(player.GetPos()+vf2d{0,-player.GetZ()},player.GetFrame().GetSourceImage()->Decal(),player.GetSpinAngle(),{12,12},player.GetFrame().GetSourceRect().pos,player.GetFrame().GetSourceRect().size,vf2d(player.GetSizeMult(),player.GetSizeMult())); for(Monster&m:monstersAfter){ - view.DrawPartialDecal(m.GetPos()-vf2d{12,12}*m.GetSizeMult(),m.GetFrame().GetSourceImage()->Decal(),m.GetFrame().GetSourceRect().pos,m.GetFrame().GetSourceRect().size,vf2d(m.GetSizeMult(),m.GetSizeMult())); + m.Draw(); } for(Effect&e:foregroundEffects){ e.Draw(); @@ -374,6 +378,10 @@ void Crawler::RenderWorld(float fElapsedTime){ } } +Player&Crawler::GetPlayer(){ + return player; +} + void Crawler::RenderHud(){ if(player.GetGroundSlamCooldown()>0){ FillRectDecal({10,ScreenHeight()-22.f},{64,6},BLACK); diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index bde5be59..73b83322 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -10,7 +10,6 @@ class Crawler : public olc::PixelGameEngine { - const vi2d WORLD_SIZE={64,8}; Camera2D camera; Player player; Renderable GFX_Pl_Sheet,GFX_Slime_Sheet,GFX_Circle, @@ -21,6 +20,7 @@ public: Crawler(); public: + const vi2d WORLD_SIZE={64,8}; TileTransformedView view; bool OnUserCreate() override; bool OnUserUpdate(float fElapsedTime) override; @@ -41,4 +41,5 @@ public: bool RightReleased(); bool UpReleased(); bool DownReleased(); + Player&GetPlayer(); }; \ No newline at end of file diff --git a/Crawler/Monster.cpp b/Crawler/Monster.cpp index 8e8c46e6..146f9bd9 100644 --- a/Crawler/Monster.cpp +++ b/Crawler/Monster.cpp @@ -1,11 +1,13 @@ #include "Monster.h" #include "DamageNumber.h" +#include "Crawler.h" #include "DEFINES.h" INCLUDE_ANIMATION_DATA INCLUDE_MONSTER_DATA INCLUDE_MONSTER_LIST INCLUDE_DAMAGENUMBER_LIST +INCLUDE_game MonsterData::MonsterData(){} MonsterData::MonsterData(MonsterName type,int hp,int atk,std::vectoranimations,float moveSpd,float size,MonsterStrategy strategy): @@ -65,13 +67,78 @@ void Monster::UpdateAnimation(AnimationState state){ animation.ChangeState(internal_animState,state); } bool Monster::Update(float fElapsedTime){ - switch(strategy){ - RUN_TOWARDS:{ - - }break; - SHOOT_AFAR:{ + if(IsAlive()){ + for(Monster&m:MONSTER_LIST){ + if(&m==this)continue; + if(geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ + m.Collision(*this); + geom2d::line line(pos,m.GetPos()); + float dist = line.length(); + m.SetPosition(line.rpoint(dist*1.1)); + if(m.IsAlive()){ + vel=line.vector().norm()*-128; + } + } + } + if(geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(game->GetPlayer().GetPos(),12*game->GetPlayer().GetSizeMult()/2))){ + geom2d::line line(pos,game->GetPlayer().GetPos()); + float dist = line.length(); + SetPosition(line.rpoint(-0.1)); + vel=line.vector().norm()*-128; + } + if(state==NORMAL){ + if(game->GetPlayer().GetX()>pos.x){ + facingDirection=RIGHT; + } else { + facingDirection=LEFT; + } + } + switch(strategy){ + case RUN_TOWARDS:{ + targetAcquireTimer=std::max(0.f,targetAcquireTimer-fElapsedTime); + if(targetAcquireTimer==0){ + targetAcquireTimer=3; + target=geom2d::line(pos,game->GetPlayer().GetPos()).upoint(1.2); + state=MOVE_TOWARDS; + } + if(state==MOVE_TOWARDS&&geom2d::line(pos,target).length()>100*fElapsedTime*moveSpd){ + pos+=geom2d::line(pos,target).vector().norm()*100*fElapsedTime*moveSpd; + switch(type){ + 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 { + if(state==MOVE_TOWARDS){ + state=NORMAL;//Revert state once we've finished moving towards target. + } + } + }break; + case SHOOT_AFAR:{ - }break; + }break; + } + if(vel.x>0){ + vel.x=std::max(0.f,vel.x-friction*fElapsedTime); + } else { + vel.x=std::min(0.f,vel.x+friction*fElapsedTime); + } + if(vel.y>0){ + vel.y=std::max(0.f,vel.y-friction*fElapsedTime); + } else { + vel.y=std::min(0.f,vel.y+friction*fElapsedTime); + } + float newX=pos.x+vel.x*fElapsedTime; + if(newX-12*size>0&&newX+12*sizeWORLD_SIZE.x*24){ + pos.x=newX; + } + float newY=pos.y+vel.y*fElapsedTime; + if(newY-12*size>0&&newY+12*sizeWORLD_SIZE.y*24){ + pos.y=newY; + } } if(hp<=0){ deathTimer+=fElapsedTime; @@ -83,6 +150,37 @@ bool Monster::Update(float fElapsedTime){ randomFrameOffset=0; return true; } +Key Monster::GetFacingDirection(){ + return facingDirection; +} +void Monster::Draw(){ + if(GetFacingDirection()==RIGHT){ + game->view.DrawPartialDecal((GetPos()+vf2d{float(GetFrame().GetSourceRect().size.x),0}*GetSizeMult())-vf2d{12,12}*GetSizeMult(),GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*-1,GetSizeMult())); + } else { + 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){ + Collision(); +} +void Monster::Collision(Monster&m){ + Collision(); +} +void Monster::Collision(){ + if(strategy==RUN_TOWARDS&&state==MOVE_TOWARDS){ + state=NORMAL; + } +} +void Monster::SetVelocity(vf2d vel){ + this->vel=vel; +} +void Monster::SetPosition(vf2d pos){ + this->pos=pos; +} AnimationState Monster::GetDeathAnimationName(){ switch(type){ case SLIME_GREEN:{ @@ -112,6 +210,9 @@ bool Monster::Hurt(int damage){ bool Monster::IsAlive(){ return hp>0; } +vf2d&Monster::GetTargetPos(){ + return target; +} MonsterSpawner::MonsterSpawner(){} MonsterSpawner::MonsterSpawner(vf2d pos,int range,std::vector>monsters): diff --git a/Crawler/Monster.h b/Crawler/Monster.h index 2ca83d92..3d647a1a 100644 --- a/Crawler/Monster.h +++ b/Crawler/Monster.h @@ -1,6 +1,8 @@ #pragma once #include "olcPixelGameEngine.h" #include "Animation.h" +#include "State.h" +#include "Player.h" #include "olcUTIL_Animate2D.h" enum MonsterStrategy{ @@ -42,11 +44,17 @@ struct MonsterData{ struct Monster{ private: vf2d pos; + vf2d vel={0,0}; + float friction=400; + vf2d target={0,0}; + float targetAcquireTimer=0; int hp,maxhp; int atk; float moveSpd; float size; + Key facingDirection; MonsterStrategy strategy; + State state=State::NORMAL; Animate2D::Animationanimation; Animate2D::AnimationState internal_animState; float randomFrameOffset=0.f; @@ -67,6 +75,14 @@ struct Monster{ //Returns true when damage is actually dealt (there is a death check here.) bool Hurt(int damage); bool IsAlive(); + vf2d&GetTargetPos(); + Key GetFacingDirection(); + void Draw(); + void Collision(Player&p); + void Collision(Monster&p); + void Collision(); + void SetVelocity(vf2d vel); + void SetPosition(vf2d pos); }; struct MonsterSpawner{ diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index 95818171..ea178f79 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -131,6 +131,37 @@ void Player::Update(float fElapsedTime){ } animation.UpdateState(internal_animState,fElapsedTime); groundSlamCooldown=std::max(0.f,groundSlamCooldown-fElapsedTime); + for(Monster&m:MONSTER_LIST){ + if(geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ + if(m.IsAlive()){ + m.Collision(*this); + } + geom2d::line line(pos,m.GetPos()); + float dist = line.length(); + m.SetPosition(line.rpoint(dist*1.1)); + if(m.IsAlive()){ + vel=line.vector().norm()*-128; + } + } + } + if(vel.x>0){ + vel.x=std::max(0.f,vel.x-friction*fElapsedTime); + } else { + vel.x=std::min(0.f,vel.x+friction*fElapsedTime); + } + if(vel.y>0){ + vel.y=std::max(0.f,vel.y-friction*fElapsedTime); + } else { + vel.y=std::min(0.f,vel.y+friction*fElapsedTime); + } + float newX=pos.x+vel.x*fElapsedTime; + if(newX-12*size>0&&newX+12*sizeWORLD_SIZE.x*24){ + pos.x=newX; + } + float newY=pos.y+vel.y*fElapsedTime; + if(newY-12*size>0&&newY+12*sizeWORLD_SIZE.y*24){ + pos.y=newY; + } if(attack_cooldown_timer==0&&game->GetMouse(0).bHeld){ bool attack=false; Monster*closest=nullptr; @@ -149,6 +180,10 @@ void Player::Update(float fElapsedTime){ } } +vf2d Player::GetVelocity(){ + return vel; +} + void Player::Hurt(int damage){ if(hp<=0) return; hp=std::max(0,hp-damage); diff --git a/Crawler/Player.h b/Crawler/Player.h index 42db70ed..f8d6c050 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -9,6 +9,8 @@ private: int hp=100,maxhp=hp; int atk=10; vf2d pos; + vf2d vel={0,0}; + float friction=400; float z=0; float moveSpd=1.0f; float size=1.0f; @@ -48,6 +50,7 @@ public: State GetState(); void SetFacingDirection(Key direction); Key GetFacingDirection(); + vf2d GetVelocity(); void Hurt(int damage); diff --git a/Crawler/State.h b/Crawler/State.h index c988e212..bc16592a 100644 --- a/Crawler/State.h +++ b/Crawler/State.h @@ -2,5 +2,6 @@ enum State{ NORMAL, - SPIN + SPIN, + MOVE_TOWARDS, }; \ No newline at end of file