#define OLC_PGE_APPLICATION #define OLC_SOUNDWAVE #define OLC_PGEX_TRANSFORMEDVIEW #include "olcUTIL_Geometry2D.h" #include "VirusAttack.h" VirusAttack::VirusAttack() { // Name your application sAppName = "olcCodeJam 2023 Entry"; } bool VirusAttack::OnUserCreate(){ game.Initialise(GetScreenSize()); CONSTANT::VIRUS_IMG1.Load("assets/unit.png"); CONSTANT::SELECTION_CIRCLE.Load("assets/selection_circle.png"); TILE.Load("assets/tile.png",nullptr,false,false); units.push_back(std::make_unique(vf2d{32,32},CONSTANT::VIRUS_IMG1,true)); for(int i=0;i<10;i++){ if(rand()%2==0){ units.push_back(std::make_unique(vf2d{float(rand()%ScreenWidth()),float(rand()%ScreenHeight())},CONSTANT::VIRUS_IMG1,true)); } else { units.push_back(std::make_unique(vf2d{float(rand()%ScreenWidth()),float(rand()%ScreenHeight())},CONSTANT::VIRUS_IMG1,false)); } } return true; } void VirusAttack::HandleDraggingSelection(){ if(GetMouse(0).bPressed){ for(auto&u:units){ u->Deselect(); } if(startingDragPos==CONSTANT::UNSELECTED){ startingDragPos=GetWorldMousePos(); } } if(GetMouse(0).bReleased){ vf2d endDragPos=GetWorldMousePos(); if(endDragPos.x selectionRegion(startingDragPos,endDragPos-startingDragPos); for(auto&u:units){ if(u->IsFriendly()){ if(geom2d::overlaps(selectionRegion,u->GetPos())){ u->Select(); } } } startingDragPos=CONSTANT::UNSELECTED; } } vf2d VirusAttack::GetWorldMousePos(){ return game.ScreenToWorld(GetMousePos()); } void VirusAttack::DrawSelectionRectangle(){ if(startingDragPos!=CONSTANT::UNSELECTED){ game.FillRectDecal(startingDragPos,GetWorldMousePos()-startingDragPos,{255,255,0,128}); } } void VirusAttack::HandleRightClickMove(){ if (GetMouse(1).bPressed){ bool selectedTarget=false; for(auto&u:units){ if(!u->IsFriendly()){ geom2d::rect unitRegion(u->GetPos()-u->GetUnitSize()/2,u->GetUnitSize()); if(geom2d::overlaps(unitRegion,GetWorldMousePos())){ for(auto&u2:units){ if(u2->IsFriendly()&&u2->IsSelected()){ u2->SetTargetUnit(u); } } selectedTarget=true; break; } } } if(!selectedTarget){ for(auto&u:units){ if(u->IsFriendly()&&u->IsSelected()){ u->SetTargetLocation(GetWorldMousePos()); } } } } } void VirusAttack::CollisionChecking(std::shared_ptru,std::shared_ptru2){ if(u!=u2&&geom2d::overlaps(geom2d::circle(u->GetPos(),u->GetUnitSize().x/2),geom2d::circle(u2->GetPos(),u2->GetUnitSize().x/2))){ geom2d::linecollisionLine(u->GetPos(),u2->GetPos()); float maxDist=u->GetUnitSize().x/2+u2->GetUnitSize().x/2; float dist=maxDist-collisionLine.length(); vf2d dir=collisionLine.vector().norm(); u->SetPos(u->GetPos()-dir*dist/2); u2->SetPos(u2->GetPos()+dir*dist/2); } } void VirusAttack::IdentifyClosestTarget(Unit*&closestUnit,float&closestDist,std::shared_ptru,std::shared_ptru2){ if(u->IsFriendly()!=u2->IsFriendly()){ geom2d::lineunitLine(u->GetPos(),u2->GetPos()); if(unitLine.length()0){ if(game.GetWorldScale().x<2){ game.ZoomAtScreenPos(1.25,GetMousePos()); } } else if(GetMouseWheel()<0){ if(game.GetWorldScale().x>0.5){ game.ZoomAtScreenPos(0.75,GetMousePos()); } } for(auto&u:units){ Unit*closestUnit=nullptr; float closestDist=999999; for(auto&u2:units){ IdentifyClosestTarget(closestUnit,closestDist,u,u2); CollisionChecking(u,u2); } u->AttemptAttack(closestUnit); u->Update(fElapsedTime); } game.DrawPartialDecal({0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,TILE.Decal(),{0,0},CONSTANT::WORLD_SIZE*CONSTANT::TILE_SIZE,DARK_GREEN); for(auto&u:units){ u->Draw(game); } for(auto&u:units){ u->DrawHud(game); } DrawSelectionRectangle(); return true; } int main() { VirusAttack app; if (app.Construct(426, 320, 4, 4)) app.Start(); return 0; }