Add powerup collection and powerup collection effect.

main
sigonasr2 3 months ago
parent cb16ce831a
commit b1e418bbc7
  1. BIN
      assets/shadow.png
  2. 4
      hamster.vcxproj
  3. 18
      src/Hamster.cpp
  4. 4
      src/Hamster.h
  5. 20
      src/HamsterGame.cpp
  6. 27
      src/Powerup.cpp
  7. 7
      src/Powerup.h

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 B

@ -105,6 +105,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;CMAKE_INTDIR="Debug"</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;CMAKE_INTDIR="Debug"</PreprocessorDefinitions>
<ObjectFileName>$(IntDir)</ObjectFileName> <ObjectFileName>$(IntDir)</ObjectFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_DEBUG;_WINDOWS;CMAKE_INTDIR=\"Debug\"</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_DEBUG;_WINDOWS;CMAKE_INTDIR=\"Debug\"</PreprocessorDefinitions>
@ -149,6 +150,7 @@
<ObjectFileName>$(IntDir)</ObjectFileName> <ObjectFileName>$(IntDir)</ObjectFileName>
<DebugInformationFormat> <DebugInformationFormat>
</DebugInformationFormat> </DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\"</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\"</PreprocessorDefinitions>
@ -193,6 +195,7 @@
<ObjectFileName>$(IntDir)</ObjectFileName> <ObjectFileName>$(IntDir)</ObjectFileName>
<DebugInformationFormat> <DebugInformationFormat>
</DebugInformationFormat> </DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"MinSizeRel\"</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"MinSizeRel\"</PreprocessorDefinitions>
@ -236,6 +239,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="RelWithDebInfo"</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="RelWithDebInfo"</PreprocessorDefinitions>
<ObjectFileName>$(IntDir)</ObjectFileName> <ObjectFileName>$(IntDir)</ObjectFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"RelWithDebInfo\"</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"RelWithDebInfo\"</PreprocessorDefinitions>

@ -99,9 +99,9 @@ void Hamster::DrawHamsters(TransformedView&tv){
const Animate2D::Frame&img{h.animations.GetState(h.internalAnimState)==HamsterGame::DEFAULT?anim.GetFrame(h.distanceTravelled/100.f):h.GetCurrentAnimation()}; const Animate2D::Frame&img{h.animations.GetState(h.internalAnimState)==HamsterGame::DEFAULT?anim.GetFrame(h.distanceTravelled/100.f):h.GetCurrentAnimation()};
const Animate2D::Frame&wheelTopImg{wheelTopAnim.GetFrame(h.distanceTravelled/80.f)}; const Animate2D::Frame&wheelTopImg{wheelTopAnim.GetFrame(h.distanceTravelled/80.f)};
const Animate2D::Frame&wheelBottomImg{wheelBottomAnim.GetFrame(h.distanceTravelled/80.f)}; const Animate2D::Frame&wheelBottomImg{wheelBottomAnim.GetFrame(h.distanceTravelled/80.f)};
tv.DrawPartialRotatedDecal(h.pos,wheelBottomImg.GetSourceImage()->Decal(),h.rot,wheelBottomImg.GetSourceRect().size/2,wheelBottomImg.GetSourceRect().pos,wheelBottomImg.GetSourceRect().size); if(h.HasPowerup(Powerup::WHEEL))tv.DrawPartialRotatedDecal(h.pos,wheelBottomImg.GetSourceImage()->Decal(),h.rot,wheelBottomImg.GetSourceRect().size/2,wheelBottomImg.GetSourceRect().pos,wheelBottomImg.GetSourceRect().size);
tv.DrawPartialRotatedDecal(h.pos,img.GetSourceImage()->Decal(),h.rot,img.GetSourceRect().size/2,img.GetSourceRect().pos,img.GetSourceRect().size); tv.DrawPartialRotatedDecal(h.pos,img.GetSourceImage()->Decal(),h.rot,img.GetSourceRect().size/2,img.GetSourceRect().pos,img.GetSourceRect().size);
tv.DrawPartialRotatedDecal(h.pos,wheelTopImg.GetSourceImage()->Decal(),h.rot,wheelTopImg.GetSourceRect().size/2,wheelTopImg.GetSourceRect().pos,wheelTopImg.GetSourceRect().size,{1.f,1.f},{255,255,255,192}); if(h.HasPowerup(Powerup::WHEEL))tv.DrawPartialRotatedDecal(h.pos,wheelTopImg.GetSourceImage()->Decal(),h.rot,wheelTopImg.GetSourceRect().size/2,wheelTopImg.GetSourceRect().pos,wheelTopImg.GetSourceRect().size,{1.f,1.f},{255,255,255,192});
} }
} }
@ -186,6 +186,12 @@ void Hamster::HandleCollision(){
bumpTimer=h.bumpTimer=0.12f; bumpTimer=h.bumpTimer=0.12f;
} }
} }
for(Powerup&powerup:Powerup::GetPowerups()){
if(!HasPowerup(powerup.GetType())&&geom2d::overlaps(geom2d::circle<float>(GetPos(),collisionRadius),geom2d::circle<float>(powerup.GetPos(),20.f))){
ObtainPowerup(powerup.GetType());
powerup.OnPowerupObtain();
}
}
} }
const float Hamster::GetRadius()const{ const float Hamster::GetRadius()const{
@ -240,3 +246,11 @@ const float Hamster::GetBumpAmount()const{
float finalBumpAmt{DEFAULT_BUMP_AMT}; float finalBumpAmt{DEFAULT_BUMP_AMT};
return finalBumpAmt*GetMaxSpeed()/DEFAULT_MAX_SPD; return finalBumpAmt*GetMaxSpeed()/DEFAULT_MAX_SPD;
} }
void Hamster::ObtainPowerup(const Powerup::PowerupType powerup){
powerups.insert(powerup);
}
const bool Hamster::HasPowerup(const Powerup::PowerupType powerup)const{
return powerups.count(powerup);
}

@ -41,6 +41,7 @@ All rights reserved.
#include "olcUTIL_Geometry2D.h" #include "olcUTIL_Geometry2D.h"
#include "olcUTIL_Animate2D.h" #include "olcUTIL_Animate2D.h"
#include "Terrain.h" #include "Terrain.h"
#include <unordered_set>
class Hamster{ class Hamster{
enum PlayerControlled{ enum PlayerControlled{
@ -81,6 +82,7 @@ class Hamster{
PlayerControlled IsPlayerControlled; PlayerControlled IsPlayerControlled;
static std::optional<Hamster*>playerHamster; static std::optional<Hamster*>playerHamster;
HamsterState state{NORMAL}; HamsterState state{NORMAL};
std::unordered_set<Powerup::PowerupType>powerups;
public: public:
Hamster(const vf2d spawnPos,const std::string_view img,const PlayerControlled IsPlayerControlled=NPC); Hamster(const vf2d spawnPos,const std::string_view img,const PlayerControlled IsPlayerControlled=NPC);
static const Hamster&GetPlayer(); static const Hamster&GetPlayer();
@ -100,4 +102,6 @@ public:
const float GetFriction()const; const float GetFriction()const;
const float GetTurnSpeed()const; const float GetTurnSpeed()const;
const float GetBumpAmount()const; const float GetBumpAmount()const;
void ObtainPowerup(const Powerup::PowerupType powerup);
const bool HasPowerup(const Powerup::PowerupType powerup)const;
}; };

@ -38,6 +38,7 @@ void HamsterGame::_LoadImage(const std::string_view img){
void HamsterGame::LoadGraphics(){ void HamsterGame::LoadGraphics(){
_LoadImage("border.png"); _LoadImage("border.png");
_LoadImage("gametiles.png"); _LoadImage("gametiles.png");
_LoadImage("shadow.png");
} }
void HamsterGame::LoadAnimations(){ void HamsterGame::LoadAnimations(){
@ -96,6 +97,7 @@ void HamsterGame::UpdateGame(const float fElapsedTime){
camera.Update(fElapsedTime); camera.Update(fElapsedTime);
tv.SetWorldOffset(-SCREEN_FRAME.pos+camera.GetViewPosition()); tv.SetWorldOffset(-SCREEN_FRAME.pos+camera.GetViewPosition());
Hamster::UpdateHamsters(fElapsedTime); Hamster::UpdateHamsters(fElapsedTime);
Powerup::UpdatePowerups(fElapsedTime);
border.Update(fElapsedTime); border.Update(fElapsedTime);
} }
@ -106,6 +108,24 @@ void HamsterGame::DrawGame(){
border.Draw(); border.Draw();
DrawStringDecal(SCREEN_FRAME.pos+vf2d{1,1},"Terrain Type: "+Terrain::TerrainToString(Hamster::GetPlayer().GetTerrainStandingOn()),BLACK); DrawStringDecal(SCREEN_FRAME.pos+vf2d{1,1},"Terrain Type: "+Terrain::TerrainToString(Hamster::GetPlayer().GetTerrainStandingOn()),BLACK);
DrawStringDecal(SCREEN_FRAME.pos,"Terrain Type: "+Terrain::TerrainToString(Hamster::GetPlayer().GetTerrainStandingOn())); DrawStringDecal(SCREEN_FRAME.pos,"Terrain Type: "+Terrain::TerrainToString(Hamster::GetPlayer().GetTerrainStandingOn()));
for(int y:std::ranges::iota_view(0,4)){
for(int x:std::ranges::iota_view(0,2)){
const int powerupInd{y*2+x};
const float drawX{x*32.f+12.f};
const float drawY{y*32.f+12.f+96.f};
const Powerup::PowerupType powerupType{Powerup::PowerupType(powerupInd)};
const geom2d::rect<float>powerupSubimageRect{Powerup::GetPowerupSubimageRect(powerupType)};
if(Hamster::GetPlayer().HasPowerup(powerupType)){
SetDecalMode(DecalMode::ADDITIVE);
DrawPartialRotatedDecal(vf2d{drawX,drawY}+16,GetGFX("gametiles.png").Decal(),0.f,{16.f,16.f},powerupSubimageRect.pos,powerupSubimageRect.size,{1.1f,1.1f});
SetDecalMode(DecalMode::NORMAL);
DrawPartialDecal({drawX,drawY},GetGFX("gametiles.png").Decal(),powerupSubimageRect.pos,powerupSubimageRect.size);
}else{
DrawPartialDecal({drawX,drawY},GetGFX("gametiles.png").Decal(),powerupSubimageRect.pos,powerupSubimageRect.size,{1.f,1.f},VERY_DARK_GREY);
}
}
}
} }
const Terrain::TerrainType HamsterGame::GetTerrainTypeAtPos(const vf2d pos)const{ const Terrain::TerrainType HamsterGame::GetTerrainTypeAtPos(const vf2d pos)const{

@ -55,7 +55,7 @@ const vf2d&Powerup::GetPos()const{
const Powerup::PowerupType&Powerup::GetType()const{ const Powerup::PowerupType&Powerup::GetType()const{
return type; return type;
} }
const std::vector<Powerup>&Powerup::GetPowerups(){ std::vector<Powerup>&Powerup::GetPowerups(){
return powerupList; return powerupList;
} }
@ -88,9 +88,30 @@ const Powerup::PowerupType Powerup::TileIDPowerupType(const int tileId){
return powerupIds.at(tileId).first; return powerupIds.at(tileId).first;
} }
void Powerup::UpdatePowerups(const float fElapsedTime){
for(Powerup&powerup:powerupList){
powerup.z=abs(pow(sin(HamsterGame::Game().GetRuntime()/1.5f*geom2d::pi),4.f)*4)+5;
if(powerup.spinSpd>0.f){
powerup.spinSpd+=fElapsedTime;
if(powerup.spinSpd>=3.f)powerup.spinSpd=0.f;
}
}
}
void Powerup::DrawPowerups(TransformedView&tv){ void Powerup::DrawPowerups(TransformedView&tv){
for(const Powerup&powerup:powerupList){ for(const Powerup&powerup:powerupList){
geom2d::rect<float>spriteRect{POWERUP_TILESET_STARTING_POS+vf2d{int(powerup.GetType())*32.f,0.f},{32,32}}; geom2d::rect<float>spriteRect{GetPowerupSubimageRect(powerup.GetType())};
tv.DrawPartialRotatedDecal(powerup.GetPos(),HamsterGame::GetGFX("gametiles.png").Decal(),0.f,{16,16},spriteRect.pos,spriteRect.size); tv.DrawRotatedDecal(powerup.GetPos(),HamsterGame::GetGFX("shadow.png").Decal(),0.f,{16,16});
float scaleX{1.f};
if(powerup.spinSpd>0.f)scaleX=sin(geom2d::pi*HamsterGame::Game().GetRuntime()/powerup.spinSpd);
tv.DrawPartialRotatedDecal(powerup.GetPos()-vf2d{0,powerup.z},HamsterGame::GetGFX("gametiles.png").Decal(),0.f,{16,16},spriteRect.pos,spriteRect.size,{scaleX,1.f});
} }
} }
const geom2d::rect<float>Powerup::GetPowerupSubimageRect(const PowerupType powerupType){
return {POWERUP_TILESET_STARTING_POS+vf2d{int(powerupType)*32.f,0.f},{32,32}};
}
void Powerup::OnPowerupObtain(){
spinSpd=0.3f;
}

@ -62,17 +62,22 @@ private:
static std::unordered_map<int,std::pair<PowerupType,TileType>>powerupIds; static std::unordered_map<int,std::pair<PowerupType,TileType>>powerupIds;
static const vf2d POWERUP_TILESET_STARTING_POS; static const vf2d POWERUP_TILESET_STARTING_POS;
vf2d pos; vf2d pos;
float z{5.f};
float spinSpd{};
PowerupType type; PowerupType type;
public: public:
Powerup(const vf2d pos,const PowerupType type); Powerup(const vf2d pos,const PowerupType type);
static void Initialize(const std::vector<Powerup>&powerupList); static void Initialize(const std::vector<Powerup>&powerupList);
const vf2d&GetPos()const; const vf2d&GetPos()const;
const PowerupType&GetType()const; const PowerupType&GetType()const;
static const std::vector<Powerup>&GetPowerups(); static std::vector<Powerup>&GetPowerups();
static void AddOrUpdatePowerupIdList(const int powerupId,const PowerupType powerupType); static void AddOrUpdatePowerupIdList(const int powerupId,const PowerupType powerupType);
static void AddOrUpdatePowerupIdList(const int powerupId,const TileType powerupTileType); static void AddOrUpdatePowerupIdList(const int powerupId,const TileType powerupTileType);
static const bool TileIDIsPowerupTile(const int tileId); static const bool TileIDIsPowerupTile(const int tileId);
static const bool TileIDIsUpperLeftPowerupTile(const int tileId); static const bool TileIDIsUpperLeftPowerupTile(const int tileId);
static const PowerupType TileIDPowerupType(const int tileId); static const PowerupType TileIDPowerupType(const int tileId);
static void UpdatePowerups(const float fElapsedTime);
static void DrawPowerups(TransformedView&tv); static void DrawPowerups(TransformedView&tv);
static const geom2d::rect<float>GetPowerupSubimageRect(const PowerupType powerupType);
void OnPowerupObtain();
}; };
Loading…
Cancel
Save