From 022998271764418c2b240a0704d4b94077864018 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Wed, 12 Jul 2023 00:23:36 -0500 Subject: [PATCH] Added lightning bolt attack, added emitter system --- Crawler/ATTRIBUTION | 1 + Crawler/Animation.cpp | 317 +++++++++++++++++++++ Crawler/Animation.h | 12 +- Crawler/BulletTypes.h | 8 + Crawler/Class.cpp | 3 + Crawler/Crawler.cpp | 302 ++------------------ Crawler/Crawler.h | 6 +- Crawler/Crawler.vcxproj | 5 + Crawler/Crawler.vcxproj.filters | 18 ++ Crawler/DEFINES.h | 1 + Crawler/Effect.cpp | 16 +- Crawler/Effect.h | 8 +- Crawler/Emitter.cpp | 18 ++ Crawler/Emitter.h | 20 ++ Crawler/LightningBolt.cpp | 64 +++++ Crawler/LightningBoltEmitter.cpp | 38 +++ Crawler/Player.h | 1 + Crawler/Version.h | 2 +- Crawler/assets/chain_lightning.png | Bin 0 -> 571 bytes Crawler/assets/lightning_bolt.png | Bin 0 -> 10113 bytes Crawler/assets/lightning_bolt_part1.png | Bin 0 -> 547 bytes Crawler/assets/lightning_bolt_part2.png | Bin 0 -> 542 bytes Crawler/assets/lightning_bolt_part3.png | Bin 0 -> 537 bytes Crawler/assets/lightning_bolt_part4.png | Bin 0 -> 539 bytes Crawler/assets/lightning_splash_effect.png | Bin 0 -> 10525 bytes Crawler/olcUTIL_Animate2D.h | 7 +- 26 files changed, 553 insertions(+), 294 deletions(-) create mode 100644 Crawler/ATTRIBUTION create mode 100644 Crawler/Animation.cpp create mode 100644 Crawler/Emitter.cpp create mode 100644 Crawler/Emitter.h create mode 100644 Crawler/LightningBolt.cpp create mode 100644 Crawler/LightningBoltEmitter.cpp create mode 100644 Crawler/assets/chain_lightning.png create mode 100644 Crawler/assets/lightning_bolt.png create mode 100644 Crawler/assets/lightning_bolt_part1.png create mode 100644 Crawler/assets/lightning_bolt_part2.png create mode 100644 Crawler/assets/lightning_bolt_part3.png create mode 100644 Crawler/assets/lightning_bolt_part4.png create mode 100644 Crawler/assets/lightning_splash_effect.png diff --git a/Crawler/ATTRIBUTION b/Crawler/ATTRIBUTION new file mode 100644 index 00000000..e5a21612 --- /dev/null +++ b/Crawler/ATTRIBUTION @@ -0,0 +1 @@ +Image by pikisuperstar on Freepik \ No newline at end of file diff --git a/Crawler/Animation.cpp b/Crawler/Animation.cpp new file mode 100644 index 00000000..f47335aa --- /dev/null +++ b/Crawler/Animation.cpp @@ -0,0 +1,317 @@ +#include "Animation.h" +#include "Crawler.h" +#include "DEFINES.h" + +INCLUDE_game +INCLUDE_ANIMATION_DATA + +void sig::Animation::InitializeAnimations(){ + //Warrior animations. + Animate2D::FrameSequence pl_warrior_walk_s{0.2}; + pl_warrior_walk_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}}); + pl_warrior_walk_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{1,0}*24,{24,24}}}); + pl_warrior_walk_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}}); + pl_warrior_walk_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{2,0}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WARRIOR_WALK_S]=pl_warrior_walk_s; + Animate2D::FrameSequence pl_warrior_walk_e{0.2}; + pl_warrior_walk_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}}); + pl_warrior_walk_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{1,3}*24,{24,24}}}); + pl_warrior_walk_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}}); + pl_warrior_walk_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{2,3}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WARRIOR_WALK_E]=pl_warrior_walk_e; + Animate2D::FrameSequence pl_warrior_walk_w{0.2}; + pl_warrior_walk_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}}); + pl_warrior_walk_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{1,2}*24,{24,24}}}); + pl_warrior_walk_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}}); + pl_warrior_walk_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{2,2}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WARRIOR_WALK_W]=pl_warrior_walk_w; + Animate2D::FrameSequence pl_warrior_walk_n{0.2}; + pl_warrior_walk_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}}); + pl_warrior_walk_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{1,1}*24,{24,24}}}); + pl_warrior_walk_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}}); + pl_warrior_walk_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{2,1}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WARRIOR_WALK_N]=pl_warrior_walk_n; + Animate2D::FrameSequence pl_warrior_idle_s; + pl_warrior_idle_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WARRIOR_IDLE_S]=pl_warrior_idle_s; + Animate2D::FrameSequence pl_warrior_idle_e; + pl_warrior_idle_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WARRIOR_IDLE_E]=pl_warrior_idle_e; + Animate2D::FrameSequence pl_warrior_idle_w; + pl_warrior_idle_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WARRIOR_IDLE_W]=pl_warrior_idle_w; + Animate2D::FrameSequence pl_warrior_idle_n; + pl_warrior_idle_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WARRIOR_IDLE_N]=pl_warrior_idle_n; + Animate2D::FrameSequence pl_warrior_swing_s(0.05),pl_warrior_swing_n(0.05),pl_warrior_swing_e(0.05),pl_warrior_swing_w(0.05); + Animate2D::FrameSequence pl_warrior_sonic_swing_s(0.1,Animate2D::Style::OneShot),pl_warrior_sonic_swing_n(0.1,Animate2D::Style::OneShot),pl_warrior_sonic_swing_e(0.1,Animate2D::Style::OneShot),pl_warrior_sonic_swing_w(0.1,Animate2D::Style::OneShot); + for (int i=0;i<4;i++){ + pl_warrior_swing_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,0}*24,{24,24}}}); + pl_warrior_sonic_swing_s.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,4}*24,{24,24}}}); + } + for (int i=0;i<4;i++){ + pl_warrior_swing_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,1}*24,{24,24}}}); + pl_warrior_sonic_swing_n.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,5}*24,{24,24}}}); + } + for (int i=0;i<4;i++){ + pl_warrior_swing_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,2}*24,{24,24}}}); + pl_warrior_sonic_swing_w.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,6}*24,{24,24}}}); + } + for (int i=0;i<4;i++){ + pl_warrior_swing_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,3}*24,{24,24}}}); + pl_warrior_sonic_swing_e.AddFrame({&game->GFX_Warrior_Sheet,{vi2d{4+i,7}*24,{24,24}}}); + } + ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_N]=pl_warrior_swing_n; + ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_E]=pl_warrior_swing_e; + ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_S]=pl_warrior_swing_s; + ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_W]=pl_warrior_swing_w; + ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_N]=pl_warrior_sonic_swing_n; + ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_E]=pl_warrior_sonic_swing_e; + ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_S]=pl_warrior_sonic_swing_s; + ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_W]=pl_warrior_sonic_swing_w; + + //Ranger animations + Animate2D::FrameSequence pl_ranger_walk_s{0.2}; + pl_ranger_walk_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}}); + pl_ranger_walk_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{1,0}*24,{24,24}}}); + pl_ranger_walk_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}}); + pl_ranger_walk_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{2,0}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::RANGER_WALK_S]=pl_ranger_walk_s; + Animate2D::FrameSequence pl_ranger_walk_e{0.2}; + pl_ranger_walk_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}}); + pl_ranger_walk_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{1,3}*24,{24,24}}}); + pl_ranger_walk_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}}); + pl_ranger_walk_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{2,3}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::RANGER_WALK_E]=pl_ranger_walk_e; + Animate2D::FrameSequence pl_ranger_walk_w{0.2}; + pl_ranger_walk_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}}); + pl_ranger_walk_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{1,2}*24,{24,24}}}); + pl_ranger_walk_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}}); + pl_ranger_walk_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{2,2}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::RANGER_WALK_W]=pl_ranger_walk_w; + Animate2D::FrameSequence pl_ranger_walk_n{0.2}; + pl_ranger_walk_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}}); + pl_ranger_walk_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{1,1}*24,{24,24}}}); + pl_ranger_walk_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}}); + pl_ranger_walk_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{2,1}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::RANGER_WALK_N]=pl_ranger_walk_n; + Animate2D::FrameSequence pl_ranger_idle_s; + pl_ranger_idle_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::RANGER_IDLE_S]=pl_ranger_idle_s; + Animate2D::FrameSequence pl_ranger_idle_e; + pl_ranger_idle_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::RANGER_IDLE_E]=pl_ranger_idle_e; + Animate2D::FrameSequence pl_ranger_idle_w; + pl_ranger_idle_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::RANGER_IDLE_W]=pl_ranger_idle_w; + Animate2D::FrameSequence pl_ranger_idle_n; + pl_ranger_idle_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::RANGER_IDLE_N]=pl_ranger_idle_n; + + //Wizard animations + Animate2D::FrameSequence pl_wizard_walk_s{0.2}; + pl_wizard_walk_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}}); + pl_wizard_walk_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{1,0}*24,{24,24}}}); + pl_wizard_walk_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}}); + pl_wizard_walk_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{2,0}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_WALK_S]=pl_wizard_walk_s; + Animate2D::FrameSequence pl_wizard_walk_e{0.2}; + pl_wizard_walk_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}}); + pl_wizard_walk_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{1,3}*24,{24,24}}}); + pl_wizard_walk_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}}); + pl_wizard_walk_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{2,3}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_WALK_E]=pl_wizard_walk_e; + Animate2D::FrameSequence pl_wizard_walk_w{0.2}; + pl_wizard_walk_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}}); + pl_wizard_walk_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{1,2}*24,{24,24}}}); + pl_wizard_walk_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}}); + pl_wizard_walk_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{2,2}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_WALK_W]=pl_wizard_walk_w; + Animate2D::FrameSequence pl_wizard_walk_n{0.2}; + pl_wizard_walk_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}}); + pl_wizard_walk_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{1,1}*24,{24,24}}}); + pl_wizard_walk_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}}); + pl_wizard_walk_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{2,1}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_WALK_N]=pl_wizard_walk_n; + Animate2D::FrameSequence pl_wizard_idle_s; + pl_wizard_idle_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_IDLE_S]=pl_wizard_idle_s; + Animate2D::FrameSequence pl_wizard_idle_e; + pl_wizard_idle_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_IDLE_E]=pl_wizard_idle_e; + Animate2D::FrameSequence pl_wizard_idle_w; + pl_wizard_idle_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_IDLE_W]=pl_wizard_idle_w; + Animate2D::FrameSequence pl_wizard_idle_n; + pl_wizard_idle_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_IDLE_N]=pl_wizard_idle_n; + Animate2D::FrameSequence pl_wizard_idle_attack_s; + pl_wizard_idle_attack_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_S]=pl_wizard_idle_attack_s; + Animate2D::FrameSequence pl_wizard_idle_attack_e; + pl_wizard_idle_attack_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_E]=pl_wizard_idle_attack_e; + Animate2D::FrameSequence pl_wizard_idle_attack_w; + pl_wizard_idle_attack_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_W]=pl_wizard_idle_attack_w; + Animate2D::FrameSequence pl_wizard_idle_attack_n; + pl_wizard_idle_attack_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}}); + ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_N]=pl_wizard_idle_attack_n; + Animate2D::FrameSequence pl_wizard_attack_s(0.2); + for(int i=0;i<3;i++){ + pl_wizard_attack_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,0}*24,{24,24}}}); + if(i==1){ + pl_wizard_attack_s.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}}); + } + } + ANIMATION_DATA[AnimationState::WIZARD_ATTACK_S]=pl_wizard_attack_s; + Animate2D::FrameSequence pl_wizard_attack_e(0.2); + for(int i=0;i<3;i++){ + pl_wizard_attack_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,3}*24,{24,24}}}); + if(i==1){ + pl_wizard_attack_e.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}}); + } + } + ANIMATION_DATA[AnimationState::WIZARD_ATTACK_E]=pl_wizard_attack_e; + Animate2D::FrameSequence pl_wizard_attack_w(0.2); + for(int i=0;i<3;i++){ + pl_wizard_attack_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,2}*24,{24,24}}}); + if(i==1){ + pl_wizard_attack_w.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}}); + } + } + ANIMATION_DATA[AnimationState::WIZARD_ATTACK_W]=pl_wizard_attack_w; + Animate2D::FrameSequence pl_wizard_attack_n(0.2); + for(int i=0;i<3;i++){ + pl_wizard_attack_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4+i,1}*24,{24,24}}}); + if(i==1){ + pl_wizard_attack_n.AddFrame({&game->GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}}); + } + } + ANIMATION_DATA[AnimationState::WIZARD_ATTACK_N]=pl_wizard_attack_n; + + //Load slime animations. + for(int slime=0;slime<4;slime++){ + for(int state=0;state<5;state++){ + Animate2D::FrameSequence anim; + if(state==4){//These are death animations. + anim=Animate2D::FrameSequence(0.1f,Animate2D::Style::OneShot); + } + if(state==2){//These are death animations. + anim=Animate2D::FrameSequence(0.06f); + } + for (int frame=0;frame<10;frame++){ + anim.AddFrame({&game->GFX_Slime_Sheet,{vi2d{frame,state+5*slime}*24,{24,24}}}); + } + 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({&game->GFX_Effect_GroundSlam_Back,{{i*64,0},{64,64}}}); + effect_groundslam_front.AddFrame({&game->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; + Animate2D::FrameSequence battlecry_effect(0.02f,Animate2D::Style::OneShot); + for(int i=0;i<5;i++){ + battlecry_effect.AddFrame({&game->GFX_Battlecry_Effect,{{i*84,0},{84,84}}}); + } + ANIMATION_DATA[AnimationState::BATTLECRY_EFFECT]=battlecry_effect; + Animate2D::FrameSequence sonicslash_effect(0.04f,Animate2D::Style::OneShot); + for(int i=0;i<4;i++){ + sonicslash_effect.AddFrame({&game->GFX_SonicSlash,{{i*60,0},{60,60}}}); + } + ANIMATION_DATA[AnimationState::SONICSLASH]=sonicslash_effect; + Animate2D::FrameSequence energy_bolt; + energy_bolt.AddFrame({&game->GFX_EnergyBolt,{{0,0},{24,24}}}); + ANIMATION_DATA[AnimationState::ENERGY_BOLT]=energy_bolt; + + Animate2D::FrameSequence energy_particle; + for(int i=0;i<3;i++){ + energy_particle.AddFrame({&game->GFX_EnergyParticle,{{i*3,0},{3,3}}}); + } + ANIMATION_DATA[AnimationState::ENERGY_PARTICLE]=energy_particle; + + Animate2D::FrameSequence splash_animation(0.05); + for(int i=0;i<5;i++){ + splash_animation.AddFrame({&game->GFX_Splash_Effect,{{i*24,0},{24,24}}}); + } + ANIMATION_DATA[AnimationState::SPLASH_EFFECT]=splash_animation; + + Animate2D::FrameSequence dot_particle; + dot_particle.AddFrame({&game->GFX_BulletCircle,{{0,0},{3,3}}}); + ANIMATION_DATA[AnimationState::DOT_PARTICLE]=dot_particle; + + Animate2D::FrameSequence lightningbolt(0.03,Animate2D::Style::PingPong); + for(int i=0;i<5;i++){ + lightningbolt.AddFrame({&game->GFX_LightningBolt,{{i*24,0},{24,24}}}); + } + ANIMATION_DATA[AnimationState::LIGHTNING_BOLT]=lightningbolt; + + Animate2D::FrameSequence lightningboltpart1; + lightningboltpart1.AddFrame({&game->GFX_LightningBoltParticle1,{{0,0},{5,5}}}); + ANIMATION_DATA[AnimationState::LIGHTNING_BOLT_PARTICLE1]=lightningboltpart1; + Animate2D::FrameSequence lightningboltpart2; + lightningboltpart2.AddFrame({&game->GFX_LightningBoltParticle2,{{0,0},{5,5}}}); + ANIMATION_DATA[AnimationState::LIGHTNING_BOLT_PARTICLE2]=lightningboltpart2; + Animate2D::FrameSequence lightningboltpart3; + lightningboltpart3.AddFrame({&game->GFX_LightningBoltParticle3,{{0,0},{5,5}}}); + ANIMATION_DATA[AnimationState::LIGHTNING_BOLT_PARTICLE3]=lightningboltpart3; + Animate2D::FrameSequence lightningboltpart4; + lightningboltpart4.AddFrame({&game->GFX_LightningBoltParticle4,{{0,0},{5,5}}}); + ANIMATION_DATA[AnimationState::LIGHTNING_BOLT_PARTICLE4]=lightningboltpart4; + + Animate2D::FrameSequence chainlightning; + chainlightning.AddFrame({&game->GFX_ChainLightning,{{0,0},{1,9}}}); + ANIMATION_DATA[AnimationState::CHAIN_LIGHTNING]=chainlightning; + + Animate2D::FrameSequence lightningsplash; + for(int i=0;i<5;i++){ + lightningsplash.AddFrame({&game->GFX_LightningSplash,{{i*24,0},{24,24}}}); + } + ANIMATION_DATA[AnimationState::LIGHTNING_SPLASH]=lightningsplash; +} + +void sig::Animation::SetupPlayerAnimations(){ + game->player.AddAnimation(AnimationState::WARRIOR_WALK_N); + game->player.AddAnimation(AnimationState::WARRIOR_WALK_E); + game->player.AddAnimation(AnimationState::WARRIOR_WALK_S); + game->player.AddAnimation(AnimationState::WARRIOR_WALK_W); + game->player.AddAnimation(AnimationState::WARRIOR_IDLE_N); + game->player.AddAnimation(AnimationState::WARRIOR_IDLE_E); + game->player.AddAnimation(AnimationState::WARRIOR_IDLE_S); + game->player.AddAnimation(AnimationState::WARRIOR_IDLE_W); + game->player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_E); + game->player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_S); + game->player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_N); + game->player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_W); + game->player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_E); + game->player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_S); + game->player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_N); + game->player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_W); + game->player.AddAnimation(AnimationState::RANGER_WALK_N); + game->player.AddAnimation(AnimationState::RANGER_WALK_E); + game->player.AddAnimation(AnimationState::RANGER_WALK_S); + game->player.AddAnimation(AnimationState::RANGER_WALK_W); + game->player.AddAnimation(AnimationState::RANGER_IDLE_N); + game->player.AddAnimation(AnimationState::RANGER_IDLE_E); + game->player.AddAnimation(AnimationState::RANGER_IDLE_S); + game->player.AddAnimation(AnimationState::RANGER_IDLE_W); + game->player.AddAnimation(AnimationState::WIZARD_WALK_N); + game->player.AddAnimation(AnimationState::WIZARD_WALK_E); + game->player.AddAnimation(AnimationState::WIZARD_WALK_S); + game->player.AddAnimation(AnimationState::WIZARD_WALK_W); + game->player.AddAnimation(AnimationState::WIZARD_IDLE_N); + game->player.AddAnimation(AnimationState::WIZARD_IDLE_E); + game->player.AddAnimation(AnimationState::WIZARD_IDLE_S); + game->player.AddAnimation(AnimationState::WIZARD_IDLE_W); + game->player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_N); + game->player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_E); + game->player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_S); + game->player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_W); + game->player.AddAnimation(AnimationState::WIZARD_ATTACK_N); + game->player.AddAnimation(AnimationState::WIZARD_ATTACK_E); + game->player.AddAnimation(AnimationState::WIZARD_ATTACK_S); + game->player.AddAnimation(AnimationState::WIZARD_ATTACK_W); +} \ No newline at end of file diff --git a/Crawler/Animation.h b/Crawler/Animation.h index d6f3b1ea..e8391861 100644 --- a/Crawler/Animation.h +++ b/Crawler/Animation.h @@ -18,4 +18,14 @@ enum AnimationState{ WIZARD_IDLE_ATTACK_S,WIZARD_IDLE_ATTACK_E,WIZARD_IDLE_ATTACK_N,WIZARD_IDLE_ATTACK_W, WIZARD_ATTACK_S,WIZARD_ATTACK_E,WIZARD_ATTACK_N,WIZARD_ATTACK_W, ENERGY_BOLT,ENERGY_PARTICLE,SPLASH_EFFECT,DOT_PARTICLE, -}; \ No newline at end of file + LIGHTNING_BOLT,LIGHTNING_BOLT_PARTICLE1,LIGHTNING_BOLT_PARTICLE2,LIGHTNING_BOLT_PARTICLE3,LIGHTNING_BOLT_PARTICLE4, + CHAIN_LIGHTNING,LIGHTNING_SPLASH +}; + +namespace sig{ + class Animation{ + public: + static void InitializeAnimations(); + static void SetupPlayerAnimations(); + }; +} \ No newline at end of file diff --git a/Crawler/BulletTypes.h b/Crawler/BulletTypes.h index 6fc8e0f2..45a6b3a0 100644 --- a/Crawler/BulletTypes.h +++ b/Crawler/BulletTypes.h @@ -15,4 +15,12 @@ struct FireBolt:public Bullet{ void Update(float fElapsedTime)override; bool PlayerHit(Player&player)override; bool MonsterHit(Monster&monster)override; +}; + +struct LightningBolt:public Bullet{ + float lastParticleSpawn=0; + LightningBolt(vf2d pos,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/Class.cpp b/Crawler/Class.cpp index ef4095d0..14f61a0c 100644 --- a/Crawler/Class.cpp +++ b/Crawler/Class.cpp @@ -295,6 +295,9 @@ bool Wizard::Ability1(){ } bool Wizard::Ability2(){ + ACCESS_PLAYER + float angleToCursor=atan2(game->GetWorldMousePos().y-p.pos.y,game->GetWorldMousePos().x-p.pos.x); + BULLET_LIST.push_back(std::make_unique(LightningBolt(p.pos,{cos(angleToCursor)*230,sin(angleToCursor)*230},12,p.GetAttack()*4,p.upperLevel,true,WHITE))); return true; } diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 7fdc7055..5bdde233 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -13,8 +13,10 @@ #include "utils.h" #include #include +#include "Emitter.h" INCLUDE_CLASS_DATA +INCLUDE_EMITTER_LIST //#define DEBUG_COLLISIONS //Shows collision hitboxes. //#define DEBUG_POS //Shows player position. @@ -69,50 +71,18 @@ bool Crawler::OnUserCreate(){ GFX_EnergyBolt.Load("assets/energy_bolt.png"); GFX_EnergyParticle.Load("assets/energy_particle.png"); GFX_Splash_Effect.Load("assets/splash_effect.png"); + GFX_LightningBolt.Load("assets/lightning_bolt.png"); + GFX_LightningBoltParticle1.Load("assets/lightning_bolt_part1.png"); + GFX_LightningBoltParticle2.Load("assets/lightning_bolt_part2.png"); + GFX_LightningBoltParticle3.Load("assets/lightning_bolt_part3.png"); + GFX_LightningBoltParticle4.Load("assets/lightning_bolt_part4.png"); + GFX_ChainLightning.Load("assets/chain_lightning.png"); + GFX_LightningSplash.Load("assets/lightning_splash_effect.png"); //Animations - InitializeAnimations(); + sig::Animation::InitializeAnimations(); - player.AddAnimation(AnimationState::WARRIOR_WALK_N); - player.AddAnimation(AnimationState::WARRIOR_WALK_E); - player.AddAnimation(AnimationState::WARRIOR_WALK_S); - player.AddAnimation(AnimationState::WARRIOR_WALK_W); - player.AddAnimation(AnimationState::WARRIOR_IDLE_N); - player.AddAnimation(AnimationState::WARRIOR_IDLE_E); - player.AddAnimation(AnimationState::WARRIOR_IDLE_S); - player.AddAnimation(AnimationState::WARRIOR_IDLE_W); - player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_E); - player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_S); - player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_N); - player.AddAnimation(AnimationState::WARRIOR_SWINGSWORD_W); - player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_E); - player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_S); - player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_N); - player.AddAnimation(AnimationState::WARRIOR_SWINGSONICSWORD_W); - player.AddAnimation(AnimationState::RANGER_WALK_N); - player.AddAnimation(AnimationState::RANGER_WALK_E); - player.AddAnimation(AnimationState::RANGER_WALK_S); - player.AddAnimation(AnimationState::RANGER_WALK_W); - player.AddAnimation(AnimationState::RANGER_IDLE_N); - player.AddAnimation(AnimationState::RANGER_IDLE_E); - player.AddAnimation(AnimationState::RANGER_IDLE_S); - player.AddAnimation(AnimationState::RANGER_IDLE_W); - player.AddAnimation(AnimationState::WIZARD_WALK_N); - player.AddAnimation(AnimationState::WIZARD_WALK_E); - player.AddAnimation(AnimationState::WIZARD_WALK_S); - player.AddAnimation(AnimationState::WIZARD_WALK_W); - player.AddAnimation(AnimationState::WIZARD_IDLE_N); - player.AddAnimation(AnimationState::WIZARD_IDLE_E); - player.AddAnimation(AnimationState::WIZARD_IDLE_S); - player.AddAnimation(AnimationState::WIZARD_IDLE_W); - player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_N); - player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_E); - player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_S); - player.AddAnimation(AnimationState::WIZARD_IDLE_ATTACK_W); - player.AddAnimation(AnimationState::WIZARD_ATTACK_N); - player.AddAnimation(AnimationState::WIZARD_ATTACK_E); - player.AddAnimation(AnimationState::WIZARD_ATTACK_S); - player.AddAnimation(AnimationState::WIZARD_ATTACK_W); + sig::Animation::SetupPlayerAnimations(); view=TileTransformedView{GetScreenSize(),{1,1}}; LoadLevel(CAMPAIGN_1_1); @@ -137,245 +107,6 @@ bool Crawler::OnUserUpdate(float fElapsedTime){ return true; } -void Crawler::InitializeAnimations(){ - //Warrior animations. - Animate2D::FrameSequence pl_warrior_walk_s{0.2}; - pl_warrior_walk_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_warrior_walk_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{1,0}*24,{24,24}}}); - pl_warrior_walk_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_warrior_walk_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{2,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_WALK_S]=pl_warrior_walk_s; - Animate2D::FrameSequence pl_warrior_walk_e{0.2}; - pl_warrior_walk_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_warrior_walk_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{1,3}*24,{24,24}}}); - pl_warrior_walk_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_warrior_walk_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{2,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_WALK_E]=pl_warrior_walk_e; - Animate2D::FrameSequence pl_warrior_walk_w{0.2}; - pl_warrior_walk_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_warrior_walk_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{1,2}*24,{24,24}}}); - pl_warrior_walk_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_warrior_walk_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{2,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_WALK_W]=pl_warrior_walk_w; - Animate2D::FrameSequence pl_warrior_walk_n{0.2}; - pl_warrior_walk_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_warrior_walk_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{1,1}*24,{24,24}}}); - pl_warrior_walk_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_warrior_walk_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{2,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_WALK_N]=pl_warrior_walk_n; - Animate2D::FrameSequence pl_warrior_idle_s; - pl_warrior_idle_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_IDLE_S]=pl_warrior_idle_s; - Animate2D::FrameSequence pl_warrior_idle_e; - pl_warrior_idle_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_IDLE_E]=pl_warrior_idle_e; - Animate2D::FrameSequence pl_warrior_idle_w; - pl_warrior_idle_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_IDLE_W]=pl_warrior_idle_w; - Animate2D::FrameSequence pl_warrior_idle_n; - pl_warrior_idle_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{0,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WARRIOR_IDLE_N]=pl_warrior_idle_n; - Animate2D::FrameSequence pl_warrior_swing_s(0.05),pl_warrior_swing_n(0.05),pl_warrior_swing_e(0.05),pl_warrior_swing_w(0.05); - Animate2D::FrameSequence pl_warrior_sonic_swing_s(0.1,Animate2D::Style::OneShot),pl_warrior_sonic_swing_n(0.1,Animate2D::Style::OneShot),pl_warrior_sonic_swing_e(0.1,Animate2D::Style::OneShot),pl_warrior_sonic_swing_w(0.1,Animate2D::Style::OneShot); - for (int i=0;i<4;i++){ - pl_warrior_swing_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,0}*24,{24,24}}}); - pl_warrior_sonic_swing_s.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,4}*24,{24,24}}}); - } - for (int i=0;i<4;i++){ - pl_warrior_swing_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,1}*24,{24,24}}}); - pl_warrior_sonic_swing_n.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,5}*24,{24,24}}}); - } - for (int i=0;i<4;i++){ - pl_warrior_swing_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,2}*24,{24,24}}}); - pl_warrior_sonic_swing_w.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,6}*24,{24,24}}}); - } - for (int i=0;i<4;i++){ - pl_warrior_swing_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,3}*24,{24,24}}}); - pl_warrior_sonic_swing_e.AddFrame({&GFX_Warrior_Sheet,{vi2d{4+i,7}*24,{24,24}}}); - } - ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_N]=pl_warrior_swing_n; - ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_E]=pl_warrior_swing_e; - ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_S]=pl_warrior_swing_s; - ANIMATION_DATA[AnimationState::WARRIOR_SWINGSWORD_W]=pl_warrior_swing_w; - ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_N]=pl_warrior_sonic_swing_n; - ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_E]=pl_warrior_sonic_swing_e; - ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_S]=pl_warrior_sonic_swing_s; - ANIMATION_DATA[AnimationState::WARRIOR_SWINGSONICSWORD_W]=pl_warrior_sonic_swing_w; - - //Ranger animations - Animate2D::FrameSequence pl_ranger_walk_s{0.2}; - pl_ranger_walk_s.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_ranger_walk_s.AddFrame({&GFX_Ranger_Sheet,{vi2d{1,0}*24,{24,24}}}); - pl_ranger_walk_s.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_ranger_walk_s.AddFrame({&GFX_Ranger_Sheet,{vi2d{2,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_WALK_S]=pl_ranger_walk_s; - Animate2D::FrameSequence pl_ranger_walk_e{0.2}; - pl_ranger_walk_e.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_ranger_walk_e.AddFrame({&GFX_Ranger_Sheet,{vi2d{1,3}*24,{24,24}}}); - pl_ranger_walk_e.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_ranger_walk_e.AddFrame({&GFX_Ranger_Sheet,{vi2d{2,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_WALK_E]=pl_ranger_walk_e; - Animate2D::FrameSequence pl_ranger_walk_w{0.2}; - pl_ranger_walk_w.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_ranger_walk_w.AddFrame({&GFX_Ranger_Sheet,{vi2d{1,2}*24,{24,24}}}); - pl_ranger_walk_w.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_ranger_walk_w.AddFrame({&GFX_Ranger_Sheet,{vi2d{2,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_WALK_W]=pl_ranger_walk_w; - Animate2D::FrameSequence pl_ranger_walk_n{0.2}; - pl_ranger_walk_n.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_ranger_walk_n.AddFrame({&GFX_Ranger_Sheet,{vi2d{1,1}*24,{24,24}}}); - pl_ranger_walk_n.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_ranger_walk_n.AddFrame({&GFX_Ranger_Sheet,{vi2d{2,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_WALK_N]=pl_ranger_walk_n; - Animate2D::FrameSequence pl_ranger_idle_s; - pl_ranger_idle_s.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_IDLE_S]=pl_ranger_idle_s; - Animate2D::FrameSequence pl_ranger_idle_e; - pl_ranger_idle_e.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_IDLE_E]=pl_ranger_idle_e; - Animate2D::FrameSequence pl_ranger_idle_w; - pl_ranger_idle_w.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_IDLE_W]=pl_ranger_idle_w; - Animate2D::FrameSequence pl_ranger_idle_n; - pl_ranger_idle_n.AddFrame({&GFX_Ranger_Sheet,{vi2d{0,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::RANGER_IDLE_N]=pl_ranger_idle_n; - - //Wizard animations - Animate2D::FrameSequence pl_wizard_walk_s{0.2}; - pl_wizard_walk_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_wizard_walk_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{1,0}*24,{24,24}}}); - pl_wizard_walk_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}}); - pl_wizard_walk_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{2,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_WALK_S]=pl_wizard_walk_s; - Animate2D::FrameSequence pl_wizard_walk_e{0.2}; - pl_wizard_walk_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_wizard_walk_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{1,3}*24,{24,24}}}); - pl_wizard_walk_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}}); - pl_wizard_walk_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{2,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_WALK_E]=pl_wizard_walk_e; - Animate2D::FrameSequence pl_wizard_walk_w{0.2}; - pl_wizard_walk_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_wizard_walk_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{1,2}*24,{24,24}}}); - pl_wizard_walk_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}}); - pl_wizard_walk_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{2,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_WALK_W]=pl_wizard_walk_w; - Animate2D::FrameSequence pl_wizard_walk_n{0.2}; - pl_wizard_walk_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_wizard_walk_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{1,1}*24,{24,24}}}); - pl_wizard_walk_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}}); - pl_wizard_walk_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{2,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_WALK_N]=pl_wizard_walk_n; - Animate2D::FrameSequence pl_wizard_idle_s; - pl_wizard_idle_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_S]=pl_wizard_idle_s; - Animate2D::FrameSequence pl_wizard_idle_e; - pl_wizard_idle_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_E]=pl_wizard_idle_e; - Animate2D::FrameSequence pl_wizard_idle_w; - pl_wizard_idle_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_W]=pl_wizard_idle_w; - Animate2D::FrameSequence pl_wizard_idle_n; - pl_wizard_idle_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{0,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_N]=pl_wizard_idle_n; - Animate2D::FrameSequence pl_wizard_idle_attack_s; - pl_wizard_idle_attack_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_S]=pl_wizard_idle_attack_s; - Animate2D::FrameSequence pl_wizard_idle_attack_e; - pl_wizard_idle_attack_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_E]=pl_wizard_idle_attack_e; - Animate2D::FrameSequence pl_wizard_idle_attack_w; - pl_wizard_idle_attack_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_W]=pl_wizard_idle_attack_w; - Animate2D::FrameSequence pl_wizard_idle_attack_n; - pl_wizard_idle_attack_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}}); - ANIMATION_DATA[AnimationState::WIZARD_IDLE_ATTACK_N]=pl_wizard_idle_attack_n; - Animate2D::FrameSequence pl_wizard_attack_s(0.2); - for(int i=0;i<3;i++){ - pl_wizard_attack_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{4+i,0}*24,{24,24}}}); - if(i==1){ - pl_wizard_attack_s.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,0}*24,{24,24}}}); - } - } - ANIMATION_DATA[AnimationState::WIZARD_ATTACK_S]=pl_wizard_attack_s; - Animate2D::FrameSequence pl_wizard_attack_e(0.2); - for(int i=0;i<3;i++){ - pl_wizard_attack_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{4+i,3}*24,{24,24}}}); - if(i==1){ - pl_wizard_attack_e.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,3}*24,{24,24}}}); - } - } - ANIMATION_DATA[AnimationState::WIZARD_ATTACK_E]=pl_wizard_attack_e; - Animate2D::FrameSequence pl_wizard_attack_w(0.2); - for(int i=0;i<3;i++){ - pl_wizard_attack_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{4+i,2}*24,{24,24}}}); - if(i==1){ - pl_wizard_attack_w.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,2}*24,{24,24}}}); - } - } - ANIMATION_DATA[AnimationState::WIZARD_ATTACK_W]=pl_wizard_attack_w; - Animate2D::FrameSequence pl_wizard_attack_n(0.2); - for(int i=0;i<3;i++){ - pl_wizard_attack_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{4+i,1}*24,{24,24}}}); - if(i==1){ - pl_wizard_attack_n.AddFrame({&GFX_Wizard_Sheet,{vi2d{4,1}*24,{24,24}}}); - } - } - ANIMATION_DATA[AnimationState::WIZARD_ATTACK_N]=pl_wizard_attack_n; - - //Load slime animations. - for(int slime=0;slime<4;slime++){ - for(int state=0;state<5;state++){ - Animate2D::FrameSequence anim; - if(state==4){//These are death animations. - anim=Animate2D::FrameSequence(0.1f,Animate2D::Style::OneShot); - } - if(state==2){//These are death animations. - anim=Animate2D::FrameSequence(0.06f); - } - for (int frame=0;frame<10;frame++){ - anim.AddFrame({&GFX_Slime_Sheet,{vi2d{frame,state+5*slime}*24,{24,24}}}); - } - 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; - Animate2D::FrameSequence battlecry_effect(0.02f,Animate2D::Style::OneShot); - for(int i=0;i<5;i++){ - battlecry_effect.AddFrame({&GFX_Battlecry_Effect,{{i*84,0},{84,84}}}); - } - ANIMATION_DATA[AnimationState::BATTLECRY_EFFECT]=battlecry_effect; - Animate2D::FrameSequence sonicslash_effect(0.04f,Animate2D::Style::OneShot); - for(int i=0;i<4;i++){ - sonicslash_effect.AddFrame({&GFX_SonicSlash,{{i*60,0},{60,60}}}); - } - ANIMATION_DATA[AnimationState::SONICSLASH]=sonicslash_effect; - Animate2D::FrameSequence energy_bolt; - energy_bolt.AddFrame({&GFX_EnergyBolt,{{0,0},{24,24}}}); - ANIMATION_DATA[AnimationState::ENERGY_BOLT]=energy_bolt; - - Animate2D::FrameSequence energy_particle; - for(int i=0;i<3;i++){ - energy_particle.AddFrame({&GFX_EnergyParticle,{{i*3,0},{3,3}}}); - } - ANIMATION_DATA[AnimationState::ENERGY_PARTICLE]=energy_particle; - - Animate2D::FrameSequence splash_animation(0.05); - for(int i=0;i<5;i++){ - splash_animation.AddFrame({&GFX_Splash_Effect,{{i*24,0},{24,24}}}); - } - ANIMATION_DATA[AnimationState::SPLASH_EFFECT]=splash_animation; - - Animate2D::FrameSequence dot_particle; - dot_particle.AddFrame({&GFX_BulletCircle,{{0,0},{3,3}}}); - ANIMATION_DATA[AnimationState::DOT_PARTICLE]=dot_particle; -} - bool Crawler::LeftHeld(){ return GetKey(LEFT).bHeld||GetKey(A).bHeld; } @@ -625,6 +356,15 @@ void Crawler::UpdateCamera(float fElapsedTime){ } void Crawler::UpdateEffects(float fElapsedTime){ + for(auto it=EMITTER_LIST.begin();it!=EMITTER_LIST.end();++it){ + auto ptr=(*it).get(); + if(!ptr->Update(fElapsedTime)){ + it=EMITTER_LIST.erase(it); + if(it==EMITTER_LIST.end()){ + break; + } + } + } for(std::vector::iterator it=backgroundEffects.begin();it!=backgroundEffects.end();++it){ Effect&e=*it; if(!e.Update(fElapsedTime)){ @@ -650,6 +390,7 @@ void Crawler::UpdateBullets(float fElapsedTime){ b->UpdateFadeTime(fElapsedTime); b->Update(fElapsedTime); b->pos+=b->vel*fElapsedTime; + b->animation.UpdateState(b->internal_animState,fElapsedTime); if(!b->deactivated){ if(b->friendly){ for(Monster&m:MONSTER_LIST){ @@ -697,7 +438,6 @@ void Crawler::UpdateBullets(float fElapsedTime){ } continue; } - b->animation.UpdateState(b->internal_animState,fElapsedTime); continuePlayerBulletLoop: continue; } diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index b7527d34..c3fb3e0b 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -18,13 +18,16 @@ struct TilesheetData{ class Crawler : public olc::PixelGameEngine { + friend class sig::Animation; Camera2D camera; Player player; Renderable GFX_Warrior_Sheet,GFX_Slime_Sheet,GFX_Circle, GFX_Effect_GroundSlam_Back,GFX_Effect_GroundSlam_Front, GFX_Heart,GFX_BLOCK_BUBBLE,GFX_Ranger_Sheet,GFX_Wizard_Sheet, GFX_Battlecry_Effect,GFX_Mana,GFX_SonicSlash,GFX_EnergyParticle, - GFX_Splash_Effect; + GFX_Splash_Effect,GFX_LightningBolt,GFX_LightningBoltParticle1, + GFX_LightningBoltParticle2,GFX_LightningBoltParticle3,GFX_LightningBoltParticle4, + GFX_ChainLightning,GFX_LightningSplash; public: Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt; Pathfinding pathfinder; @@ -51,7 +54,6 @@ public: TileTransformedView view; bool OnUserCreate() override; bool OnUserUpdate(float fElapsedTime) override; - void InitializeAnimations(); void InitializeLevel(std::string mapFile,MapName map); void LoadLevel(MapName map); void HandleUserInput(float fElapsedTime); diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index bb32f7fc..fd65a0d9 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -182,6 +182,7 @@ + @@ -201,13 +202,17 @@ + + + + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index f56de6c9..2609e37b 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -19,6 +19,9 @@ {715c64c5-956a-4ed3-9205-64110409fbeb} + + {0f85b918-f194-4114-9a10-803e204faf2e} + @@ -99,6 +102,9 @@ Header Files + + Header Files + @@ -146,6 +152,18 @@ Source Files + + Source Files + + + Source Files\Bullet Types + + + Source Files\Emitters + + + Source Files + diff --git a/Crawler/DEFINES.h b/Crawler/DEFINES.h index 14fc2273..5db4cc4d 100644 --- a/Crawler/DEFINES.h +++ b/Crawler/DEFINES.h @@ -8,6 +8,7 @@ #define INCLUDE_BULLET_LIST extern std::vector>BULLET_LIST; #define INCLUDE_CLASS_DATA extern std::map>CLASS_DATA; #define INCLUDE_PARTICLE_LIST extern std::vectorPARTICLE_LIST; +#define INCLUDE_EMITTER_LIST extern std::vector>EMITTER_LIST; #define ACCESS_PLAYER Player&p=game->GetPlayer(); diff --git a/Crawler/Effect.cpp b/Crawler/Effect.cpp index 64965add..36f14065 100644 --- a/Crawler/Effect.cpp +++ b/Crawler/Effect.cpp @@ -5,8 +5,13 @@ INCLUDE_ANIMATION_DATA INCLUDE_game -Effect::Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,float size,float fadeout,vf2d spd,Pixel col) - :pos(pos),lifetime(lifetime),upperLevel(upperLevel),size(size),fadeout(fadeout),original_fadeoutTime(fadeout),spd(spd),col(col){ +Effect::Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,float size,float fadeout,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending) + :Effect::Effect(pos,lifetime,animation,upperLevel,{size,size},fadeout,spd,col,rotation,rotationSpd,additiveBlending){ + this->animation.AddState(animation,ANIMATION_DATA[animation]); +} + +Effect::Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,vf2d size,float fadeout,vf2d spd,Pixel col,float rotation,float rotationSpd,bool additiveBlending) + :pos(pos),lifetime(lifetime),upperLevel(upperLevel),size(size),fadeout(fadeout),original_fadeoutTime(fadeout),spd(spd),col(col),rotation(rotation),rotationSpd(rotationSpd),additiveBlending(additiveBlending){ this->animation.AddState(animation,ANIMATION_DATA[animation]); } @@ -18,16 +23,19 @@ bool Effect::Update(float fElapsedTime){ return false; } } + rotation+=rotationSpd*fElapsedTime; pos+=spd*fElapsedTime; animation.UpdateState(internal_animState,fElapsedTime); return true; } void Effect::Draw(){ + if(additiveBlending)game->SetDecalMode(DecalMode::ADDITIVE); + else game->SetDecalMode(DecalMode::NORMAL); if(fadeout==0){ - game->view.DrawPartialDecal(pos-GetFrame().GetSourceRect().size*size/2,GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,{size,size},col); + game->view.DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,col); } else { - game->view.DrawPartialDecal(pos-GetFrame().GetSourceRect().size*size/2,GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,{size,size},{col.r,col.g,col.b,uint8_t(fadeout/original_fadeoutTime*255)}); + game->view.DrawPartialRotatedDecal(pos,GetFrame().GetSourceImage()->Decal(),rotation,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,size,{col.r,col.g,col.b,uint8_t(fadeout/original_fadeoutTime*255)}); } } diff --git a/Crawler/Effect.h b/Crawler/Effect.h index adb6b614..3dd719e4 100644 --- a/Crawler/Effect.h +++ b/Crawler/Effect.h @@ -7,10 +7,14 @@ struct Effect{ vf2d pos={0,0}; float lifetime=0; float fadeout=0; - float size=1; + vf2d size={1,1}; Pixel col=WHITE; vf2d spd={}; - Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,float size=1.0f,float fadeout=0.0f,vf2d spd={},Pixel col=WHITE); + float rotation=0; + float rotationSpd=0; + bool additiveBlending=false; + Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,float size=1.0f,float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false); + Effect(vf2d pos,float lifetime,AnimationState animation,bool upperLevel,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false); bool Update(float fElapsedTime); Animate2D::Frame GetFrame(); void Draw(); diff --git a/Crawler/Emitter.cpp b/Crawler/Emitter.cpp new file mode 100644 index 00000000..f619ff55 --- /dev/null +++ b/Crawler/Emitter.cpp @@ -0,0 +1,18 @@ +#include "Emitter.h" + +std::vector>EMITTER_LIST; + +Emitter::Emitter(float frequency,float timer) + :frequency(frequency),timer(timer){} + +bool Emitter::Update(float fElapsedTime){ + lastEmit=std::max(lastEmit-fElapsedTime,0.f); + if(lastEmit==0){ + lastEmit=frequency; + Emit(); + } + timer-=fElapsedTime; + if(timer<0){ + return false; + } +} \ No newline at end of file diff --git a/Crawler/Emitter.h b/Crawler/Emitter.h new file mode 100644 index 00000000..a6c855fc --- /dev/null +++ b/Crawler/Emitter.h @@ -0,0 +1,20 @@ +#include "olcPixelGameEngine.h" +#pragma once + +struct Emitter{ + float frequency; + float timer; + float lastEmit=0; + Emitter(float frequency,float timer); + bool Update(float fElapsedTime); + virtual void Emit()=0; +}; + +class LightningBoltEmitter:public Emitter{ + vf2d startPos,endPos; + bool upperLevel; + void DrawLightningBolt(); + void Emit()override; +public: + LightningBoltEmitter(vf2d startPos,vf2d endPos,float frequency,float timer,bool upperLevel); +}; \ No newline at end of file diff --git a/Crawler/LightningBolt.cpp b/Crawler/LightningBolt.cpp new file mode 100644 index 00000000..00755fb8 --- /dev/null +++ b/Crawler/LightningBolt.cpp @@ -0,0 +1,64 @@ +#include "BulletTypes.h" +#include "Effect.h" +#include "Crawler.h" +#include "DEFINES.h" +#include "Emitter.h" +#include "utils.h" + +INCLUDE_game +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){} + +void LightningBolt::Update(float fElapsedTime){ + lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); + if(lastParticleSpawn==0){ + lastParticleSpawn=0.01; + uint8_t brightness=uint8_t(util::random(100)+150); + switch(rand()%4){ + case 0:{ + game->AddEffect(Effect(pos+vf2d{util::random(12)-6,util::random(12)-6},util::random(0.1),AnimationState::LIGHTNING_BOLT_PARTICLE1,upperLevel,util::random(0.5)+1,0.1,vel*(util::random(0.1)+0.9),{brightness,brightness,brightness})); + }break; + case 1:{ + game->AddEffect(Effect(pos+vf2d{util::random(12)-6,util::random(12)-6},util::random(0.1),AnimationState::LIGHTNING_BOLT_PARTICLE2,upperLevel,util::random(0.5)+1,0.1,vel*(util::random(0.1)+0.9),{brightness,brightness,brightness})); + }break; + case 2:{ + game->AddEffect(Effect(pos+vf2d{util::random(12)-6,util::random(12)-6},util::random(0.1),AnimationState::LIGHTNING_BOLT_PARTICLE3,upperLevel,util::random(0.5)+1,0.1,vel*(util::random(0.1)+0.9),{brightness,brightness,brightness})); + }break; + case 3:{ + game->AddEffect(Effect(pos+vf2d{util::random(12)-6,util::random(12)-6},util::random(0.1),AnimationState::LIGHTNING_BOLT_PARTICLE4,upperLevel,util::random(0.5)+1,0.1,vel*(util::random(0.1)+0.9),{brightness,brightness,brightness})); + }break; + } + } +} + +bool LightningBolt::PlayerHit(Player& player) +{ + deactivated=true; + fadeOutTime=0.2f; + game->AddEffect(Effect(player.GetPos(),0.3,AnimationState::LIGHTNING_SPLASH,upperLevel,player.GetSizeMult(),0.25,{},WHITE,util::random(PI))); + return false; +} + +bool LightningBolt::MonsterHit(Monster& monster) +{ + deactivated=true; + fadeOutTime=0.2f; + game->AddEffect(Effect(monster.GetPos(),0.3,AnimationState::LIGHTNING_SPLASH,upperLevel,monster.GetSizeMult(),0.25,{},WHITE,util::random(PI))); + int targetsHit=0; + for(Monster&m:MONSTER_LIST){ + if(&m==&monster||monster.OnUpperLevel()!=m.OnUpperLevel())continue; + geom2d::linelineToTarget=geom2d::line(monster.GetPos(),m.GetPos()); + float dist=lineToTarget.length(); + if(dist<=72){ + m.Hurt(game->GetPlayer().GetAttack()*2); + EMITTER_LIST.push_back(std::make_unique(LightningBoltEmitter(monster.GetPos(),m.GetPos(),0.05,0.25,upperLevel))); + game->AddEffect(Effect(m.GetPos(),0.5,AnimationState::LIGHTNING_SPLASH,upperLevel,monster.GetSizeMult(),0.25,{},WHITE,util::random(PI))); + targetsHit++; + } + if(targetsHit>=2)break; + } + return false; +} \ No newline at end of file diff --git a/Crawler/LightningBoltEmitter.cpp b/Crawler/LightningBoltEmitter.cpp new file mode 100644 index 00000000..5f222d22 --- /dev/null +++ b/Crawler/LightningBoltEmitter.cpp @@ -0,0 +1,38 @@ +#include "Emitter.h" +#include "olcUTIL_Geometry2D.h" +#include "utils.h" +#include "Crawler.h" +#include "DEFINES.h" + +INCLUDE_game + +LightningBoltEmitter::LightningBoltEmitter(vf2d startPos,vf2d endPos,float frequency,float timer,bool upperLevel) + :startPos(startPos),endPos(endPos),Emitter(frequency,timer),upperLevel(upperLevel){} + + +void LightningBoltEmitter::Emit(){ + DrawLightningBolt(); +} + +void LightningBoltEmitter::DrawLightningBolt(){ + vf2d currentPos=startPos; + const int MAX_ITERATIONS=100; + geom2d::linelineToTarget=geom2d::line(startPos,endPos); + float targetAngle=atan2(lineToTarget.vector().y,lineToTarget.vector().x); + float targetDist=lineToTarget.length()*util::random(0.5); + targetAngle+=util::random((PI/2))-PI/4; + geom2d::linelightningLine=geom2d::line(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}); + game->AddEffect(Effect(lightningLine.upoint(0),0,AnimationState::CHAIN_LIGHTNING,upperLevel,{lightningLine.length(),0.2},0.2,{},WHITE,targetAngle,0,true)); + int iterations=1; + currentPos+=vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}; + while(iterations(currentPos,endPos).length()>1){ + geom2d::linelineToTarget=geom2d::line(currentPos,endPos); + float targetAngle=atan2(lineToTarget.vector().y,lineToTarget.vector().x); + float targetDist=lineToTarget.length()*util::random(0.5); + targetAngle+=util::random((PI/2))-PI/4; + geom2d::linelightningLine=geom2d::line(currentPos,currentPos+vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}); + game->AddEffect(Effect(lightningLine.upoint(0),0,AnimationState::CHAIN_LIGHTNING,upperLevel,{lightningLine.length(),0.2},0.2,{},WHITE,targetAngle,0,true)); + currentPos+=vf2d{cos(targetAngle)*targetDist,sin(targetAngle)*targetDist}; + iterations++; + } +} \ No newline at end of file diff --git a/Crawler/Player.h b/Crawler/Player.h index 0b9252e3..91d4db45 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -16,6 +16,7 @@ struct Player{ friend class Bard; friend class Wizard; friend class Witch; + friend class sig::Animation; private: Class cl=WARRIOR; int hp=100,maxhp=hp; diff --git a/Crawler/Version.h b/Crawler/Version.h index b138a2c8..bceb5a85 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 594 +#define VERSION_BUILD 639 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/assets/chain_lightning.png b/Crawler/assets/chain_lightning.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7caf9b10fcb731df89e3202b029ce553314869 GIT binary patch literal 571 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 literal 0 HcmV?d00001 diff --git a/Crawler/assets/lightning_bolt_part2.png b/Crawler/assets/lightning_bolt_part2.png new file mode 100644 index 0000000000000000000000000000000000000000..53a7c058698915c6e39581eb7448f5720a390ff2 GIT binary patch literal 542 zcmV+(0^$9MP)EX>4Tx04R}tkv&MmKpe$iQ>8^J4t5Z62w0sgh>AE$D;B{*X)CnqU~=gfG-*gu zTpR`0f`cE6RRiq2q3El0M8l|D%A{REC2ui07*qoM6N<$f>I6MHvj+t literal 0 HcmV?d00001 diff --git a/Crawler/assets/lightning_bolt_part3.png b/Crawler/assets/lightning_bolt_part3.png new file mode 100644 index 0000000000000000000000000000000000000000..a33c68f363adf8673700176e560a002903106795 GIT binary patch literal 537 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 literal 0 HcmV?d00001 diff --git a/Crawler/olcUTIL_Animate2D.h b/Crawler/olcUTIL_Animate2D.h index e56dece7..7da9ce4c 100644 --- a/Crawler/olcUTIL_Animate2D.h +++ b/Crawler/olcUTIL_Animate2D.h @@ -140,9 +140,10 @@ namespace olc::utils::Animate2D case Style::OneShot: return std::clamp(size_t(fTime * m_fFrameRate), size_t(0), m_vFrames.size() - 1); break; - case Style::PingPong: - // TODO - break; + case Style::PingPong:{ + size_t frame=size_t(m_fFrameRate*fTime) % (m_vFrames.size()*2-1); + return frame>=m_vFrames.size()?m_vFrames.size()-frame%m_vFrames.size()-1:frame; + }break; case Style::Reverse: return (m_vFrames.size() - 1) - (size_t(fTime * m_fFrameRate) % m_vFrames.size()); break;