|
|
|
#define OLC_PGE_APPLICATION
|
|
|
|
#include "olcPixelGameEngine.h"
|
|
|
|
#define OLC_SOUNDWAVE
|
|
|
|
#include "olcSoundWaveEngine.h"
|
|
|
|
#include "VirusAttack.h"
|
|
|
|
#include "olcUTIL_Geometry2D.h"
|
|
|
|
|
|
|
|
VirusAttack::VirusAttack()
|
|
|
|
{
|
|
|
|
// Name your application
|
|
|
|
sAppName = "olcCodeJam 2023 Entry";
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VirusAttack::OnUserCreate(){
|
|
|
|
|
|
|
|
CONSTANT::VIRUS_IMG1.Load("assets/unit.png");
|
|
|
|
CONSTANT::SELECTION_CIRCLE.Load("assets/selection_circle.png");
|
|
|
|
|
|
|
|
units.push_back(std::make_unique<BasicUnit>(vf2d{32,32},CONSTANT::VIRUS_IMG1,true));
|
|
|
|
for(int i=0;i<10;i++){
|
|
|
|
if(rand()%2==0){
|
|
|
|
units.push_back(std::make_unique<BasicUnit>(vf2d{float(rand()%ScreenWidth()),float(rand()%ScreenHeight())},CONSTANT::VIRUS_IMG1,true));
|
|
|
|
} else {
|
|
|
|
units.push_back(std::make_unique<BasicUnit2>(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=GetMousePos();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(GetMouse(0).bReleased){
|
|
|
|
vf2d endDragPos=GetMousePos();
|
|
|
|
if(endDragPos.x<startingDragPos.x){std::swap(startingDragPos.x,endDragPos.x);}
|
|
|
|
if(endDragPos.y<startingDragPos.y){std::swap(startingDragPos.y,endDragPos.y);}
|
|
|
|
geom2d::rect<float> selectionRegion(startingDragPos,endDragPos-startingDragPos);
|
|
|
|
for(auto&u:units){
|
|
|
|
if(u->IsFriendly()){
|
|
|
|
if(geom2d::overlaps(selectionRegion,u->GetPos())){
|
|
|
|
u->Select();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
startingDragPos=CONSTANT::UNSELECTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirusAttack::DrawSelectionRectangle(){
|
|
|
|
if(startingDragPos!=CONSTANT::UNSELECTED){
|
|
|
|
FillRectDecal(startingDragPos,GetMousePos()-startingDragPos,{255,255,0,128});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirusAttack::HandleRightClickMove(){
|
|
|
|
if (GetMouse(1).bPressed){
|
|
|
|
bool selectedTarget=false;
|
|
|
|
for(auto&u:units){
|
|
|
|
if(!u->IsFriendly()){
|
|
|
|
geom2d::rect<float> unitRegion(u->GetPos()-u->GetUnitSize()/2,u->GetUnitSize());
|
|
|
|
if(geom2d::overlaps(unitRegion,GetMousePos())){
|
|
|
|
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(GetMousePos());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void VirusAttack::CollisionChecking(std::shared_ptr<Unit>u,std::shared_ptr<Unit>u2){
|
|
|
|
if(u!=u2&&geom2d::overlaps(geom2d::circle<float>(u->GetPos(),u->GetUnitSize().x/2),geom2d::circle<float>(u2->GetPos(),u2->GetUnitSize().x/2))){
|
|
|
|
geom2d::line<float>collisionLine(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_ptr<Unit>u,std::shared_ptr<Unit>u2){
|
|
|
|
if(u->IsFriendly()!=u2->IsFriendly()){
|
|
|
|
geom2d::line<float>unitLine(u->GetPos(),u2->GetPos());
|
|
|
|
if(unitLine.length()<closestDist){
|
|
|
|
closestUnit=u2.get();
|
|
|
|
closestDist=unitLine.length();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VirusAttack::OnUserUpdate(float fElapsedTime){
|
|
|
|
HandleDraggingSelection();
|
|
|
|
HandleRightClickMove();
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(auto&u:units){
|
|
|
|
u->Draw(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
DrawSelectionRectangle();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
VirusAttack app;
|
|
|
|
if (app.Construct(426, 320, 4, 4))
|
|
|
|
app.Start();
|
|
|
|
return 0;
|
|
|
|
}
|