Implemented blocking. Made player abilities dynamic instead of fixed for class expansion preparation.
This commit is contained in:
parent
75b763e87b
commit
e090bc775d
5
Crawler/Ability.cpp
Normal file
5
Crawler/Ability.cpp
Normal file
@ -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){}
|
11
Crawler/Ability.h
Normal file
11
Crawler/Ability.h
Normal file
@ -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);
|
||||
};
|
@ -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::function<std::string(std::string)>capitalize=[](std::string name)->std::string{
|
||||
std::string newName="";
|
||||
for(int i=0;i<name.length();i++){
|
||||
newName.append(1,name[i]>='a'?name[i]-32:name[i]);
|
||||
newName.append(1,' ');
|
||||
}
|
||||
return newName;
|
||||
};
|
||||
std::vector<Ability>cooldowns{
|
||||
player.rightClickAbility,
|
||||
player.ability1,
|
||||
player.ability2,
|
||||
player.ability3
|
||||
};
|
||||
std::vector<Ability>activeCooldowns;
|
||||
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.cooldown<a2.cooldown;
|
||||
});
|
||||
int offset=6*activeCooldowns.size();
|
||||
for(Ability&a:activeCooldowns){
|
||||
if(a.cooldown>0){
|
||||
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";
|
||||
|
@ -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::vector<Effect>foregroundEffects,backgroundEffects;
|
||||
|
||||
public:
|
||||
|
@ -129,6 +129,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Ability.h" />
|
||||
<ClInclude Include="Animation.h" />
|
||||
<ClInclude Include="Bullet.h" />
|
||||
<ClInclude Include="Crawler.h" />
|
||||
@ -145,6 +146,7 @@
|
||||
<ClInclude Include="State.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Ability.cpp" />
|
||||
<ClCompile Include="Bullet.cpp" />
|
||||
<ClCompile Include="Crawler.cpp" />
|
||||
<ClCompile Include="DamageNumber.cpp" />
|
||||
@ -157,6 +159,10 @@
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="NewClasses.txt" />
|
||||
<Text Include="InitialConcept.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<Filter Include="Documentation">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
@ -57,6 +57,9 @@
|
||||
<ClInclude Include="Bullet.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ability.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Player.cpp">
|
||||
@ -83,8 +86,19 @@
|
||||
<ClCompile Include="Bullet.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ability.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="InitialConcept.txt">
|
||||
<Filter>Documentation</Filter>
|
||||
</Text>
|
||||
<Text Include="NewClasses.txt">
|
||||
<Filter>Documentation</Filter>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
</Project>
|
68
Crawler/NewClasses.txt
Normal file
68
Crawler/NewClasses.txt
Normal file
@ -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
|
@ -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;
|
||||
}
|
@ -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();
|
||||
|
@ -6,4 +6,5 @@ enum State{
|
||||
SPIN,
|
||||
MOVE_TOWARDS,
|
||||
MOVE_AWAY,
|
||||
BLOCK,
|
||||
};
|
BIN
Crawler/assets/block.png
Normal file
BIN
Crawler/assets/block.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 668 B |
Loading…
x
Reference in New Issue
Block a user