Implement ground slam animation

pull/28/head
sigonasr2 1 year ago
parent 515c74aa9f
commit 7e543a3021
  1. 1
      Crawler/Animation.h
  2. 44
      Crawler/Crawler.cpp
  3. 10
      Crawler/Crawler.h
  4. 6
      Crawler/Crawler.vcxproj
  5. 12
      Crawler/Crawler.vcxproj.filters
  6. 7
      Crawler/DEFINES.h
  7. 34
      Crawler/Effect.cpp
  8. 18
      Crawler/Effect.h
  9. 2
      Crawler/Monster.h
  10. 15
      Crawler/Player.cpp
  11. BIN
      Crawler/assets/ground-slam-attack-back.png
  12. BIN
      Crawler/assets/ground-slam-attack-front.png
  13. 9
      Crawler/cpp.hint

@ -7,4 +7,5 @@ enum AnimationState{
BLUE_SLIME_IDLE,BLUE_SLIME_ROLL,BLUE_SLIME_JUMP,BLUE_SLIME_SPIT,BLUE_SLIME_DIE, 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, 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, YELLOW_SLIME_IDLE,YELLOW_SLIME_ROLL,YELLOW_SLIME_JUMP,YELLOW_SLIME_SPIT,YELLOW_SLIME_DIE,
GROUND_SLAM_ATTACK_BACK,GROUND_SLAM_ATTACK_FRONT,
}; };

@ -29,6 +29,8 @@ bool Crawler::OnUserCreate(){
GFX_Pl_Sheet.Load("assets/nico-warrior.png"); GFX_Pl_Sheet.Load("assets/nico-warrior.png");
GFX_Slime_Sheet.Load("assets/slime.png"); GFX_Slime_Sheet.Load("assets/slime.png");
GFX_Circle.Load("assets/circle.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 //Animations
InitializeAnimations(); InitializeAnimations();
@ -52,6 +54,7 @@ bool Crawler::OnUserCreate(){
bool Crawler::OnUserUpdate(float fElapsedTime){ bool Crawler::OnUserUpdate(float fElapsedTime){
HandleUserInput(fElapsedTime); HandleUserInput(fElapsedTime);
UpdateEffects(fElapsedTime);
player.Update(fElapsedTime); player.Update(fElapsedTime);
for(Monster&m:MONSTER_LIST){ for(Monster&m:MONSTER_LIST){
m.Update(fElapsedTime); m.Update(fElapsedTime);
@ -111,11 +114,18 @@ void Crawler::InitializeAnimations(){
ANIMATION_DATA[AnimationState(AnimationState::GREEN_SLIME_IDLE+state+slime*5)]=anim; 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){ void Crawler::HandleUserInput(float fElapsedTime){
bool setIdleAnimation=true; bool setIdleAnimation=true;
if(GetKey(SPACE).bPressed){ if(GetKey(SPACE).bPressed&&player.GetState()==State::NORMAL){
player.Spin(Player::GROUND_SLAM_SPIN_TIME,14*PI); player.Spin(Player::GROUND_SLAM_SPIN_TIME,14*PI);
} }
if(GetKey(RIGHT).bHeld){ if(GetKey(RIGHT).bHeld){
@ -243,6 +253,27 @@ void Crawler::UpdateCamera(float fElapsedTime){
view.SetWorldOffset(vi2d(camera.GetViewPosition())); view.SetWorldOffset(vi2d(camera.GetViewPosition()));
} }
void Crawler::UpdateEffects(float fElapsedTime){
for(std::vector<Effect>::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<Effect>::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){ 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++){
@ -260,6 +291,9 @@ void Crawler::RenderWorld(float fElapsedTime){
vf2d shadowScale=vf2d{8/3.f,1}/std::max(1.f,player.GetZ()/4); 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); 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){ 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())); 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){ 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())); 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<DamageNumber>::iterator it=DAMAGENUMBER_LIST.begin();it!=DAMAGENUMBER_LIST.end();++it){ for(std::vector<DamageNumber>::iterator it=DAMAGENUMBER_LIST.begin();it!=DAMAGENUMBER_LIST.end();++it){
DamageNumber&dn=*it; DamageNumber&dn=*it;
dn.lifeTime+=fElapsedTime; 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() int main()
{ {
Crawler demo; Crawler demo;

@ -6,24 +6,28 @@
#include "olcPGEX_TransformedView.h" #include "olcPGEX_TransformedView.h"
#include "Player.h" #include "Player.h"
#include "olcUTIL_Camera2D.h" #include "olcUTIL_Camera2D.h"
#include "Effect.h"
class Crawler : public olc::PixelGameEngine class Crawler : public olc::PixelGameEngine
{ {
const vi2d WORLD_SIZE={64,8}; const vi2d WORLD_SIZE={64,8};
Camera2D camera; Camera2D camera;
TileTransformedView view;
Player player; 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::vector<Effect>foregroundEffects,backgroundEffects;
public: public:
Crawler(); Crawler();
public: public:
TileTransformedView view;
bool OnUserCreate() override; bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override; bool OnUserUpdate(float fElapsedTime) override;
void InitializeAnimations(); void InitializeAnimations();
void HandleUserInput(float fElapsedTime); void HandleUserInput(float fElapsedTime);
void UpdateCamera(float fElapsedTime); void UpdateCamera(float fElapsedTime);
void UpdateEffects(float fElapsedTime);
void RenderWorld(float fElapsedTime); void RenderWorld(float fElapsedTime);
void AddEffect(Effect foreground,Effect background);
}; };

@ -132,6 +132,8 @@
<ClInclude Include="Animation.h" /> <ClInclude Include="Animation.h" />
<ClInclude Include="Crawler.h" /> <ClInclude Include="Crawler.h" />
<ClInclude Include="DamageNumber.h" /> <ClInclude Include="DamageNumber.h" />
<ClInclude Include="DEFINES.h" />
<ClInclude Include="Effect.h" />
<ClInclude Include="Monster.h" /> <ClInclude Include="Monster.h" />
<ClInclude Include="olcPGEX_TransformedView.h" /> <ClInclude Include="olcPGEX_TransformedView.h" />
<ClInclude Include="olcPixelGameEngine.h" /> <ClInclude Include="olcPixelGameEngine.h" />
@ -144,11 +146,15 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="Crawler.cpp" /> <ClCompile Include="Crawler.cpp" />
<ClCompile Include="DamageNumber.cpp" /> <ClCompile Include="DamageNumber.cpp" />
<ClCompile Include="Effect.cpp" />
<ClCompile Include="pixelGameEngine.cpp" /> <ClCompile Include="pixelGameEngine.cpp" />
<ClCompile Include="Player.cpp" /> <ClCompile Include="Player.cpp" />
<ClCompile Include="Monster.cpp" /> <ClCompile Include="Monster.cpp" />
<ClCompile Include="MonsterData.cpp" /> <ClCompile Include="MonsterData.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

@ -48,6 +48,12 @@
<ClInclude Include="State.h"> <ClInclude Include="State.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Effect.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DEFINES.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Player.cpp"> <ClCompile Include="Player.cpp">
@ -68,5 +74,11 @@
<ClCompile Include="pixelGameEngine.cpp"> <ClCompile Include="pixelGameEngine.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Effect.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -0,0 +1,7 @@
#pragma once
#define INCLUDE_ANIMATION_DATA extern std::map<AnimationState,Animate2D::FrameSequence>ANIMATION_DATA;
#define INCLUDE_MONSTER_LIST extern std::vector<Monster>MONSTER_LIST;
#define INCLUDE_SPAWNER_LIST extern std::vector<MonsterSpawner>SPAWNER_LIST;
#define INCLUDE_DAMAGENUMBER_LIST extern std::vector<DamageNumber>DAMAGENUMBER_LIST;
#define INCLUDE_game extern Crawler*game;
#define INCLUDE_MONSTER_DATA extern std::map<MonsterName,MonsterData>MONSTER_DATA;

@ -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);
}

@ -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::Animation<AnimationState>animation;
Animate2D::AnimationState internal_animState;
float original_fadeoutTime;
};

@ -26,7 +26,7 @@ struct MonsterData{
MonsterName type; MonsterName type;
public: public:
MonsterData(); 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::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 GetHealth(); int GetHealth();
int GetAttack(); int GetAttack();

@ -2,14 +2,14 @@
#include "Player.h" #include "Player.h"
#include "Crawler.h" #include "Crawler.h"
#include "DamageNumber.h" #include "DamageNumber.h"
#include "DEFINES.h"
INCLUDE_MONSTER_DATA
extern std::map<MonsterName,MonsterData>MONSTER_DATA; INCLUDE_MONSTER_LIST
extern std::vector<Monster>MONSTER_LIST; INCLUDE_ANIMATION_DATA
extern std::map<AnimationState,Animate2D::FrameSequence>ANIMATION_DATA; INCLUDE_SPAWNER_LIST
extern std::vector<MonsterSpawner>SPAWNER_LIST; INCLUDE_DAMAGENUMBER_LIST
extern std::vector<DamageNumber>DAMAGENUMBER_LIST; INCLUDE_game
extern Crawler*game;
const float Player::GROUND_SLAM_SPIN_TIME=0.6f; const float Player::GROUND_SLAM_SPIN_TIME=0.6f;
@ -116,6 +116,7 @@ void Player::Update(float fElapsedTime){
state=NORMAL; state=NORMAL;
spin_angle=0; spin_angle=0;
z=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){ if(lastAnimationFlip>0){
lastAnimationFlip=std::max(0.f,lastAnimationFlip-fElapsedTime); lastAnimationFlip=std::max(0.f,lastAnimationFlip-fElapsedTime);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 912 B

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 812 B

After

Width:  |  Height:  |  Size: 10 KiB

@ -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
Loading…
Cancel
Save