Added Hamster colors.
BIN
assets/hamster2.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
assets/hamster3.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/hamster4.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
assets/hamster5.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
assets/hamster6.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
assets/hamster7.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/hamster8.png
Normal file
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 std::vector<std::string>Hamster::NPC_HAMSTER_IMAGES{
|
||||
"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;
|
||||
|
||||
Hamster::Hamster(const vf2d spawnPos,const std::string&img,const PlayerControlled IsPlayerControlled)
|
||||
@ -219,22 +226,39 @@ void Hamster::UpdateHamsters(const float fElapsedTime){
|
||||
}
|
||||
}
|
||||
|
||||
void Hamster::LoadHamsters(const geom2d::rect<int>startingLoc){
|
||||
void Hamster::CreateHamsters(const HamsterGame::GameMode mode){
|
||||
HAMSTER_LIST.clear();
|
||||
playerHamster.reset();
|
||||
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)};
|
||||
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)){
|
||||
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)};
|
||||
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--;
|
||||
}
|
||||
std::string colorChoice{hamsterColorChoices.at(util::random()%hamsterColorChoices.size())};
|
||||
std::erase(hamsterColorChoices,colorChoice);
|
||||
Hamster&npcHamster{HAMSTER_LIST.emplace_back(vf2d{},colorChoice,NPC)};
|
||||
HamsterAI::AIType typeChosen{HamsterAI::DUMB};
|
||||
switch(mode){
|
||||
case HamsterGame::GameMode::GRAND_PRIX_1:{
|
||||
int randPct{util::random()%100};
|
||||
if(randPct<=25)typeChosen=HamsterAI::DUMB;
|
||||
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;
|
||||
case HamsterGame::GameMode::SINGLE_RACE:{
|
||||
int randPct{util::random()%100};
|
||||
switch(HamsterGame::Game().GetMapDifficulty()){
|
||||
case Difficulty::EASY:{
|
||||
@ -251,20 +275,43 @@ void Hamster::LoadHamsters(const geom2d::rect<int>startingLoc){
|
||||
if(randPct<=20)typeChosen=HamsterAI::NORMAL;
|
||||
}break;
|
||||
}
|
||||
}break;
|
||||
case HamsterGame::GameMode::MARATHON:{
|
||||
int randPct{util::random()%100};
|
||||
if(randPct<=1)typeChosen=HamsterAI::DUMB;
|
||||
else if(randPct<=20)typeChosen=HamsterAI::NORMAL;
|
||||
else typeChosen=HamsterAI::SMART;
|
||||
}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{};
|
||||
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){
|
||||
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)){
|
||||
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 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_TIME_TO_MAX_SPD{0.3f};
|
||||
@ -129,11 +129,13 @@ class Hamster{
|
||||
float boostTimer{};
|
||||
float canCollectWheelPowerupTimer{};
|
||||
float SEARCH_RANGE{1.f};
|
||||
HamsterAI::AIType aiLevel;
|
||||
public:
|
||||
Hamster(const vf2d spawnPos,const std::string&img,const PlayerControlled IsPlayerControlled=NPC);
|
||||
static const Hamster&GetPlayer();
|
||||
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 DrawOverlay();
|
||||
const Animate2D::Frame&GetCurrentAnimation()const;
|
||||
|
@ -44,6 +44,9 @@ bool HamsterGame::OnUserCreate(){
|
||||
LoadSound("nene - Boss Battle #5 V2.ogg");
|
||||
|
||||
LoadLevel("StageV.tmx"); //THIS IS TEMPORARY.
|
||||
Hamster::CreateHamsters(mode);
|
||||
Hamster::MoveHamstersToSpawn(currentMap.value().GetData().GetSpawnZone());
|
||||
camera.SetTarget(Hamster::GetPlayer().GetPos());
|
||||
|
||||
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::KNOCKOUT,"hamster.png",{{64,32},{96,32}},0.2f);
|
||||
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};
|
||||
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}}});
|
||||
@ -148,9 +158,6 @@ void HamsterGame::LoadLevel(const std::string&mapName){
|
||||
camera.Update(0.f);
|
||||
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);
|
||||
SetDrawTarget(mapImage.Sprite());
|
||||
Clear(BLANK);
|
||||
|
@ -60,6 +60,13 @@ struct Letter{
|
||||
class HamsterGame : public olc::PixelGameEngine
|
||||
{
|
||||
public:
|
||||
enum class GameMode{
|
||||
GRAND_PRIX_1,
|
||||
GRAND_PRIX_2,
|
||||
GRAND_PRIX_3,
|
||||
SINGLE_RACE,
|
||||
MARATHON,
|
||||
};
|
||||
const static std::string ASSETS_DIR;
|
||||
HamsterGame()=delete;
|
||||
HamsterGame(const std::string&appName);
|
||||
@ -122,4 +129,5 @@ private:
|
||||
std::string currentMapName;
|
||||
MiniAudio audio;
|
||||
std::unordered_map<std::string,int>bgm;
|
||||
GameMode mode{GameMode::SINGLE_RACE};
|
||||
};
|