Unit Collisions

CorrectiveAction
sigonasr2 1 year ago
parent bf61fa77b4
commit 5c211ce9b3
  1. 48
      olcCodeJam2023Entry/Unit.cpp
  2. 19
      olcCodeJam2023Entry/Unit.h
  3. 47
      olcCodeJam2023Entry/VirusAttack.cpp
  4. 2
      olcCodeJam2023Entry/VirusAttack.h
  5. 2
      olcCodeJam2023Entry/olcUTIL_Geometry2D.h

@ -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…
Cancel
Save