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 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,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();
|
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};
|
||||||
|
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};
|
int randPct{util::random()%100};
|
||||||
switch(HamsterGame::Game().GetMapDifficulty()){
|
switch(HamsterGame::Game().GetMapDifficulty()){
|
||||||
case Difficulty::EASY:{
|
case Difficulty::EASY:{
|
||||||
@ -251,20 +275,43 @@ void Hamster::LoadHamsters(const geom2d::rect<int>startingLoc){
|
|||||||
if(randPct<=20)typeChosen=HamsterAI::NORMAL;
|
if(randPct<=20)typeChosen=HamsterAI::NORMAL;
|
||||||
}break;
|
}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{};
|
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};
|
||||||
};
|
};
|