diff --git a/HamsterJet.h b/HamsterJet.h deleted file mode 100644 index 0d46c3f..0000000 --- a/HamsterJet.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma region License -/* -License (OLC-3) -~~~~~~~~~~~~~~~ - -Copyright 2024 Joshua Sigona - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions or derivations of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions or derivative works in binary form must reproduce the above -copyright notice. This list of conditions and the following disclaimer must be -reproduced in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors may -be used to endorse or promote products derived from this software without specific -prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -Portions of this software are copyright © 2024 The FreeType -Project (www.freetype.org). Please see LICENSE_FT.txt for more information. -All rights reserved. -*/ -#pragma endregion -#pragma once - -class HamsterJet{ - -}; \ No newline at end of file diff --git a/assets/hamster_jet.png b/assets/hamster_jet.png index f6c856f..0c59948 100644 Binary files a/assets/hamster_jet.png and b/assets/hamster_jet.png differ diff --git a/src/Hamster.cpp b/src/Hamster.cpp index d820102..7a06dc2 100644 --- a/src/Hamster.cpp +++ b/src/Hamster.cpp @@ -151,7 +151,9 @@ void Hamster::DrawHamsters(TransformedView&tv){ if(h.state==FLYING)h.hamsterJet.value().Draw(); HamsterGame::Game().SetZ(h.z); if(h.HasPowerup(Powerup::WHEEL))tv.DrawPartialRotatedDecal(h.pos,wheelBottomImg.GetSourceImage()->Decal(),h.rot,wheelBottomImg.GetSourceRect().size/2,wheelBottomImg.GetSourceRect().pos,wheelBottomImg.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale,PixelLerp(h.shrinkEffectColor,WHITE,h.imgScale)); + HamsterGame::Game().SetZ(h.z+0.005f); tv.DrawPartialRotatedDecal(h.pos,img.GetSourceImage()->Decal(),h.rot,img.GetSourceRect().size/2,img.GetSourceRect().pos,img.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale,PixelLerp(h.shrinkEffectColor,WHITE,h.imgScale)); + HamsterGame::Game().SetZ(h.z+0.01f); if(h.HasPowerup(Powerup::WHEEL))tv.DrawPartialRotatedDecal(h.pos,wheelTopImg.GetSourceImage()->Decal(),h.rot,wheelTopImg.GetSourceRect().size/2,wheelTopImg.GetSourceRect().pos,wheelTopImg.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale,PixelLerp(h.shrinkEffectColor,{255,255,255,192},h.imgScale)); HamsterGame::Game().SetZ(0.f); } @@ -270,6 +272,7 @@ const float Hamster::GetTimeToMaxSpeed()const{ float finalTimeToMaxSpd{DEFAULT_TIME_TO_MAX_SPD}; if(!HasPowerup(Powerup::ICE)&&GetTerrainStandingOn()==Terrain::ICE)finalTimeToMaxSpd*=3; else if(!HasPowerup(Powerup::SWAMP)&&GetTerrainStandingOn()==Terrain::SWAMP)finalTimeToMaxSpd*=1.25; + if(state==FLYING)finalTimeToMaxSpd*=30.f; return finalTimeToMaxSpd; } const float Hamster::GetMaxSpeed()const{ @@ -296,12 +299,14 @@ const float Hamster::GetMaxSpeed()const{ }break; } if(HasPowerup(Powerup::WHEEL))finalMaxSpd*=1.5f; + if(state==FLYING)finalMaxSpd*=8.f; return finalMaxSpd; } const float Hamster::GetFriction()const{ float finalFriction{DEFAULT_FRICTION}; if(!HasPowerup(Powerup::ICE)&&GetTerrainStandingOn()==Terrain::ICE)finalFriction*=0.1f; else if(!HasPowerup(Powerup::SWAMP)&&GetTerrainStandingOn()==Terrain::SWAMP)finalFriction*=0.6f; + if(state==FLYING)finalFriction*=8.f; return finalFriction; } const float Hamster::GetTurnSpeed()const{ diff --git a/src/Hamster.h b/src/Hamster.h index 198c207..998b026 100644 --- a/src/Hamster.h +++ b/src/Hamster.h @@ -46,6 +46,7 @@ All rights reserved. #include "HamsterGame.h" class Hamster{ + friend class HamsterJet; enum PlayerControlled{ PLAYER_CONTROLLED=true, NPC=false, diff --git a/src/HamsterGame.cpp b/src/HamsterGame.cpp index bd6713b..1f24d1d 100644 --- a/src/HamsterGame.cpp +++ b/src/HamsterGame.cpp @@ -79,7 +79,7 @@ void HamsterGame::LoadAnimations(){ lavaAnimFrames.AddFrame(Animate2D::Frame{&GetGFX("gametiles.png"),{sourcePos,{16,16}}}); } LoadAnimation(JET_LIGHTS,"hamster_jet.png",{{0,48},{48,48}},0.3f,Animate2D::Style::Repeat,{48,48}); - + LoadAnimation(JET_FLAMES,"hamster_jet.png",{{48,0},{96,0}},0.15f,Animate2D::Style::Repeat,{48,48}); animatedWaterTile.Create(16,16,false,false); UpdateWaterTexture(); @@ -135,6 +135,7 @@ void HamsterGame::UpdateGame(const float fElapsedTime){ cloudOffset+=cloudSpd*fElapsedTime; camera.SetViewSize(tv.GetWorldVisibleArea()); camera.Update(fElapsedTime); + camera.SetLazyFollowRate(4.f*Hamster::GetPlayer().GetMaxSpeed()/128.f); tv.SetWorldOffset(tv.ScaleToWorld(-SCREEN_FRAME.pos)+camera.GetViewPosition()); Hamster::UpdateHamsters(fElapsedTime); Powerup::UpdatePowerups(fElapsedTime); diff --git a/src/HamsterGame.h b/src/HamsterGame.h index cbca8ff..f23906c 100644 --- a/src/HamsterGame.h +++ b/src/HamsterGame.h @@ -63,6 +63,7 @@ public: WHEEL_TOP, WHEEL_BOTTOM, JET_LIGHTS, + JET_FLAMES, }; HamsterGame(); @@ -109,7 +110,6 @@ private: GFX3D::PipeLine renderer; virtual void Apply3DTransform(std::vector&decals)override final; float zoom{1.f}; //Increase to zoom out, decrease to zoom in (this is the overhead distance from the player). - GFX3D::vec3d vUp{0,-1,0}; GFX3D::vec3d vEye{0.f,0,1}; GFX3D::vec3d vLookDir{0,0,-1}; diff --git a/src/HamsterJet.cpp b/src/HamsterJet.cpp index 4ba8bd5..1e86d57 100644 --- a/src/HamsterJet.cpp +++ b/src/HamsterJet.cpp @@ -49,14 +49,20 @@ void HamsterJet::Update(const float fElapsedTime){ jet.Update(fElapsedTime); lights.Update(fElapsedTime); timer=std::max(0.f,timer-fElapsedTime); + lastTappedSpace+=fElapsedTime; switch(state){ case SWOOP_DOWN:{ HamsterGame::Game().SetZoom(1.5f); z=util::lerp(0.f,3.f,std::pow(timer/3.f,2)); vf2d originalPos{hamster.GetPos().x-128.f,hamster.GetPos().y+32.f}; - pos=hamster.GetPos().lerp(originalPos,std::pow(timer/3.f,4)); if(timer<=0.4f){ hamster.SetPos(hamsterOriginalPos-vf2d{0.f,sin(float(geom2d::pi)*timer/0.4f)*8.f}); + hamster.SetZ(sin(float(geom2d::pi)*timer/0.4f)*0.2f); + jetState[TOP_LEFT]=OFF; + jetState[BOTTOM_LEFT]=OFF; + }else{ + jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=ON; + pos=hamster.GetPos().lerp(originalPos,std::pow(timer/3.f,4)); } if(timer<=0.f){ state=RISE_UP; @@ -68,22 +74,74 @@ void HamsterJet::Update(const float fElapsedTime){ } }break; case RISE_UP:{ + jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=ON; pos=targetPos.lerp(originalPos,std::sqrt(timer/3.f)); z=util::lerp(targetZ,0.f,timer/3.f); hamster.SetPos(pos); - hamster.SetZ(z+0.01f); + hamster.SetZ(z+0.03f); if(timer<=0.f){ state=PLAYER_CONTROL; HamsterGame::Game().SetZoom(1.f); } }break; + case PLAYER_CONTROL:{ + jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=OFF; + HandleJetControls(); + pos=hamster.GetPos(); + }break; } } void HamsterJet::Draw(){ HamsterGame::Game().SetZ(z); HamsterGame::Game().tv.DrawPartialRotatedDecal(pos,jet.Decal(),0.f,{24,24},{},{48,48}); + const Animate2D::FrameSequence&flameAnim{HamsterGame::Game().GetAnimation("hamster_jet.png",HamsterGame::AnimationState::JET_FLAMES)}; + const Animate2D::Frame&flameFrame{flameAnim.GetFrame(HamsterGame::Game().GetRuntime())}; + HamsterGame::Game().SetZ(z+0.01f); + if(jetState[TOP_LEFT])HamsterGame::Game().tv.DrawPartialRotatedDecal(pos,flameFrame.GetSourceImage()->Decal(),0.f,flameFrame.GetSourceRect().size/2,flameFrame.GetSourceRect().pos+vf2d{0,0},flameFrame.GetSourceRect().size/2); + if(jetState[BOTTOM_LEFT])HamsterGame::Game().tv.DrawPartialRotatedDecal(pos,flameFrame.GetSourceImage()->Decal(),0.f,{24,0},flameFrame.GetSourceRect().pos+vf2d{0,24},flameFrame.GetSourceRect().size/2); + if(jetState[BOTTOM_RIGHT])HamsterGame::Game().tv.DrawPartialRotatedDecal(pos,flameFrame.GetSourceImage()->Decal(),0.f,{0,0},flameFrame.GetSourceRect().pos+vf2d{24,24},flameFrame.GetSourceRect().size/2); + if(jetState[TOP_RIGHT])HamsterGame::Game().tv.DrawPartialRotatedDecal(pos,flameFrame.GetSourceImage()->Decal(),0.f,{0,24},flameFrame.GetSourceRect().pos+vf2d{24,0},flameFrame.GetSourceRect().size/2); const Animate2D::FrameSequence&lightAnim{HamsterGame::Game().GetAnimation("hamster_jet.png",HamsterGame::AnimationState::JET_LIGHTS)}; const Animate2D::Frame&lightFrame{lightAnim.GetFrame(HamsterGame::Game().GetRuntime())}; + HamsterGame::Game().SetZ(z+0.02f); HamsterGame::Game().tv.DrawPartialRotatedDecal(pos,lights.Decal(),0.f,lightFrame.GetSourceRect().size/2.f,lightFrame.GetSourceRect().pos,lightFrame.GetSourceRect().size); HamsterGame::Game().SetZ(0.f); +} + +void HamsterJet::HandleJetControls(){ + lastTappedSpace+=HamsterGame::Game().GetElapsedTime(); + vf2d aimingDir{}; + if(HamsterGame::Game().GetKey(W).bHeld){ + aimingDir+=vf2d{0,-1}; + jetState[BOTTOM_RIGHT]=ON; + jetState[BOTTOM_LEFT]=ON; + } + if(HamsterGame::Game().GetKey(D).bHeld){ + aimingDir+=vf2d{1,0}; + jetState[BOTTOM_LEFT]=ON; + jetState[TOP_LEFT]=ON; + } + if(HamsterGame::Game().GetKey(S).bHeld){ + aimingDir+=vf2d{0,1}; + jetState[TOP_LEFT]=ON; + jetState[TOP_RIGHT]=ON; + } + if(HamsterGame::Game().GetKey(A).bHeld){ + aimingDir+=vf2d{-1,0}; + jetState[BOTTOM_RIGHT]=ON; + jetState[TOP_RIGHT]=ON; + } + if(aimingDir!=vf2d{}){ + hamster.targetRot=aimingDir.norm().polar().y; + const vf2d currentVel{hamster.vel}; + hamster.vel+=vf2d{currentVel.polar().x+(hamster.GetMaxSpeed()*HamsterGame::Game().GetElapsedTime())/hamster.GetTimeToMaxSpeed(),hamster.rot}.cart(); + hamster.vel=vf2d{std::min(hamster.GetMaxSpeed(),hamster.vel.polar().x),hamster.vel.polar().y}.cart(); + hamster.frictionEnabled=false; + } + if(HamsterGame::Game().GetKey(SPACE).bPressed){ + if(lastTappedSpace<=0.6f){ + state=LANDING; + } + lastTappedSpace=0.f; + } } \ No newline at end of file diff --git a/src/HamsterJet.h b/src/HamsterJet.h index e9c6c02..bb09b5d 100644 --- a/src/HamsterJet.h +++ b/src/HamsterJet.h @@ -50,6 +50,16 @@ class HamsterJet{ LANDING, COMPLETE_LANDING, }; + enum JetDirection{ + TOP_LEFT, + BOTTOM_LEFT, + BOTTOM_RIGHT, + TOP_RIGHT, + }; + enum JetState{ + ON=true, + OFF=false, + }; Hamster&hamster; vf2d pos; vf2d hamsterOriginalPos; @@ -61,8 +71,11 @@ class HamsterJet{ SpecialRenderable jet; SpecialRenderable lights; float timer{}; + std::arrayjetState; + float lastTappedSpace{}; public: HamsterJet(Hamster&hamster); void Update(const float fElapsedTime); void Draw(); + void HandleJetControls(); }; \ No newline at end of file