mirror of
https://github.com/sigonasr2/hamster.git
synced 2025-04-17 22:29:40 -05:00
Add basic collision resolution between Hamsters.
This commit is contained in:
parent
f234f1a4fe
commit
506b5f99ae
@ -60,9 +60,21 @@ void Hamster::UpdateHamsters(const float fElapsedTime){
|
||||
for(Hamster&h:HAMSTER_LIST){
|
||||
h.animations.UpdateState(h.internalAnimState,fElapsedTime);
|
||||
h.frictionEnabled=true;
|
||||
h.bumpTimer-=fElapsedTime;
|
||||
h.HandleCollision();
|
||||
switch(h.state){
|
||||
case NORMAL:{
|
||||
//TODO: NPC controls.
|
||||
if(h.IsPlayerControlled){
|
||||
h.HandlePlayerControls();
|
||||
}
|
||||
}break;
|
||||
case BUMPED:{
|
||||
if(h.bumpTimer<=0.f){
|
||||
h.state=NORMAL;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
h.TurnTowardsTargetDirection();
|
||||
h.MoveHamster();
|
||||
}
|
||||
@ -135,3 +147,37 @@ void Hamster::MoveHamster(){
|
||||
}
|
||||
#pragma endregion
|
||||
}
|
||||
|
||||
void Hamster::HandleCollision(){
|
||||
for(Hamster&h:HAMSTER_LIST){
|
||||
if(this==&h)continue;
|
||||
if(geom2d::overlaps(geom2d::circle<float>(GetPos(),GetRadius()),geom2d::circle<float>(h.GetPos(),h.GetRadius()))){
|
||||
if(geom2d::line<float>(GetPos(),h.GetPos()).length()==0.f){ //Push these two in random directions, they are on top of each other!
|
||||
float randDir{util::random(2*geom2d::pi)};
|
||||
vf2d collisionResolve1{GetPos()+vf2d{GetRadius(),randDir}.cart()};
|
||||
vf2d collisionResolve2{h.GetPos()+vf2d{h.GetRadius(),float(randDir+geom2d::pi)}.cart()};
|
||||
pos=collisionResolve1;
|
||||
h.pos=collisionResolve2;
|
||||
vel=vf2d{100.f,randDir}.cart();
|
||||
h.vel=vf2d{100.f,float(randDir+geom2d::pi)}.cart();
|
||||
}else{
|
||||
geom2d::line<float>collisionLine{geom2d::line<float>(GetPos(),h.GetPos())};
|
||||
float distance{collisionLine.length()};
|
||||
float totalRadii{GetRadius()+h.GetRadius()};
|
||||
float bumpDistance{totalRadii-distance};
|
||||
vf2d collisionResolve1{GetPos()+vf2d{bumpDistance/2.f,float(collisionLine.vector().polar().y+geom2d::pi)}.cart()};
|
||||
vf2d collisionResolve2{h.GetPos()+vf2d{bumpDistance/2.f,collisionLine.vector().polar().y}.cart()};
|
||||
pos=collisionResolve1;
|
||||
h.pos=collisionResolve2;
|
||||
vel=vf2d{100.f,float(collisionLine.vector().polar().y+geom2d::pi)}.cart();
|
||||
h.vel=vf2d{100.f,collisionLine.vector().polar().y}.cart();
|
||||
}
|
||||
state=h.state=BUMPED;
|
||||
bumpTimer=h.bumpTimer=0.12f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const float Hamster::GetRadius()const{
|
||||
return collisionRadius;
|
||||
}
|
@ -47,6 +47,11 @@ class Hamster{
|
||||
NPC=false,
|
||||
};
|
||||
|
||||
enum PlayerState{
|
||||
NORMAL,
|
||||
BUMPED,
|
||||
};
|
||||
|
||||
static std::vector<Hamster>HAMSTER_LIST;
|
||||
|
||||
static const uint8_t MAX_HAMSTER_COUNT;
|
||||
@ -64,11 +69,14 @@ class Hamster{
|
||||
float timeToMaxSpd{0.5f};
|
||||
float friction{400.f};
|
||||
bool frictionEnabled{false};
|
||||
float collisionRadius{12.f};
|
||||
float bumpTimer{};
|
||||
std::string img;
|
||||
Animate2D::Animation<HamsterGame::AnimationState>animations;
|
||||
Animate2D::AnimationState internalAnimState;
|
||||
PlayerControlled IsPlayerControlled;
|
||||
static std::optional<Hamster*>playerHamster;
|
||||
PlayerState state{NORMAL};
|
||||
public:
|
||||
Hamster(const vf2d spawnPos,const std::string_view img,const PlayerControlled IsPlayerControlled=NPC);
|
||||
static const Hamster&GetPlayer();
|
||||
@ -80,4 +88,6 @@ public:
|
||||
void HandlePlayerControls();
|
||||
void TurnTowardsTargetDirection();
|
||||
void MoveHamster();
|
||||
void HandleCollision();
|
||||
const float GetRadius()const;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user