void PlayableEmotion::notifyCollision(GameObject &other) { if (currentState == LOSING || currentState == WINNING) return; else if (other.is("KillingRectangle")) { currentState = PlayableState::LOSING; spriteLosing.setFrame(0); } else if (other.is("VictoryRectangle")) { currentState = PlayableState::WINNING; spriteWinning.setFrame(0); } else if (isSmashing && other.is("DestroyableRectangle")) { ((DestroyableRectangle &) other).smashThis(); } else if (other.is("CollidableAABBGameObject")) { Rect collidingRect = ((AxisAlignedBoundingBox *) other.getCollisionVolume())->axisAlignedRectangle; //among internal circles, find the one that is closes to the axis aligned rectangle int min_k = -1; double distanceBetweenCircleAndRectangle = numeric_limits<float>::infinity(); for (int k = 0; k < 3; k++) { const Vec2 ¤tCenter = auxCollisionVolume[k].getCenter(); double dd = Vec2::distanceBetweenPoints(currentCenter, collidingRect.getClosestPointTo(currentCenter)); if (dd < distanceBetweenCircleAndRectangle) { min_k = k; distanceBetweenCircleAndRectangle = dd; } } const Vec2 closestInnerCircle = auxCollisionVolume[min_k].getCenter(); const Vec2 closestPointOnRectangle = collidingRect.getClosestPointTo(closestInnerCircle); float grab_angle = (closestPointOnRectangle - centerPos).ang_rad(); if(grab_angle >= -M_PI_2 && grab_angle <= M_PI_2){ canGrabLeft = true; canGrabRight = false; grabableToTheLeft = &other; grabableToTheRight = nullptr; }else{ canGrabLeft = false; canGrabRight = true; grabableToTheLeft = nullptr; grabableToTheRight = &other; } double overlap = auxCollisionVolume[min_k].getRadius() - distanceBetweenCircleAndRectangle; static double TOLERANCE = M_PI / 20.0; if (overlap >= 0.0) { Vec2 directionToEscape = (closestInnerCircle - closestPointOnRectangle).getNormalizedVector(); updatePos(centerPos + overlap * directionToEscape); double angleToEscape = directionToEscape.ang_rad(); if (abs(angleToEscape) < TOLERANCE || abs(angleToEscape - M_PI) < TOLERANCE) { if (iterationsSinceLastVerticalSupportNodification > 10) { TyperInput::getInstance().addEventOnFront( TyperInput::TypingEvent::VERTICAL_SUPPORT_FOUND); iterationsSinceLastVerticalSupportNodification = 0; } // speed.x = 0; } else if (abs(angleToEscape - M_PI_2) < TOLERANCE || abs(angleToEscape + M_PI_2) < TOLERANCE) { if (iterationsSinceLastHorizontalSupportNodification > 10) { TyperInput::getInstance().addEventOnFront( TyperInput::TypingEvent::HORIZONTAL_SUPPORT_FOUND); iterationsSinceLastHorizontalSupportNodification = 0; } speed.y = 0; } else { } } } }