Unit Collisions
This commit is contained in:
parent
bf61fa77b4
commit
5c211ce9b3
@ -1,5 +1,6 @@
|
||||
#include "Unit.h"
|
||||
#include "Constant.h"
|
||||
#include "olcUTIL_Geometry2D.h"
|
||||
|
||||
BasicUnit::BasicUnit(vf2d pos,Renderable&img,bool friendly)
|
||||
:Unit({
|
||||
@ -138,7 +139,20 @@ int Unit::GetMemorySize(){
|
||||
}
|
||||
|
||||
void Unit::Update(float fElapsedTime){
|
||||
|
||||
if(!target.expired()){
|
||||
auto ptrTarget=target.lock();
|
||||
if(!InRange(ptrTarget)){
|
||||
pos+=(ptrTarget->GetPos()-pos).norm()*GetMoveSpd()*24*fElapsedTime;
|
||||
} else {
|
||||
//TODO Attack here.
|
||||
}
|
||||
} else
|
||||
if(targetLoc!=CONSTANT::UNSELECTED){
|
||||
float dist=geom2d::line<float>(pos,targetLoc).length();
|
||||
if(dist>24){
|
||||
pos+=(targetLoc-pos).norm()*GetMoveSpd()*24*fElapsedTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Unit& operator <<(Unit&u,const int n){
|
||||
@ -177,3 +191,35 @@ void Unit::Deselect(){
|
||||
vf2d Unit::GetPos(){
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool Unit::IsDead(){
|
||||
return dead;
|
||||
}
|
||||
|
||||
vf2d Unit::GetUnitSize(){
|
||||
return img.Sprite()->Size();
|
||||
}
|
||||
|
||||
void Unit::SetTargetUnit(std::weak_ptr<Unit>target){
|
||||
this->target=target;
|
||||
this->targetLoc=CONSTANT::UNSELECTED;
|
||||
}
|
||||
|
||||
void Unit::SetTargetLocation(vf2d targetLoc){
|
||||
this->target.reset();
|
||||
this->targetLoc=targetLoc;
|
||||
}
|
||||
|
||||
bool Unit::InRange(std::shared_ptr<Unit>target){
|
||||
float dist=geom2d::line(GetPos(),target->GetPos()).length();
|
||||
return dist<24*(GetRange()+1);
|
||||
}
|
||||
|
||||
bool Unit::InRange(vf2d pos){
|
||||
float dist=geom2d::line(GetPos(),pos).length();
|
||||
return dist<24*(GetRange()+1);
|
||||
}
|
||||
|
||||
void Unit::SetPos(vf2d newPos){
|
||||
pos=newPos;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "olcPixelGameEngine.h"
|
||||
#include "Constant.h"
|
||||
|
||||
struct Marker{
|
||||
size_t index;
|
||||
@ -20,6 +21,13 @@ 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);
|
||||
@ -38,6 +46,11 @@ public:
|
||||
void Select();
|
||||
void Deselect();
|
||||
vf2d GetPos();
|
||||
bool IsDead();
|
||||
vf2d GetUnitSize();
|
||||
void SetTargetUnit(std::weak_ptr<Unit>target);
|
||||
void SetTargetLocation(vf2d targetLoc);
|
||||
void SetPos(vf2d newPos);
|
||||
protected:
|
||||
vf2d pos;
|
||||
bool friendly;
|
||||
@ -47,9 +60,15 @@ protected:
|
||||
Marker atkSpd;
|
||||
Marker moveSpd;
|
||||
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);
|
||||
};
|
||||
|
||||
struct BasicUnit:Unit{
|
||||
|
@ -29,7 +29,7 @@ bool VirusAttack::OnUserCreate(){
|
||||
|
||||
void VirusAttack::HandleDraggingSelection(){
|
||||
if(GetMouse(0).bPressed){
|
||||
for(std::unique_ptr<Unit>&u:units){
|
||||
for(auto&u:units){
|
||||
u->Deselect();
|
||||
}
|
||||
if(startingDragPos==CONSTANT::UNSELECTED){
|
||||
@ -40,10 +40,10 @@ void VirusAttack::HandleDraggingSelection(){
|
||||
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);}
|
||||
utils::geom2d::rect<float> selectionRegion(startingDragPos,endDragPos-startingDragPos);
|
||||
for(std::unique_ptr<Unit>&u:units){
|
||||
geom2d::rect<float> selectionRegion(startingDragPos,endDragPos-startingDragPos);
|
||||
for(auto&u:units){
|
||||
if(u->IsFriendly()){
|
||||
if(utils::geom2d::overlaps(selectionRegion,u->GetPos())){
|
||||
if(geom2d::overlaps(selectionRegion,u->GetPos())){
|
||||
u->Select();
|
||||
}
|
||||
}
|
||||
@ -61,11 +61,46 @@ void VirusAttack::DrawSelectionRectangle(){
|
||||
bool VirusAttack::OnUserUpdate(float fElapsedTime){
|
||||
HandleDraggingSelection();
|
||||
|
||||
for(std::unique_ptr<Unit>&u:units){
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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))){
|
||||
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);
|
||||
}
|
||||
}
|
||||
u->Update(fElapsedTime);
|
||||
}
|
||||
|
||||
for(std::unique_ptr<Unit>&u:units){
|
||||
for(auto&u:units){
|
||||
u->Draw(this);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
class VirusAttack : public olc::PixelGameEngine
|
||||
{
|
||||
private:
|
||||
std::vector<std::unique_ptr<Unit>>units;
|
||||
std::vector<std::shared_ptr<Unit>>units;
|
||||
|
||||
vf2d startingDragPos=CONSTANT::UNSELECTED;
|
||||
void HandleDraggingSelection();
|
||||
|
@ -1044,3 +1044,5 @@ namespace olc::utils::geom2d
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace utils;
|
Loading…
x
Reference in New Issue
Block a user