Fixed unit attacking
This commit is contained in:
parent
5c211ce9b3
commit
2a538d0aee
olcCodeJam2023Entry
@ -13,7 +13,7 @@ BasicUnit::BasicUnit(vf2d pos,Renderable&img,bool friendly)
|
||||
|
||||
|
||||
void BasicUnit::Attack(Unit&victim){
|
||||
|
||||
victim<<=1;
|
||||
}
|
||||
|
||||
BasicUnit2::BasicUnit2(vf2d pos,Renderable&img,bool friendly)
|
||||
@ -94,7 +94,7 @@ void Unit::Draw(PixelGameEngine*pge){
|
||||
CheckColor(i,col);
|
||||
|
||||
pge->FillRectDecal({float(initialBarX)+i*CONSTANT::BAR_SQUARE_SIZE.x,
|
||||
float(initialBarY)},CONSTANT::BAR_SQUARE_SIZE,col);
|
||||
float(initialBarY)},CONSTANT::BAR_SQUARE_SIZE,memory[i]?col:col/4);
|
||||
pge->DrawRectDecal({float(initialBarX)+i*CONSTANT::BAR_SQUARE_SIZE.x,
|
||||
float(initialBarY)},CONSTANT::BAR_SQUARE_SIZE,BLACK);
|
||||
}
|
||||
@ -153,22 +153,26 @@ void Unit::Update(float fElapsedTime){
|
||||
pos+=(targetLoc-pos).norm()*GetMoveSpd()*24*fElapsedTime;
|
||||
}
|
||||
}
|
||||
|
||||
reloadTimer=std::max(0.f,reloadTimer-fElapsedTime);
|
||||
}
|
||||
|
||||
Unit& operator <<(Unit&u,const int n){
|
||||
std::vector<bool> operator <<(Unit&u,const int n){
|
||||
std::vector<bool>tempMem=u.memory;
|
||||
for(int i=0;i<u.GetMemorySize()-1;i++){
|
||||
u.memory[i]=u.memory[i+1];
|
||||
tempMem[i]=tempMem[i+1];
|
||||
}
|
||||
u.memory[u.GetMemorySize()-1]=0;
|
||||
return u;
|
||||
tempMem[u.GetMemorySize()-1]=0;
|
||||
return tempMem;
|
||||
}
|
||||
|
||||
Unit& operator >>(Unit&u,const int n){
|
||||
std::vector<bool> operator >>(Unit&u,const int n){
|
||||
std::vector<bool>tempMem=u.memory;
|
||||
for(int i=1;i<u.GetMemorySize();i++){
|
||||
u.memory[i]=u.memory[i-1];
|
||||
tempMem[i]=tempMem[i-1];
|
||||
}
|
||||
u.memory[0]=0;
|
||||
return u;
|
||||
tempMem[0]=0;
|
||||
return tempMem;
|
||||
}
|
||||
|
||||
bool Unit::IsFriendly(){
|
||||
@ -223,3 +227,27 @@ bool Unit::InRange(vf2d pos){
|
||||
void Unit::SetPos(vf2d newPos){
|
||||
pos=newPos;
|
||||
}
|
||||
|
||||
void Unit::AttemptAttack(Unit*unit){
|
||||
if(reloadTimer>0)return;
|
||||
Unit*finalTarget=nullptr;
|
||||
if(unit!=nullptr){
|
||||
finalTarget=unit;
|
||||
if(!target.expired()){
|
||||
auto ptrTarget=target.lock();
|
||||
if(InRange(ptrTarget)){
|
||||
finalTarget=ptrTarget.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(finalTarget!=nullptr){
|
||||
if(InRange(finalTarget->GetPos())){
|
||||
_Attack(finalTarget); //Call the parent function first, followed by the child.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::_Attack(Unit*finalTarget){
|
||||
Attack(*finalTarget);
|
||||
reloadTimer=1.f/GetAtkSpd();
|
||||
}
|
@ -21,13 +21,6 @@ struct Memory{
|
||||
int size;
|
||||
};
|
||||
|
||||
struct Unit;
|
||||
|
||||
struct UnitGroup{
|
||||
std::vector<std::weak_ptr<Unit>>group;
|
||||
vf2d pos;
|
||||
};
|
||||
|
||||
struct Unit{
|
||||
public:
|
||||
Unit(std::vector<Memory>memory,vf2d pos,Renderable&img,bool friendly=false);
|
||||
@ -51,6 +44,24 @@ public:
|
||||
void SetTargetUnit(std::weak_ptr<Unit>target);
|
||||
void SetTargetLocation(vf2d targetLoc);
|
||||
void SetPos(vf2d newPos);
|
||||
void AttemptAttack(Unit*unit);
|
||||
|
||||
|
||||
std::vector<bool>& operator <<=(const int n){
|
||||
for(int i=0;i<GetMemorySize()-1;i++){
|
||||
memory[i]=memory[i+1];
|
||||
}
|
||||
memory[GetMemorySize()-1]=0;
|
||||
return memory;
|
||||
}
|
||||
|
||||
std::vector<bool>& operator >>=(const int n){
|
||||
for(int i=GetMemorySize()-1;i>0;i--){
|
||||
memory[i]=memory[i-1];
|
||||
}
|
||||
memory[0]=0;
|
||||
return memory;
|
||||
}
|
||||
protected:
|
||||
vf2d pos;
|
||||
bool friendly;
|
||||
@ -62,13 +73,14 @@ protected:
|
||||
Marker procedure;
|
||||
std::weak_ptr<Unit>target;
|
||||
vf2d targetLoc=CONSTANT::UNSELECTED;
|
||||
std::weak_ptr<UnitGroup>group;
|
||||
private:
|
||||
int GetBits(Marker&m);
|
||||
bool selected=false;
|
||||
bool dead=false;
|
||||
bool InRange(std::shared_ptr<Unit>target);
|
||||
bool InRange(vf2d pos);
|
||||
float reloadTimer=0;
|
||||
void _Attack(Unit*finalTarget);
|
||||
};
|
||||
|
||||
struct BasicUnit:Unit{
|
||||
|
@ -19,7 +19,7 @@ bool VirusAttack::OnUserCreate(){
|
||||
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,false));
|
||||
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));
|
||||
}
|
||||
@ -58,9 +58,7 @@ void VirusAttack::DrawSelectionRectangle(){
|
||||
}
|
||||
}
|
||||
|
||||
bool VirusAttack::OnUserUpdate(float fElapsedTime){
|
||||
HandleDraggingSelection();
|
||||
|
||||
void VirusAttack::HandleRightClickMove(){
|
||||
if (GetMouse(1).bPressed){
|
||||
bool selectedTarget=false;
|
||||
for(auto&u:units){
|
||||
@ -85,10 +83,10 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto&u:units){
|
||||
for(auto&u2:units){
|
||||
if(&u!=&u2&&geom2d::overlaps(geom2d::circle<float>(u->GetPos(),u->GetUnitSize().x/2),geom2d::circle<float>(u2->GetPos(),u2->GetUnitSize().x/2))){
|
||||
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();
|
||||
@ -96,7 +94,30 @@ bool VirusAttack::OnUserUpdate(float fElapsedTime){
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,9 @@ private:
|
||||
vf2d startingDragPos=CONSTANT::UNSELECTED;
|
||||
void HandleDraggingSelection();
|
||||
void DrawSelectionRectangle();
|
||||
void HandleRightClickMove();
|
||||
void CollisionChecking(std::shared_ptr<Unit>u,std::shared_ptr<Unit>u2);
|
||||
void IdentifyClosestTarget(Unit*&closestUnit,float&closestDist,std::shared_ptr<Unit>u,std::shared_ptr<Unit>u2);
|
||||
|
||||
public:
|
||||
VirusAttack();
|
||||
|
Loading…
x
Reference in New Issue
Block a user