Add basic collision resolution between Hamsters.

main
sigonasr2 3 months ago
parent f234f1a4fe
commit 506b5f99ae
  1. 50
      src/Hamster.cpp
  2. 10
      src/Hamster.h

@ -60,8 +60,20 @@ void Hamster::UpdateHamsters(const float fElapsedTime){
for(Hamster&h:HAMSTER_LIST){ for(Hamster&h:HAMSTER_LIST){
h.animations.UpdateState(h.internalAnimState,fElapsedTime); h.animations.UpdateState(h.internalAnimState,fElapsedTime);
h.frictionEnabled=true; h.frictionEnabled=true;
if(h.IsPlayerControlled){ h.bumpTimer-=fElapsedTime;
h.HandlePlayerControls(); 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.TurnTowardsTargetDirection();
h.MoveHamster(); h.MoveHamster();
@ -135,3 +147,37 @@ void Hamster::MoveHamster(){
} }
#pragma endregion #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, NPC=false,
}; };
enum PlayerState{
NORMAL,
BUMPED,
};
static std::vector<Hamster>HAMSTER_LIST; static std::vector<Hamster>HAMSTER_LIST;
static const uint8_t MAX_HAMSTER_COUNT; static const uint8_t MAX_HAMSTER_COUNT;
@ -64,11 +69,14 @@ class Hamster{
float timeToMaxSpd{0.5f}; float timeToMaxSpd{0.5f};
float friction{400.f}; float friction{400.f};
bool frictionEnabled{false}; bool frictionEnabled{false};
float collisionRadius{12.f};
float bumpTimer{};
std::string img; std::string img;
Animate2D::Animation<HamsterGame::AnimationState>animations; Animate2D::Animation<HamsterGame::AnimationState>animations;
Animate2D::AnimationState internalAnimState; Animate2D::AnimationState internalAnimState;
PlayerControlled IsPlayerControlled; PlayerControlled IsPlayerControlled;
static std::optional<Hamster*>playerHamster; static std::optional<Hamster*>playerHamster;
PlayerState state{NORMAL};
public: public:
Hamster(const vf2d spawnPos,const std::string_view img,const PlayerControlled IsPlayerControlled=NPC); Hamster(const vf2d spawnPos,const std::string_view img,const PlayerControlled IsPlayerControlled=NPC);
static const Hamster&GetPlayer(); static const Hamster&GetPlayer();
@ -80,4 +88,6 @@ public:
void HandlePlayerControls(); void HandlePlayerControls();
void TurnTowardsTargetDirection(); void TurnTowardsTargetDirection();
void MoveHamster(); void MoveHamster();
void HandleCollision();
const float GetRadius()const;
}; };
Loading…
Cancel
Save