From e090bc775d8e3505c95dfee08eac17851e47bbbc Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sat, 17 Jun 2023 21:19:08 -0500 Subject: [PATCH] Implemented blocking. Made player abilities dynamic instead of fixed for class expansion preparation. --- Crawler/Ability.cpp | 5 +++ Crawler/Ability.h | 11 ++++++ Crawler/Crawler.cpp | 50 +++++++++++++++++++---- Crawler/Crawler.h | 2 +- Crawler/Crawler.vcxproj | 6 +++ Crawler/Crawler.vcxproj.filters | 16 +++++++- Crawler/NewClasses.txt | 68 ++++++++++++++++++++++++++++++++ Crawler/Player.cpp | 42 ++++++++++++++------ Crawler/Player.h | 8 ++-- Crawler/State.h | 1 + Crawler/assets/block.png | Bin 0 -> 668 bytes 11 files changed, 183 insertions(+), 26 deletions(-) create mode 100644 Crawler/Ability.cpp create mode 100644 Crawler/Ability.h create mode 100644 Crawler/NewClasses.txt create mode 100644 Crawler/assets/block.png diff --git a/Crawler/Ability.cpp b/Crawler/Ability.cpp new file mode 100644 index 00000000..b2421a81 --- /dev/null +++ b/Crawler/Ability.cpp @@ -0,0 +1,5 @@ +#include "Ability.h" + +Ability::Ability(){}; +Ability::Ability(std::string name,float cooldownTime,Pixel barColor1,Pixel barColor2) + :name(name),cooldown(0),COOLDOWN_TIME(cooldownTime),barColor1(barColor1),barColor2(barColor2){} \ No newline at end of file diff --git a/Crawler/Ability.h b/Crawler/Ability.h new file mode 100644 index 00000000..0bee6507 --- /dev/null +++ b/Crawler/Ability.h @@ -0,0 +1,11 @@ +#pragma once +#include "olcPixelGameEngine.h" + +struct Ability{ + std::string name=""; + float cooldown=0; + float COOLDOWN_TIME=0; + Pixel barColor1,barColor2; + Ability(); + Ability(std::string name,float cooldownTime,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED); +}; \ No newline at end of file diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index ef1832b9..8f4ac291 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -3,6 +3,7 @@ #include "olcUTIL_Camera2D.h" #include "DamageNumber.h" #include "Bullet.h" +#include "Ability.h" #include "DEFINES.h" //192x192 @@ -35,6 +36,7 @@ bool Crawler::OnUserCreate(){ GFX_Effect_GroundSlam_Back.Load("assets/ground-slam-attack-back.png"); GFX_Effect_GroundSlam_Front.Load("assets/ground-slam-attack-front.png"); GFX_Heart.Load("assets/heart.png"); + GFX_BLOCK_BUBBLE.Load("assets/block.png"); //Animations InitializeAnimations(); @@ -221,9 +223,9 @@ bool Crawler::DownReleased(){ void Crawler::HandleUserInput(float fElapsedTime){ bool setIdleAnimation=true; - if(GetKey(SPACE).bPressed&&player.GetState()==State::NORMAL&&player.GetGroundSlamCooldown()==0){ + if(GetKey(SPACE).bPressed&&player.GetAbility2Cooldown()==0){ player.Spin(Player::GROUND_SLAM_SPIN_TIME,14*PI); - player.iframe_time=Player::GROUND_SLAM_SPIN_TIME; + player.iframe_time=Player::GROUND_SLAM_SPIN_TIME+0.1; } if(player.GetVelocity()==vf2d{0,0}){ if(RightHeld()){ @@ -361,6 +363,10 @@ void Crawler::HandleUserInput(float fElapsedTime){ } } + if(player.GetState()==State::BLOCK){ + setIdleAnimation=false; + } + if(setIdleAnimation){ switch(player.GetLastReleasedMovementKey()){ case UP:{ @@ -464,6 +470,9 @@ void Crawler::RenderWorld(float fElapsedTime){ 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())); + if(player.GetState()==State::BLOCK){ + view.DrawDecal(player.GetPos()-vf2d{12,12},GFX_BLOCK_BUBBLE.Decal()); + } for(Monster&m:monstersAfter){ m.Draw(); } @@ -497,12 +506,37 @@ Player&Crawler::GetPlayer(){ } void Crawler::RenderHud(){ - if(player.GetGroundSlamCooldown()>0){ - FillRectDecal({10,ScreenHeight()-22.f},{64,6},BLACK); - FillRectDecal({11,ScreenHeight()-21.f},{62,4},DARK_GREY); - GradientFillRectDecal({10,ScreenHeight()-22.f},{(player.GetGroundSlamCooldown()/Player::GROUND_SLAM_COOLDOWN)*64,6},VERY_DARK_RED,VERY_DARK_RED,DARK_RED,DARK_RED); - DrawRotatedStringPropDecal(vf2d{8,ScreenHeight()-20.f}+vf2d{1,1},"G R O U N D S L A M",-PI/64,{0,0},BLACK,{0.4,0.4}); - DrawRotatedStringPropDecal({8,ScreenHeight()-20.f},"G R O U N D S L A M",-PI/64,{0,0},WHITE,{0.4,0.4}); + const std::functioncapitalize=[](std::string name)->std::string{ + std::string newName=""; + for(int i=0;i='a'?name[i]-32:name[i]); + newName.append(1,' '); + } + return newName; + }; + std::vectorcooldowns{ + player.rightClickAbility, + player.ability1, + player.ability2, + player.ability3 + }; + std::vectoractiveCooldowns; + std::copy_if(cooldowns.begin(),cooldowns.end(),std::back_inserter(activeCooldowns),[](Ability a){ + return a.cooldown>0; + }); + std::sort(activeCooldowns.begin(),activeCooldowns.end(),[](Ability&a1,Ability&a2){ + return a1.cooldown0){ + FillRectDecal(vf2d{10,ScreenHeight()-22.f}-vf2d{0,float(offset)},{64,6},BLACK); + FillRectDecal(vf2d{11,ScreenHeight()-21.f}-vf2d{0,float(offset)},{62,4},DARK_GREY); + GradientFillRectDecal(vf2d{10,ScreenHeight()-22.f}-vf2d{0,float(offset)},{(a.cooldown/a.COOLDOWN_TIME)*64,6},a.barColor1,a.barColor1,a.barColor2,a.barColor2); + DrawRotatedStringPropDecal(vf2d{8,ScreenHeight()-20.f}+vf2d{1,1}-vf2d{0,float(offset)},capitalize(a.name),-PI/64,{0,0},BLACK,{0.4,0.4}); + DrawRotatedStringPropDecal(vf2d{8,ScreenHeight()-20.f}-vf2d{0,float(offset)},capitalize(a.name),-PI/64,{0,0},WHITE,{0.4,0.4}); + } + offset-=6; } DrawDecal({2,2},GFX_Heart.Decal()); std::string text=player.GetHealth()>0?std::to_string(player.GetHealth()):"X"; diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index 799d216d..c8190bf8 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -14,7 +14,7 @@ class Crawler : public olc::PixelGameEngine Player player; Renderable GFX_Pl_Sheet,GFX_Slime_Sheet,GFX_Circle, GFX_Effect_GroundSlam_Back,GFX_Effect_GroundSlam_Front, - GFX_Heart; + GFX_Heart,GFX_BLOCK_BUBBLE; std::vectorforegroundEffects,backgroundEffects; public: diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index f243dfb7..f1b26c1d 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -129,6 +129,7 @@ + @@ -145,6 +146,7 @@ + @@ -157,6 +159,10 @@ + + + + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index 324d05a1..2699abb8 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -9,7 +9,7 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms @@ -57,6 +57,9 @@ Header Files + + Header Files + @@ -83,8 +86,19 @@ Source Files + + Source Files + + + + Documentation + + + Documentation + + \ No newline at end of file diff --git a/Crawler/NewClasses.txt b/Crawler/NewClasses.txt new file mode 100644 index 00000000..8866310b --- /dev/null +++ b/Crawler/NewClasses.txt @@ -0,0 +1,68 @@ +Warrior +Rightclick - Block +1 - Battlecry +10% Attack buff, -10% dmg taken for 10s +Nearby Enemies with size smaller or equal to 100% will receive a Movespd debuff of 30% for 5 seconds. (350 Range) +12sec. cd +40 mana +2 - Ground Slam +dmg: 4x Atk +15 sec. cd +50 Mana +3 - Sonic Slash +Shoots a half moon that damage everything it passes +Dmg: 8x Atk +60 Mana +Size of Projectile: 250 +Range: 900 +40 sec. cd + +Warrior should not be able to run out of mana. Mana only stands in the way of using all 3 skills at the same time. +the Battlecry slow is primarly ment to make it easier to catch up with range units that run away, at the moment warrior probably has the hardest time dealing with mosnters that run. + + +Ranger +Rightclick - Retreat +Backwardsjump +leap 250 Range backwards. +cd 7 seconds. +1 Rapid fire +Shoots 4 auto hits with 0.1 sec delay between each shot. Animation locked +Normal auto hit Damage (x4) +12 sec cd. +2 Charged shot +35 Mana +Shots an arrow that does Pierce dmg. 0.3 charge animation lock +Damage: 2.5x Atk +15 sec. cd +3 Multishot +40 Mana +Shots 6 Arrows at once in a volley +every arrow normal autohit dmg. (can be used as shotgun against large foes for 6x atk) +25 sec. cd +55 Mana + +Wizard +Rightclick - Teleport +Teleports to a location within 650 Range +cd 8 sec. +5 mana (probably strongest defensive spell so lets give it a slight nerf for the probably most mana hungry class next to bard) +1 Firebolt +Firebolt explodes in a bigger aoe on collision or after a set distance (1000?) +dmg: 1x autohit dmg on target that colides. 3x dmg in 250 aoe explosion +6 sec cd +30 Mana +2 Lightning bolt +Projectile. does dmg on hit and a chain lightning jumps to 2 nearby enemies that receive half the dmg. +dmg: 4x Atk main target (2x Atk nearby enemies) +6 sec cd +25 Mana +3 Meteor +after cast meteor hits a location and leaves a fire field that does some damage over time. +1.5 second cast. (no cd if cast canceled) +Max Cast Range 900, Cast on Mouse location +AoE Range: 400 +Damage: 9x Atk +Fire field: same aoe range, stays 4 seconds. 1x Atk per second for enemies inside. +40 sec cd. +Mana 75 \ No newline at end of file diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index eb79b3cc..ea182d2b 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -12,14 +12,13 @@ INCLUDE_DAMAGENUMBER_LIST INCLUDE_game const float Player::GROUND_SLAM_SPIN_TIME=0.6f; -const float Player::GROUND_SLAM_COOLDOWN=20; Player::Player(): - state(State::NORMAL),lastReleasedMovementKey(DOWN),facingDirection(DOWN){ -} - -Player::Player(vf2d pos): - pos(pos),state(State::NORMAL),lastReleasedMovementKey(DOWN),facingDirection(DOWN){ + state(State::NORMAL),lastReleasedMovementKey(DOWN),facingDirection(DOWN), + rightClickAbility("Block",15,VERY_DARK_BLUE,DARK_BLUE), + ability1("Battlecry",12), + ability2("Ground Slam",15), + ability3("Sonic Slash",40){ } void Player::SetX(float x){ @@ -125,13 +124,23 @@ void Player::Update(float fElapsedTime){ if(lastAnimationFlip>0){ lastAnimationFlip=std::max(0.f,lastAnimationFlip-fElapsedTime); } + animation.UpdateState(internal_animState,fElapsedTime); + }break; + case BLOCK:{ + if(rightClickAbility.COOLDOWN_TIME-rightClickAbility.cooldown>3){ + state=NORMAL; + } }break; default:{ - //Update animations normally. + //Update animations normally. + moveSpd=1.0; + animation.UpdateState(internal_animState,fElapsedTime); } } - animation.UpdateState(internal_animState,fElapsedTime); - groundSlamCooldown=std::max(0.f,groundSlamCooldown-fElapsedTime); + rightClickAbility.cooldown=std::max(0.f,rightClickAbility.cooldown-fElapsedTime); + ability1.cooldown=std::max(0.f,ability1.cooldown-fElapsedTime); + ability2.cooldown=std::max(0.f,ability2.cooldown-fElapsedTime); + ability3.cooldown=std::max(0.f,ability3.cooldown-fElapsedTime); for(Monster&m:MONSTER_LIST){ if(iframe_time==0&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ if(m.IsAlive()){ @@ -195,6 +204,11 @@ void Player::Update(float fElapsedTime){ } } } + if(rightClickAbility.cooldown==0&&GetState()==State::NORMAL&&game->GetMouse(1).bHeld){ + rightClickAbility.cooldown=rightClickAbility.COOLDOWN_TIME; + SetState(State::BLOCK); + moveSpd=0.7; + } } float Player::GetSwordSwingTimer(){ @@ -219,6 +233,7 @@ bool Player::HasIframes(){ bool Player::Hurt(int damage){ if(hp<=0||iframe_time!=0) return false; + if(state==State::BLOCK)damage=0; hp=std::max(0,hp-damage); DAMAGENUMBER_LIST.push_back(DamageNumber(pos,damage)); } @@ -259,8 +274,11 @@ void Player::Moved(){ } } -float Player::GetGroundSlamCooldown(){ - return groundSlamCooldown; +float Player::GetAbility2Cooldown(){ + return ability2.cooldown; +} +float Player::GetRightClickCooldown(){ + return rightClickAbility.cooldown; } void Player::Spin(float duration,float spinSpd){ @@ -268,5 +286,5 @@ void Player::Spin(float duration,float spinSpd){ spin_attack_timer=duration; spin_spd=spinSpd; spin_angle=0; - groundSlamCooldown=GROUND_SLAM_COOLDOWN; + ability2.cooldown=ability2.COOLDOWN_TIME; } \ No newline at end of file diff --git a/Crawler/Player.h b/Crawler/Player.h index f57d094b..2a07b6a3 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -3,6 +3,7 @@ #include "Animation.h" #include "Monster.h" #include "State.h" +#include "Ability.h" struct Player{ friend class Crawler; @@ -16,13 +17,13 @@ private: float moveSpd=1.0f; float size=1.0f; float attack_range=1.5f; + Ability rightClickAbility,ability1,ability2,ability3; const float ATTACK_COOLDOWN=0.35f; float attack_cooldown_timer=0; float spin_attack_timer=0; float spin_spd=0; float spin_angle=0; float lastAnimationFlip=0; - float groundSlamCooldown=0; float swordSwingTimer=0; float iframe_time=0; State state=State::NORMAL; @@ -44,9 +45,7 @@ private: protected: public: Player(); - Player(vf2d pos); const static float GROUND_SLAM_SPIN_TIME; - const static float GROUND_SLAM_COOLDOWN; vf2d&GetPos(); float GetX(); float GetY(); @@ -69,7 +68,8 @@ public: Key GetLastReleasedMovementKey(); float GetSwordSwingTimer(); - float GetGroundSlamCooldown(); + float GetAbility2Cooldown(); + float GetRightClickCooldown(); //Triggers when the player has moved. void Moved(); diff --git a/Crawler/State.h b/Crawler/State.h index 9e14776b..871619e7 100644 --- a/Crawler/State.h +++ b/Crawler/State.h @@ -6,4 +6,5 @@ enum State{ SPIN, MOVE_TOWARDS, MOVE_AWAY, + BLOCK, }; \ No newline at end of file diff --git a/Crawler/assets/block.png b/Crawler/assets/block.png new file mode 100644 index 0000000000000000000000000000000000000000..d0cb9420f3d2314b39434f4943be53892bc59471 GIT binary patch literal 668 zcmV;N0%QG&P)EX>4Tx04R}tkv&MmKpe$iTeTt;DMk=+$WWauh>AE$6^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;tBaGOi}v_(bAarW+RVI`QUHRuK)l524YJ`L;z6$paAY-`p+8x000SaNLh0L z01FcU01FcV0GgZ_00007bV*G`2j>P70SqZ!09JVb005XtL_t(Y$75t50v!MT{y#Qx zOHM&XLV6jAHMDEx{}5z;SvcbwVk~3CXE?f{xB$#DY?d%mYB(WF7^z`6K1&#>WjHQN z7^!JEHcOarr4mX2vROf3BaX`&rLN<#&g&kdrYr0f8bg44wQt4B(*#ZC;-*_Zau;AYS0000