diff --git a/Crawler/Animation.cpp b/Crawler/Animation.cpp index 8961bc4d..97ad6b15 100644 --- a/Crawler/Animation.cpp +++ b/Crawler/Animation.cpp @@ -91,6 +91,17 @@ void sig::Animation::InitializeAnimations(){ //Ranger animations SetupClassWalkIdleAnimations(game->GFX_Ranger_Sheet,AnimationState::RANGER_WALK_S); + Animate2D::FrameSequence pl_ranger_shoot_s,pl_ranger_shoot_n,pl_ranger_shoot_e,pl_ranger_shoot_w; + for(int i=0;i<3;i++){ + pl_ranger_shoot_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,0}*24,{24,24}}}); + pl_ranger_shoot_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,1}*24,{24,24}}}); + pl_ranger_shoot_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,3}*24,{24,24}}}); + pl_ranger_shoot_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,2}*24,{24,24}}}); + } + ANIMATION_DATA[AnimationState::RANGER_SHOOT_S]=pl_ranger_shoot_s; + ANIMATION_DATA[AnimationState::RANGER_SHOOT_N]=pl_ranger_shoot_n; + ANIMATION_DATA[AnimationState::RANGER_SHOOT_E]=pl_ranger_shoot_e; + ANIMATION_DATA[AnimationState::RANGER_SHOOT_W]=pl_ranger_shoot_w; //Wizard animations SetupClassWalkIdleAnimations(game->GFX_Wizard_Sheet,AnimationState::WIZARD_WALK_S); @@ -184,7 +195,7 @@ void sig::Animation::InitializeAnimations(){ CreateHorizontalAnimationSequence(game->GFX_EnergyParticle,3,{3,3},AnimationState::ENERGY_PARTICLE); - CreateHorizontalAnimationSequence(game->GFX_Splash_Effect,5,{24,24},AnimationState::LIGHTNING_BOLT,{0.05}); + CreateHorizontalAnimationSequence(game->GFX_Splash_Effect,5,{24,24},AnimationState::SPLASH_EFFECT,{0.05}); CreateStillAnimation(game->GFX_BulletCircle,{3,3},AnimationState::DOT_PARTICLE); @@ -234,6 +245,10 @@ void sig::Animation::SetupPlayerAnimations(){ game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_E); game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_S); game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_W); + game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_S); + game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_N); + game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_W); + game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_E); game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_N); game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_E); game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_S); diff --git a/Crawler/Animation.h b/Crawler/Animation.h index ec908283..29895d95 100644 --- a/Crawler/Animation.h +++ b/Crawler/Animation.h @@ -22,7 +22,8 @@ enum AnimationState{ LIGHTNING_BOLT,LIGHTNING_BOLT_PARTICLE1,LIGHTNING_BOLT_PARTICLE2,LIGHTNING_BOLT_PARTICLE3,LIGHTNING_BOLT_PARTICLE4, CHAIN_LIGHTNING,LIGHTNING_SPLASH, WIZARD_CAST_S,WIZARD_CAST_N,WIZARD_CAST_E,WIZARD_CAST_W,METEOR, - FIRE_RING1,FIRE_RING2,FIRE_RING3,FIRE_RING4,FIRE_RING5,ARROW + FIRE_RING1,FIRE_RING2,FIRE_RING3,FIRE_RING4,FIRE_RING5,ARROW, + RANGER_SHOOT_S,RANGER_SHOOT_N,RANGER_SHOOT_E,RANGER_SHOOT_W, }; namespace sig{ diff --git a/Crawler/Arrow.cpp b/Crawler/Arrow.cpp new file mode 100644 index 00000000..8e7acb57 --- /dev/null +++ b/Crawler/Arrow.cpp @@ -0,0 +1,39 @@ +#include "BulletTypes.h" +#include "Effect.h" +#include "Crawler.h" +#include "DEFINES.h" +#include "utils.h" +#include "olcUTIL_Geometry2D.h" + +INCLUDE_game + +Arrow::Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) + :finalDistance(geom2d::line(pos,targetPos).length()), + Bullet(pos,vel,radius,damage, + AnimationState::ARROW,upperLevel,false,INFINITE,true,friendly,col){} + +void Arrow::Update(float fElapsedTime){ + float speed=vel.mag(); + travelDistance+=speed*fElapsedTime; + vel.y+=acc*fElapsedTime; + if(!deactivated&&travelDistance>=finalDistance){ + deactivated=true; + fadeOutTime=0.2f; + } +} + +bool Arrow::PlayerHit(Player*player) +{ + deactivated=true; + fadeOutTime=0.2f; + game->AddEffect(std::make_unique(player->GetPos(),0,AnimationState::SPLASH_EFFECT,upperLevel,player->GetSizeMult(),0.25)); + return false; +} + +bool Arrow::MonsterHit(Monster& monster) +{ + deactivated=true; + fadeOutTime=0.2f; + game->AddEffect(std::make_unique(monster.GetPos(),0,AnimationState::SPLASH_EFFECT,upperLevel,monster.GetSizeMult(),0.25)); + return false; +} \ No newline at end of file diff --git a/Crawler/Bullet.h b/Crawler/Bullet.h index 25ce5023..df959d6d 100644 --- a/Crawler/Bullet.h +++ b/Crawler/Bullet.h @@ -7,8 +7,8 @@ struct Bullet{ friend class Crawler; - vf2d pos; vf2d vel; + vf2d pos; float radius; int damage; Pixel col; @@ -17,11 +17,12 @@ struct Bullet{ bool rotates=false; bool animated=false; bool deactivated=false; //A deactivated bullet no longer interacts with the world. It's just a visual. - float fadeOutTime=0; + float fadeOutTime=0; //Setting the fade out time causes the bullet's lifetime to be set to the fadeout time as well, as that's when the bullet's alpha will reach 0, so it dies. bool friendly=false; //Whether or not it's a player bullet or enemy bullet. bool upperLevel=false; -private: +protected: float fadeOutTimer=0; +private: void UpdateFadeTime(float fElapsedTime); public: Animate2D::Animationanimation; @@ -38,6 +39,6 @@ public: //Return true when the bullet should be destroyed. Return false to handle it otherwise (like deactivating it instead). You become responsible for getting rid of the bullet. virtual bool MonsterHit(Monster&monster); Animate2D::Frame GetFrame(); - void Draw(); + virtual void Draw(); bool OnUpperLevel(); }; \ No newline at end of file diff --git a/Crawler/BulletTypes.h b/Crawler/BulletTypes.h index f14d4e0d..f8443c46 100644 --- a/Crawler/BulletTypes.h +++ b/Crawler/BulletTypes.h @@ -1,5 +1,6 @@ #pragma once #include "Bullet.h" +#include "olcPixelGameEngine.h" struct EnergyBolt:public Bullet{ float lastParticleSpawn=0; @@ -23,4 +24,14 @@ struct LightningBolt:public Bullet{ void Update(float fElapsedTime)override; bool PlayerHit(Player*player)override; bool MonsterHit(Monster&monster)override; +}; + +struct Arrow:public Bullet{ + float travelDistance=0; + float finalDistance=0; + float acc=PI/2*250; + Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE); + void Update(float fElapsedTime)override; + bool PlayerHit(Player*player)override; + bool MonsterHit(Monster&monster)override; }; \ No newline at end of file diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 935874dd..5e16e755 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -182,11 +182,14 @@ void Crawler::HandleUserInput(float fElapsedTime){ std::string staircaseDirection=GetPlayerStaircaseDirection(); if(RightHeld()){ player->SetX(player->GetX()+fElapsedTime*100*player->GetMoveSpdMult()); + player->movementVelocity.x=100; if(staircaseDirection=="RIGHT"){ player->SetY(player->GetY()-60*fElapsedTime*player->GetMoveSpdMult()); + player->movementVelocity.y=-60; } else if(staircaseDirection=="LEFT"){ player->SetY(player->GetY()+60*fElapsedTime*player->GetMoveSpdMult()); + player->movementVelocity.y=60; } player->SetFacingDirection(RIGHT); if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ @@ -196,11 +199,14 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(LeftHeld()){ player->SetX(player->GetX()-fElapsedTime*100*player->GetMoveSpdMult()); + player->movementVelocity.x=-100; if(staircaseDirection=="RIGHT"){ player->SetY(player->GetY()+60*fElapsedTime*player->GetMoveSpdMult()); + player->movementVelocity.y=60; } else if(staircaseDirection=="LEFT"){ player->SetY(player->GetY()-60*fElapsedTime*player->GetMoveSpdMult()); + player->movementVelocity.y=-60; } if(setIdleAnimation){ player->SetFacingDirection(LEFT); @@ -212,6 +218,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(UpHeld()){ player->SetY(player->GetY()-fElapsedTime*100*player->GetMoveSpdMult()); + player->movementVelocity.y=-100*fElapsedTime; if(setIdleAnimation){ player->SetFacingDirection(UP); if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ @@ -222,6 +229,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(DownHeld()){ player->SetY(player->GetY()+fElapsedTime*100*player->GetMoveSpdMult()); + player->movementVelocity.y=100*fElapsedTime; if(setIdleAnimation){ player->SetFacingDirection(DOWN); if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ @@ -233,6 +241,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(UpReleased()){ player->SetLastReleasedMovementKey(UP); + player->movementVelocity.y=0; if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(RightHeld()){ player->UpdateWalkingAnimation(RIGHT); @@ -247,6 +256,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(RightReleased()){ player->SetLastReleasedMovementKey(RIGHT); + player->movementVelocity.x=0; if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(UpHeld()){ player->UpdateWalkingAnimation(UP); @@ -261,6 +271,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(LeftReleased()){ player->SetLastReleasedMovementKey(LEFT); + player->movementVelocity.x=0; if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(RightHeld()){ player->UpdateWalkingAnimation(RIGHT); @@ -275,6 +286,7 @@ void Crawler::HandleUserInput(float fElapsedTime){ } if(DownReleased()){ player->SetLastReleasedMovementKey(DOWN); + player->movementVelocity.y=0; if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(RightHeld()){ player->UpdateWalkingAnimation(RIGHT); diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index 14353092..7352a8a7 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -203,6 +203,7 @@ + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index ed9898bc..0d282523 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -191,6 +191,9 @@ Source Files\Effects + + Source Files\Bullet Types + diff --git a/Crawler/EnergyBolt.cpp b/Crawler/EnergyBolt.cpp index fe8f787d..30374f4c 100644 --- a/Crawler/EnergyBolt.cpp +++ b/Crawler/EnergyBolt.cpp @@ -7,7 +7,8 @@ INCLUDE_game EnergyBolt::EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) -:Bullet(pos,vel,radius,damage,AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} +:Bullet(pos,vel,radius,damage, + AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} void EnergyBolt::Update(float fElapsedTime){ lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); diff --git a/Crawler/FireBolt.cpp b/Crawler/FireBolt.cpp index 6ab437a5..277b5809 100644 --- a/Crawler/FireBolt.cpp +++ b/Crawler/FireBolt.cpp @@ -8,7 +8,8 @@ INCLUDE_game INCLUDE_MONSTER_LIST FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) - :Bullet(pos,vel,radius,damage,AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} + :Bullet(pos,vel,radius,damage, + AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} void FireBolt::Update(float fElapsedTime){ lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); diff --git a/Crawler/LightningBolt.cpp b/Crawler/LightningBolt.cpp index b6430001..69cb861d 100644 --- a/Crawler/LightningBolt.cpp +++ b/Crawler/LightningBolt.cpp @@ -10,7 +10,8 @@ INCLUDE_MONSTER_LIST INCLUDE_EMITTER_LIST LightningBolt::LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) - :Bullet(pos,vel,radius,damage,AnimationState::LIGHTNING_BOLT,upperLevel,false,INFINITE,true,friendly,col){} + :Bullet(pos,vel,radius,damage, + AnimationState::LIGHTNING_BOLT,upperLevel,false,INFINITE,true,friendly,col){} void LightningBolt::Update(float fElapsedTime){ lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); diff --git a/Crawler/Player.h b/Crawler/Player.h index 7ee1e4bf..74cd8f71 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -49,9 +49,11 @@ struct Player{ void AddAnimation(AnimationState state); std::vectorbuffList; CastInfo castInfo={"",0}; + vf2d movementVelocity={};//This tells us if the player is moving (mostly controlled by user input) since their velocity is not used for regular movement. protected: const float ATTACK_COOLDOWN=0.35f; const float MAGIC_ATTACK_COOLDOWN=0.85f; + const float ARROW_ATTACK_COOLDOWN=0.6f; void SetSwordSwingTimer(float val); void SetState(State newState); void SetFacingDirection(Key direction); diff --git a/Crawler/Ranger.cpp b/Crawler/Ranger.cpp index 56833a13..e2744a3b 100644 --- a/Crawler/Ranger.cpp +++ b/Crawler/Ranger.cpp @@ -4,6 +4,7 @@ #include "Player.h" #include "Effect.h" #include "Crawler.h" +#include "BulletTypes.h" INCLUDE_MONSTER_LIST INCLUDE_BULLET_LIST @@ -28,12 +29,35 @@ AnimationState Ranger::walk_w=RANGER_WALK_W; SETUP_CLASS(Ranger) void Ranger::OnUpdate(float fElapsedTime){ - + if(GetState()==SHOOT_ARROW){ + if(attack_cooldown_timer<=ARROW_ATTACK_COOLDOWN-0.3){ + SetState(NORMAL); + } + } } bool Ranger::AutoAttack(){ + attack_cooldown_timer=ARROW_ATTACK_COOLDOWN; + geom2d::line pointTowardsCursor(GetPos(),game->GetWorldMousePos()); + vf2d extendedLine=pointTowardsCursor.upoint(1.1); + float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x); + BULLET_LIST.push_back(std::make_unique(Arrow(GetPos(),extendedLine,vf2d{cos(angleToCursor)*250,float(sin(angleToCursor)*250-PI/8*250)}+movementVelocity,12,GetAttack(),OnUpperLevel(),true))); + SetState(State::SHOOT_ARROW); + if(angleToCursor<=PI/4&&angleToCursor>-PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_E); + } else + if(angleToCursor>=3*PI/4||angleToCursor<-3*PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_W); + } else + if(angleToCursor<=3*PI/4&&angleToCursor>PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_S); + } else + if(angleToCursor>=-3*PI/4&&angleToCursor<-PI/4){ + UpdateAnimation(AnimationState::RANGER_SHOOT_N); + } return false; } + void Ranger::InitializeClassAbilities(){ #pragma region Ranger Right-click Ability (???) Ranger::rightClickAbility.action= diff --git a/Crawler/State.h b/Crawler/State.h index 1f73640d..4e253205 100644 --- a/Crawler/State.h +++ b/Crawler/State.h @@ -12,4 +12,5 @@ enum State{ PATH_AROUND, CASTING, PREP_CAST, + SHOOT_ARROW, }; \ No newline at end of file diff --git a/Crawler/Version.h b/Crawler/Version.h index 3efcae18..9a75624e 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 769 +#define VERSION_BUILD 803 #define stringify(a) stringify_(a) #define stringify_(a) #a