diff --git a/Crawler/Animation.h b/Crawler/Animation.h index 96157475..9630d980 100644 --- a/Crawler/Animation.h +++ b/Crawler/Animation.h @@ -7,4 +7,5 @@ enum AnimationState{ BLUE_SLIME_IDLE,BLUE_SLIME_ROLL,BLUE_SLIME_JUMP,BLUE_SLIME_SPIT,BLUE_SLIME_DIE, RED_SLIME_IDLE,RED_SLIME_ROLL,RED_SLIME_JUMP,RED_SLIME_SPIT,RED_SLIME_DIE, YELLOW_SLIME_IDLE,YELLOW_SLIME_ROLL,YELLOW_SLIME_JUMP,YELLOW_SLIME_SPIT,YELLOW_SLIME_DIE, + GROUND_SLAM_ATTACK_BACK,GROUND_SLAM_ATTACK_FRONT, }; \ No newline at end of file diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 702c7ce7..f6fe667f 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -29,6 +29,8 @@ bool Crawler::OnUserCreate(){ GFX_Pl_Sheet.Load("assets/nico-warrior.png"); GFX_Slime_Sheet.Load("assets/slime.png"); GFX_Circle.Load("assets/circle.png"); + GFX_Effect_GroundSlam_Back.Load("assets/ground-slam-attack-back.png"); + GFX_Effect_GroundSlam_Front.Load("assets/ground-slam-attack-front.png"); //Animations InitializeAnimations(); @@ -52,6 +54,7 @@ bool Crawler::OnUserCreate(){ bool Crawler::OnUserUpdate(float fElapsedTime){ HandleUserInput(fElapsedTime); + UpdateEffects(fElapsedTime); player.Update(fElapsedTime); for(Monster&m:MONSTER_LIST){ m.Update(fElapsedTime); @@ -111,11 +114,18 @@ void Crawler::InitializeAnimations(){ ANIMATION_DATA[AnimationState(AnimationState::GREEN_SLIME_IDLE+state+slime*5)]=anim; } } + Animate2D::FrameSequence effect_groundslam_back(0.02f,Animate2D::Style::OneShot),effect_groundslam_front(0.02f,Animate2D::Style::OneShot); + for(int i=0;i<5;i++){ + effect_groundslam_back.AddFrame({&GFX_Effect_GroundSlam_Back,{{i*64,0},{64,64}}}); + effect_groundslam_front.AddFrame({&GFX_Effect_GroundSlam_Front,{{i*64,0},{64,64}}}); + } + ANIMATION_DATA[AnimationState::GROUND_SLAM_ATTACK_BACK]=effect_groundslam_back; + ANIMATION_DATA[AnimationState::GROUND_SLAM_ATTACK_FRONT]=effect_groundslam_front; } void Crawler::HandleUserInput(float fElapsedTime){ bool setIdleAnimation=true; - if(GetKey(SPACE).bPressed){ + if(GetKey(SPACE).bPressed&&player.GetState()==State::NORMAL){ player.Spin(Player::GROUND_SLAM_SPIN_TIME,14*PI); } if(GetKey(RIGHT).bHeld){ @@ -182,55 +192,55 @@ void Crawler::HandleUserInput(float fElapsedTime){ if(GetKey(UP).bHeld){ player.UpdateAnimation(AnimationState::WALK_N); } else - if(GetKey(DOWN).bHeld){ - player.UpdateAnimation(AnimationState::WALK_S); - } else - if(GetKey(LEFT).bHeld){ - player.UpdateAnimation(AnimationState::WALK_W); - } + if(GetKey(DOWN).bHeld){ + player.UpdateAnimation(AnimationState::WALK_S); + } else + if(GetKey(LEFT).bHeld){ + player.UpdateAnimation(AnimationState::WALK_W); + } } if(GetKey(LEFT).bReleased){ player.SetLastReleasedMovementKey(LEFT); if(GetKey(RIGHT).bHeld){ player.UpdateAnimation(AnimationState::WALK_E); } else - if(GetKey(DOWN).bHeld){ - player.UpdateAnimation(AnimationState::WALK_S); - } else - if(GetKey(UP).bHeld){ - player.UpdateAnimation(AnimationState::WALK_N); - } + if(GetKey(DOWN).bHeld){ + player.UpdateAnimation(AnimationState::WALK_S); + } else + if(GetKey(UP).bHeld){ + player.UpdateAnimation(AnimationState::WALK_N); + } } if(GetKey(DOWN).bReleased){ player.SetLastReleasedMovementKey(DOWN); if(GetKey(RIGHT).bHeld){ player.UpdateAnimation(AnimationState::WALK_E); } else - if(GetKey(UP).bHeld){ - player.UpdateAnimation(AnimationState::WALK_N); - } else - if(GetKey(LEFT).bHeld){ - player.UpdateAnimation(AnimationState::WALK_W); - } + if(GetKey(UP).bHeld){ + player.UpdateAnimation(AnimationState::WALK_N); + } else + if(GetKey(LEFT).bHeld){ + player.UpdateAnimation(AnimationState::WALK_W); + } } if(setIdleAnimation){ switch(player.GetLastReleasedMovementKey()){ - case UP:{ - player.UpdateAnimation(AnimationState::IDLE_N); - }break; - case DOWN:{ - player.UpdateAnimation(AnimationState::IDLE_S); - }break; - case LEFT:{ - player.UpdateAnimation(AnimationState::IDLE_W); - }break; - case RIGHT:{ - player.UpdateAnimation(AnimationState::IDLE_E); - }break; - default:{ - player.UpdateAnimation(AnimationState::IDLE_S); - } + case UP:{ + player.UpdateAnimation(AnimationState::IDLE_N); + }break; + case DOWN:{ + player.UpdateAnimation(AnimationState::IDLE_S); + }break; + case LEFT:{ + player.UpdateAnimation(AnimationState::IDLE_W); + }break; + case RIGHT:{ + player.UpdateAnimation(AnimationState::IDLE_E); + }break; + default:{ + player.UpdateAnimation(AnimationState::IDLE_S); + } } } else { //We have moved. @@ -243,6 +253,27 @@ void Crawler::UpdateCamera(float fElapsedTime){ view.SetWorldOffset(vi2d(camera.GetViewPosition())); } +void Crawler::UpdateEffects(float fElapsedTime){ + for(std::vector::iterator it=backgroundEffects.begin();it!=backgroundEffects.end();++it){ + Effect&e=*it; + if(!e.Update(fElapsedTime)){ + it=backgroundEffects.erase(it); + if(it==backgroundEffects.end()){ + break; + } + } + } + for(std::vector::iterator it=foregroundEffects.begin();it!=foregroundEffects.end();++it){ + Effect&e=*it; + if(!e.Update(fElapsedTime)){ + it=foregroundEffects.erase(it); + if(it==foregroundEffects.end()){ + break; + } + } + } +} + void Crawler::RenderWorld(float fElapsedTime){ Clear({100,180,100}); for (int x = view.GetTopLeftTile().x/24-1; x <= view.GetBottomRightTile().x/24; x++){ @@ -260,6 +291,9 @@ void Crawler::RenderWorld(float fElapsedTime){ vf2d shadowScale=vf2d{8/3.f,1}/std::max(1.f,player.GetZ()/4); view.DrawDecal(player.GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6},GFX_Circle.Decal(),shadowScale); } + for(Effect&e:backgroundEffects){ + e.Draw(); + } for(Monster&m:monstersBefore){ 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())); } @@ -267,6 +301,9 @@ void Crawler::RenderWorld(float fElapsedTime){ 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())); } + for(Effect&e:foregroundEffects){ + e.Draw(); + } for(std::vector::iterator it=DAMAGENUMBER_LIST.begin();it!=DAMAGENUMBER_LIST.end();++it){ DamageNumber&dn=*it; dn.lifeTime+=fElapsedTime; @@ -283,6 +320,11 @@ void Crawler::RenderWorld(float fElapsedTime){ } } +void Crawler::AddEffect(Effect foreground,Effect background){ + foregroundEffects.push_back(foreground); + backgroundEffects.push_back(background); +} + int main() { Crawler demo; diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index d23f41a7..b544f614 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -6,24 +6,28 @@ #include "olcPGEX_TransformedView.h" #include "Player.h" #include "olcUTIL_Camera2D.h" - +#include "Effect.h" class Crawler : public olc::PixelGameEngine { const vi2d WORLD_SIZE={64,8}; Camera2D camera; - TileTransformedView view; Player player; - Renderable GFX_Pl_Sheet,GFX_Slime_Sheet,GFX_Circle; + Renderable GFX_Pl_Sheet,GFX_Slime_Sheet,GFX_Circle, + GFX_Effect_GroundSlam_Back,GFX_Effect_GroundSlam_Front; + std::vectorforegroundEffects,backgroundEffects; public: Crawler(); public: + TileTransformedView view; bool OnUserCreate() override; bool OnUserUpdate(float fElapsedTime) override; void InitializeAnimations(); void HandleUserInput(float fElapsedTime); void UpdateCamera(float fElapsedTime); + void UpdateEffects(float fElapsedTime); void RenderWorld(float fElapsedTime); + void AddEffect(Effect foreground,Effect background); }; \ No newline at end of file diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index fcaa6f1a..88f5a0c6 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -132,6 +132,8 @@ + + @@ -144,11 +146,15 @@ + + + + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index 172ceeb8..f51f3b17 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -48,6 +48,12 @@ Header Files + + Header Files + + + Header Files + @@ -68,5 +74,11 @@ Source Files + + Source Files + + + + \ No newline at end of file diff --git a/Crawler/DEFINES.h b/Crawler/DEFINES.h new file mode 100644 index 00000000..3982e148 --- /dev/null +++ b/Crawler/DEFINES.h @@ -0,0 +1,7 @@ +#pragma once +#define INCLUDE_ANIMATION_DATA extern std::mapANIMATION_DATA; +#define INCLUDE_MONSTER_LIST extern std::vectorMONSTER_LIST; +#define INCLUDE_SPAWNER_LIST extern std::vectorSPAWNER_LIST; +#define INCLUDE_DAMAGENUMBER_LIST extern std::vectorDAMAGENUMBER_LIST; +#define INCLUDE_game extern Crawler*game; +#define INCLUDE_MONSTER_DATA extern std::mapMONSTER_DATA; \ No newline at end of file diff --git a/Crawler/Effect.cpp b/Crawler/Effect.cpp new file mode 100644 index 00000000..a0422196 --- /dev/null +++ b/Crawler/Effect.cpp @@ -0,0 +1,34 @@ +#include "DEFINES.h" +#include "Effect.h" +#include "Crawler.h" + +INCLUDE_ANIMATION_DATA +INCLUDE_game + +Effect::Effect(vf2d pos,float lifetime,AnimationState animation,float fadeout) + :pos(pos),lifetime(lifetime),fadeout(fadeout),original_fadeoutTime(fadeout){ + this->animation.AddState(animation,ANIMATION_DATA[animation]); +} + +bool Effect::Update(float fElapsedTime){ + lifetime-=fElapsedTime; + if(lifetime<=0){ + fadeout-=fElapsedTime; + if(fadeout<=0){ + return false; + } + } + animation.UpdateState(internal_animState,fElapsedTime); +} + +void Effect::Draw(){ + if(fadeout==0){ + game->view.DrawPartialDecal(pos-GetFrame().GetSourceRect().size/2,GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size); + } else { + game->view.DrawPartialDecal(pos-GetFrame().GetSourceRect().size/2,GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,{1,1},{255,255,255,uint8_t(fadeout/original_fadeoutTime*255)}); + } +} + +Animate2D::Frame Effect::GetFrame(){ + return animation.GetFrame(internal_animState); +} \ No newline at end of file diff --git a/Crawler/Effect.h b/Crawler/Effect.h new file mode 100644 index 00000000..cef323ec --- /dev/null +++ b/Crawler/Effect.h @@ -0,0 +1,18 @@ +#pragma once +#include "olcPixelGameEngine.h" +#include "Animation.h" +#include "olcUTIL_Animate2D.h" + +struct Effect{ + vf2d pos; + float lifetime; + float fadeout; + Effect(vf2d pos,float lifetime,AnimationState animation,float fadeout=0.0f); + bool Update(float fElapsedTime); + Animate2D::Frame GetFrame(); + void Draw(); +private: + Animate2D::Animationanimation; + Animate2D::AnimationState internal_animState; + float original_fadeoutTime; +}; \ No newline at end of file diff --git a/Crawler/Monster.h b/Crawler/Monster.h index df0e2894..40ed98af 100644 --- a/Crawler/Monster.h +++ b/Crawler/Monster.h @@ -26,7 +26,7 @@ struct MonsterData{ MonsterName type; public: MonsterData(); - //When specifying animations, the first one will become the default 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::vectoranimations,float moveSpd=1.0f,float size=1.0f,MonsterStrategy strategy=RUN_TOWARDS); int GetHealth(); int GetAttack(); diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index 17e2c265..1c45f43c 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -2,14 +2,14 @@ #include "Player.h" #include "Crawler.h" #include "DamageNumber.h" +#include "DEFINES.h" - -extern std::mapMONSTER_DATA; -extern std::vectorMONSTER_LIST; -extern std::mapANIMATION_DATA; -extern std::vectorSPAWNER_LIST; -extern std::vectorDAMAGENUMBER_LIST; -extern Crawler*game; +INCLUDE_MONSTER_DATA +INCLUDE_MONSTER_LIST +INCLUDE_ANIMATION_DATA +INCLUDE_SPAWNER_LIST +INCLUDE_DAMAGENUMBER_LIST +INCLUDE_game const float Player::GROUND_SLAM_SPIN_TIME=0.6f; @@ -116,6 +116,7 @@ void Player::Update(float fElapsedTime){ state=NORMAL; spin_angle=0; z=0; + game->AddEffect(Effect{GetPos(),0.5,AnimationState::GROUND_SLAM_ATTACK_FRONT,0.6f},Effect{GetPos(),0.5,AnimationState::GROUND_SLAM_ATTACK_BACK,0.6f}); } if(lastAnimationFlip>0){ lastAnimationFlip=std::max(0.f,lastAnimationFlip-fElapsedTime); diff --git a/Crawler/assets/ground-slam-attack-back.png b/Crawler/assets/ground-slam-attack-back.png index 6ab95445..dda8c396 100644 Binary files a/Crawler/assets/ground-slam-attack-back.png and b/Crawler/assets/ground-slam-attack-back.png differ diff --git a/Crawler/assets/ground-slam-attack-front.png b/Crawler/assets/ground-slam-attack-front.png index 612bcf47..bc4a19e3 100644 Binary files a/Crawler/assets/ground-slam-attack-front.png and b/Crawler/assets/ground-slam-attack-front.png differ diff --git a/Crawler/cpp.hint b/Crawler/cpp.hint new file mode 100644 index 00000000..964b58aa --- /dev/null +++ b/Crawler/cpp.hint @@ -0,0 +1,9 @@ +// Hint files help the Visual Studio IDE interpret Visual C++ identifiers +// such as names of functions and macros. +// For more information see https://go.microsoft.com/fwlink/?linkid=865984 +#define INCLUDE_ANIMATION_DATA +#define INCLUDE_SPAWNER_LIST +#define INCLUDE_DAMAGENUMBER_LIST +#define INCLUDE_game +#define INCLUDE_MONSTER_LIST +#define INCLUDE_MONSTER_DATA