Added Hamster colors.

sigonasr2 3 months ago
parent 0f725d2403
commit d7580453d3
  1. BIN
      assets/hamster.xcf
  2. BIN
      assets/hamster2.png
  3. BIN
      assets/hamster3.png
  4. BIN
      assets/hamster4.png
  5. BIN
      assets/hamster5.png
  6. BIN
      assets/hamster6.png
  7. BIN
      assets/hamster7.png
  8. BIN
      assets/hamster8.png
  9. 99
      src/Hamster.cpp
  10. 6
      src/Hamster.h
  11. 13
      src/HamsterGame.cpp
  12. 8
      src/HamsterGame.h

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@ -49,8 +49,15 @@ const uint8_t Hamster::MAX_HAMSTER_COUNT{100U};
const uint8_t Hamster::NPC_HAMSTER_COUNT{5U}; const uint8_t Hamster::NPC_HAMSTER_COUNT{5U};
const std::vector<std::string>Hamster::NPC_HAMSTER_IMAGES{ const std::vector<std::string>Hamster::NPC_HAMSTER_IMAGES{
"hamster.png", "hamster.png",
"hamster2.png",
"hamster3.png",
"hamster4.png",
"hamster5.png",
"hamster6.png",
"hamster7.png",
"hamster8.png",
}; };
const std::string Hamster::PLAYER_HAMSTER_IMAGE{"hamster.png"}; std::string Hamster::PLAYER_HAMSTER_IMAGE{"hamster.png"};
std::optional<Hamster*>Hamster::playerHamster; std::optional<Hamster*>Hamster::playerHamster;
Hamster::Hamster(const vf2d spawnPos,const std::string&img,const PlayerControlled IsPlayerControlled) Hamster::Hamster(const vf2d spawnPos,const std::string&img,const PlayerControlled IsPlayerControlled)
@ -219,52 +226,92 @@ void Hamster::UpdateHamsters(const float fElapsedTime){
} }
} }
void Hamster::LoadHamsters(const geom2d::rect<int>startingLoc){ void Hamster::CreateHamsters(const HamsterGame::GameMode mode){
HAMSTER_LIST.clear(); HAMSTER_LIST.clear();
playerHamster.reset(); playerHamster.reset();
HAMSTER_LIST.reserve(MAX_HAMSTER_COUNT); HAMSTER_LIST.reserve(MAX_HAMSTER_COUNT);
if(NPC_HAMSTER_COUNT+1>MAX_HAMSTER_COUNT)throw std::runtime_error{std::format("WARNING! Max hamster count is too high! Please expand the MAX_HAMSTER_COUNT if you want more hamsters. Requested {} hamsters.",MAX_HAMSTER_COUNT)}; if(NPC_HAMSTER_COUNT+1>MAX_HAMSTER_COUNT)throw std::runtime_error{std::format("WARNING! Max hamster count is too high! Please expand the MAX_HAMSTER_COUNT if you want more hamsters. Requested {} hamsters.",MAX_HAMSTER_COUNT)};
playerHamster=&HAMSTER_LIST.emplace_back(vf2d{util::random_range(startingLoc.pos.x,startingLoc.pos.x+startingLoc.size.x),util::random_range(startingLoc.pos.y,startingLoc.pos.y+startingLoc.size.y)},PLAYER_HAMSTER_IMAGE,PLAYER_CONTROLLED); playerHamster=&HAMSTER_LIST.emplace_back(vf2d{},PLAYER_HAMSTER_IMAGE,PLAYER_CONTROLLED);
std::vector<std::string>hamsterColorChoices{NPC_HAMSTER_IMAGES};
std::erase(hamsterColorChoices,PLAYER_HAMSTER_IMAGE);
for(int i:std::ranges::iota_view(0U,NPC_HAMSTER_COUNT)){ for(int i:std::ranges::iota_view(0U,NPC_HAMSTER_COUNT)){
Hamster&npcHamster{HAMSTER_LIST.emplace_back(vf2d{util::random_range(startingLoc.pos.x,startingLoc.pos.x+startingLoc.size.x),util::random_range(startingLoc.pos.y,startingLoc.pos.y+startingLoc.size.y)},NPC_HAMSTER_IMAGES.at(util::random()%NPC_HAMSTER_IMAGES.size()),NPC)}; std::string colorChoice{hamsterColorChoices.at(util::random()%hamsterColorChoices.size())};
int MAX_AI_FILES{100}; std::erase(hamsterColorChoices,colorChoice);
int aiFileCount{0}; Hamster&npcHamster{HAMSTER_LIST.emplace_back(vf2d{},colorChoice,NPC)};
while(MAX_AI_FILES>0){
if(!std::filesystem::exists(std::format("{}{}.{}",HamsterGame::ASSETS_DIR,HamsterGame::Game().GetCurrentMapName(),aiFileCount)))break;
aiFileCount++;
MAX_AI_FILES--;
}
HamsterAI::AIType typeChosen{HamsterAI::DUMB}; HamsterAI::AIType typeChosen{HamsterAI::DUMB};
int randPct{util::random()%100}; switch(mode){
switch(HamsterGame::Game().GetMapDifficulty()){ case HamsterGame::GameMode::GRAND_PRIX_1:{
case Difficulty::EASY:{ int randPct{util::random()%100};
if(randPct<=40&&randPct>20)typeChosen=HamsterAI::NORMAL; if(randPct<=25)typeChosen=HamsterAI::DUMB;
else if(randPct<=20)typeChosen=HamsterAI::SMART; else if(randPct<=75)typeChosen=HamsterAI::NORMAL;
else typeChosen=HamsterAI::SMART;
}break;
case HamsterGame::GameMode::GRAND_PRIX_2:{
int randPct{util::random()%100};
if(randPct<=10)typeChosen=HamsterAI::DUMB;
else if(randPct<=2)typeChosen=HamsterAI::NORMAL;
else typeChosen=HamsterAI::SMART;
}break;
case HamsterGame::GameMode::GRAND_PRIX_3:{
int randPct{util::random()%100};
if(randPct<=1)typeChosen=HamsterAI::DUMB;
else if(randPct<=20)typeChosen=HamsterAI::NORMAL;
else typeChosen=HamsterAI::SMART;
}break; }break;
case Difficulty::MEDIUM:{ case HamsterGame::GameMode::SINGLE_RACE:{
typeChosen=HamsterAI::NORMAL; int randPct{util::random()%100};
if(randPct<=100&&randPct>80)typeChosen=HamsterAI::DUMB; switch(HamsterGame::Game().GetMapDifficulty()){
else if(randPct<=20)typeChosen=HamsterAI::SMART; case Difficulty::EASY:{
if(randPct<=40&&randPct>20)typeChosen=HamsterAI::NORMAL;
else if(randPct<=20)typeChosen=HamsterAI::SMART;
}break;
case Difficulty::MEDIUM:{
typeChosen=HamsterAI::NORMAL;
if(randPct<=100&&randPct>80)typeChosen=HamsterAI::DUMB;
else if(randPct<=20)typeChosen=HamsterAI::SMART;
}break;
case Difficulty::HARD:{
typeChosen=HamsterAI::SMART;
if(randPct<=20)typeChosen=HamsterAI::NORMAL;
}break;
}
}break; }break;
case Difficulty::HARD:{ case HamsterGame::GameMode::MARATHON:{
typeChosen=HamsterAI::SMART; int randPct{util::random()%100};
if(randPct<=20)typeChosen=HamsterAI::NORMAL; if(randPct<=1)typeChosen=HamsterAI::DUMB;
else if(randPct<=20)typeChosen=HamsterAI::NORMAL;
else typeChosen=HamsterAI::SMART;
}break; }break;
} }
npcHamster.aiLevel=typeChosen;
}
}
void Hamster::MoveHamstersToSpawn(const geom2d::rect<int>startingLoc){
int MAX_AI_FILES{100};
int aiFileCount{0};
while(MAX_AI_FILES>0){
if(!std::filesystem::exists(std::format("{}{}.{}",HamsterGame::ASSETS_DIR,HamsterGame::Game().GetCurrentMapName(),aiFileCount)))break;
aiFileCount++;
MAX_AI_FILES--;
}
for(Hamster&hamster:HAMSTER_LIST){
hamster.SetPos(vf2d{util::random_range(startingLoc.pos.x,startingLoc.pos.x+startingLoc.size.x),util::random_range(startingLoc.pos.y,startingLoc.pos.y+startingLoc.size.y)});
std::vector<int>possibleAIs{}; std::vector<int>possibleAIs{};
for(int i:std::ranges::iota_view(0,aiFileCount)){ for(int i:std::ranges::iota_view(0,aiFileCount)){
if(i%3==int(typeChosen))possibleAIs.emplace_back(i); if(i%3==hamster.aiLevel)possibleAIs.emplace_back(i);
} }
if(possibleAIs.size()==0){ if(possibleAIs.size()==0){
std::cout<<"WARNING! No AI files for AI Type "<<int(typeChosen)<<" currently exist! Consider adding them! Rolling with whatever exists..."<<std::endl; std::cout<<"WARNING! No AI files for AI Type "<<int(hamster.aiLevel)<<" currently exist! Consider adding them! Rolling with whatever exists..."<<std::endl;
for(int i:std::ranges::iota_view(0,aiFileCount)){ for(int i:std::ranges::iota_view(0,aiFileCount)){
possibleAIs.emplace_back(i); possibleAIs.emplace_back(i);
} }
} }
if(possibleAIs.size()>0)npcHamster.ai.LoadAI(HamsterGame::Game().GetCurrentMapName(),possibleAIs[util::random()%possibleAIs.size()]); if(possibleAIs.size()>0)hamster.ai.LoadAI(HamsterGame::Game().GetCurrentMapName(),possibleAIs[util::random()%possibleAIs.size()]);
} }
} }

@ -75,7 +75,7 @@ class Hamster{
static const uint8_t NPC_HAMSTER_COUNT; static const uint8_t NPC_HAMSTER_COUNT;
static const std::vector<std::string>NPC_HAMSTER_IMAGES; static const std::vector<std::string>NPC_HAMSTER_IMAGES;
static const std::string PLAYER_HAMSTER_IMAGE; static std::string PLAYER_HAMSTER_IMAGE;
const float DEFAULT_MAX_SPD{128.f}; const float DEFAULT_MAX_SPD{128.f};
const float DEFAULT_TIME_TO_MAX_SPD{0.3f}; const float DEFAULT_TIME_TO_MAX_SPD{0.3f};
@ -129,11 +129,13 @@ class Hamster{
float boostTimer{}; float boostTimer{};
float canCollectWheelPowerupTimer{}; float canCollectWheelPowerupTimer{};
float SEARCH_RANGE{1.f}; float SEARCH_RANGE{1.f};
HamsterAI::AIType aiLevel;
public: public:
Hamster(const vf2d spawnPos,const std::string&img,const PlayerControlled IsPlayerControlled=NPC); Hamster(const vf2d spawnPos,const std::string&img,const PlayerControlled IsPlayerControlled=NPC);
static const Hamster&GetPlayer(); static const Hamster&GetPlayer();
static void UpdateHamsters(const float fElapsedTime); static void UpdateHamsters(const float fElapsedTime);
static void LoadHamsters(const geom2d::rect<int>startingLoc); static void CreateHamsters(const HamsterGame::GameMode mode);
static void MoveHamstersToSpawn(const geom2d::rect<int>startingLoc);
static void DrawHamsters(TransformedView&tv); static void DrawHamsters(TransformedView&tv);
static void DrawOverlay(); static void DrawOverlay();
const Animate2D::Frame&GetCurrentAnimation()const; const Animate2D::Frame&GetCurrentAnimation()const;

@ -44,6 +44,9 @@ bool HamsterGame::OnUserCreate(){
LoadSound("nene - Boss Battle #5 V2.ogg"); LoadSound("nene - Boss Battle #5 V2.ogg");
LoadLevel("StageV.tmx"); //THIS IS TEMPORARY. LoadLevel("StageV.tmx"); //THIS IS TEMPORARY.
Hamster::CreateHamsters(mode);
Hamster::MoveHamstersToSpawn(currentMap.value().GetData().GetSpawnZone());
camera.SetTarget(Hamster::GetPlayer().GetPos());
border.ChangeBorder(Border::DEFAULT); border.ChangeBorder(Border::DEFAULT);
@ -119,6 +122,13 @@ void HamsterGame::LoadAnimations(){
LoadAnimation(AnimationState::WHEEL_BOTTOM,"hamster.png",{{64,96},{96,96}},0.1f); LoadAnimation(AnimationState::WHEEL_BOTTOM,"hamster.png",{{64,96},{96,96}},0.1f);
LoadAnimation(AnimationState::KNOCKOUT,"hamster.png",{{64,32},{96,32}},0.2f); LoadAnimation(AnimationState::KNOCKOUT,"hamster.png",{{64,32},{96,32}},0.2f);
LoadAnimation(AnimationState::SIDE_VIEW,"hamster.png",{{0,0},{32,0}},0.3f); LoadAnimation(AnimationState::SIDE_VIEW,"hamster.png",{{0,0},{32,0}},0.3f);
for(int i:std::ranges::iota_view(2,9)){
LoadAnimation(AnimationState::DEFAULT,std::format("hamster{}.png",i),{{0,32},{32,32}},0.3f);
LoadAnimation(AnimationState::WHEEL_TOP,std::format("hamster{}.png",i),{{0,96},{32,96}},0.1f);
LoadAnimation(AnimationState::WHEEL_BOTTOM,std::format("hamster{}.png",i),{{64,96},{96,96}},0.1f);
LoadAnimation(AnimationState::KNOCKOUT,std::format("hamster{}.png",i),{{64,32},{96,32}},0.2f);
LoadAnimation(AnimationState::SIDE_VIEW,std::format("hamster{}.png",i),{{0,0},{32,0}},0.3f);
}
Animate2D::FrameSequence&waterAnimFrames{(*ANIMATED_TILE_IDS.insert({1384,Animate2D::FrameSequence{0.2f}}).first).second}; Animate2D::FrameSequence&waterAnimFrames{(*ANIMATED_TILE_IDS.insert({1384,Animate2D::FrameSequence{0.2f}}).first).second};
for(vf2d&sourcePos:std::vector<vf2d>{{192+16*0,784},{192+16*1,784},{192+16*2,784},{192+16*3,784},{192+16*4,784},{192+16*5,784},{192+16*6,784},{192+16*7,784}}){ for(vf2d&sourcePos:std::vector<vf2d>{{192+16*0,784},{192+16*1,784},{192+16*2,784},{192+16*3,784},{192+16*4,784},{192+16*5,784},{192+16*6,784},{192+16*7,784}}){
waterAnimFrames.AddFrame(Animate2D::Frame{&GetGFX("gametiles.png"),{sourcePos,{16,16}}}); waterAnimFrames.AddFrame(Animate2D::Frame{&GetGFX("gametiles.png"),{sourcePos,{16,16}}});
@ -148,9 +158,6 @@ void HamsterGame::LoadLevel(const std::string&mapName){
camera.Update(0.f); camera.Update(0.f);
camera.SetMode(Camera2D::Mode::LazyFollow); camera.SetMode(Camera2D::Mode::LazyFollow);
Hamster::LoadHamsters(currentMap.value().GetData().GetSpawnZone());
camera.SetTarget(Hamster::GetPlayer().GetPos());
mapImage.Create(currentMap.value().GetData().GetMapData().width*16,currentMap.value().GetData().GetMapData().height*16); mapImage.Create(currentMap.value().GetData().GetMapData().width*16,currentMap.value().GetData().GetMapData().height*16);
SetDrawTarget(mapImage.Sprite()); SetDrawTarget(mapImage.Sprite());
Clear(BLANK); Clear(BLANK);

@ -60,6 +60,13 @@ struct Letter{
class HamsterGame : public olc::PixelGameEngine class HamsterGame : public olc::PixelGameEngine
{ {
public: public:
enum class GameMode{
GRAND_PRIX_1,
GRAND_PRIX_2,
GRAND_PRIX_3,
SINGLE_RACE,
MARATHON,
};
const static std::string ASSETS_DIR; const static std::string ASSETS_DIR;
HamsterGame()=delete; HamsterGame()=delete;
HamsterGame(const std::string&appName); HamsterGame(const std::string&appName);
@ -122,4 +129,5 @@ private:
std::string currentMapName; std::string currentMapName;
MiniAudio audio; MiniAudio audio;
std::unordered_map<std::string,int>bgm; std::unordered_map<std::string,int>bgm;
GameMode mode{GameMode::SINGLE_RACE};
}; };
Loading…
Cancel
Save