//function to remove cannon balls if they are out of screen or remain stationary for a long time void removeUselessBall(CannonBall ball, ArrayList ballList) { if (ball.getPosition().x < leftBoundary || ball.getPosition().x > rightBoundary || ball.getPosition().y < bottonBoundary) { //when out of scree, remove the ball from the ball list and destroy it ballList.Remove(ball); Destroy(ball.GetGameObject()); } else if (Mathf.Abs(ball.getVelocity().x) < 0.0001f) { //the ball's x-velocity is really small (caused by friction), remove the ball from the ball list and destroy it //note that it must been a long time for the ball staying on the ground to have such a small x-velocty ballList.Remove(ball); Destroy(ball.GetGameObject()); } }
//function to detect and handle collision bewtween cannon ball and collision lines (water, terrain and balloons) //taking one cannon ball and an array of points of the line (line with corners) as paramters, detect the collsion void handleCannonBallCollision(CannonBall ball, Vector3[] linePoints, ColliderType type) { GameObject ballObject = ball.GetGameObject(); //check that if any line segment of the line is collided with the cannon ball for (int i = 0; i < linePoints.Length - 1; i++) { //if the line which the ball is colliding with is terrain if (type == ColliderType.TERRAIN) { // if the cannon ball is collided with the line if (CollisionCalculation.isCircleCollidesLine(linePoints[i].x, linePoints[i].y, linePoints[i + 1].x, linePoints[i + 1].y, ballObject.transform.position.x, ballObject.transform.position.y, ball.getRadius())) { //if the ball is colliding with horizontal ground if (linePoints[i].y - linePoints[i + 1].y == 0) { //apply an inverse acceleration to the gravity to cancel out the gravity ball.updateVelocity(Time.deltaTime, new Vector2(0, -gravity)); //apply a friction to the ball when rolling on horizontal ground applyFrictionOfGround(ball); } else //when the ball is not colliding with the horizontal terrain, push it back by a small amount to avoid triggering continuous collision detection { //push the ball away from the terrain line in its normal vector direction by a small //amount to avoid penetration Vector2 unitNormal = CollisionCalculation.getNormal(linePoints[i].x, linePoints[i].y, linePoints[i + 1].x, linePoints[i + 1].y); ball.translatePosition(Time.deltaTime, unitNormal * 1); } //handle the collision on terrain bouncingAfterTerrainCollision(ball, linePoints[i].x, linePoints[i].y, linePoints[i + 1].x, linePoints[i + 1].y); } } else //if the line which the ball is colliding with is water { // if the cannon ball is collided with the line if (CollisionCalculation.isCircleCollidesLine(linePoints[i].x, linePoints[i].y, linePoints[i + 1].x, linePoints[i + 1].y, ballObject.transform.position.x, ballObject.transform.position.y, ball.getRadius())) { //handle the collision on water disappearAfterWaterCollision(ball, cannonBallsList); } } } }
//function for the disappearing solution of collison on water void disappearAfterWaterCollision(CannonBall ball, ArrayList ballList) { //when fall in water, remove the ball from the ball list and destroy it ballList.Remove(ball); Destroy(ball.GetGameObject()); }
//this function will handle the collision between cannon ball and any ballon body void handleBalloonCollision(CannonBall cb, ArrayList balloonList) { //vectors that store the position of points that construct the balloons Vector3[] bodyPositions; Vector3[] stringPositions; //get every ballon as line segment for (int k = 0; k < balloonsList.Count; k++) { bodyPositions = ((Balloon)balloonsList[k]).getBodyLinePositions(); stringPositions = ((Balloon)balloonsList[k]).getStringLinePositions(); //iterate through the Points to check if the cannon ball collided any line segment of the balloon string for (int i = 0; i < stringPositions.Length - 1; i++) { // if the cannon ball is collided with the line segment of a balloon string if (CollisionCalculation.isCircleCollidesLine(stringPositions[i].x, stringPositions[i].y, stringPositions[i + 1].x, stringPositions[i + 1].y, cb.GetGameObject().transform.position.x, cb.GetGameObject().transform.position.y, cb.getRadius())) { //handle the collision by moving the string to avoid intersecting with the cannon ball movingAfterCannonBallCollision(cb, ((Balloon)balloonsList[k]), stringPositions[i], stringPositions[i + 1]); } } //iterate through the Points to check if the cannon ball collided any line segment of the balloon body for (int i = 0; i < bodyPositions.Length - 1; i++) { // if the cannon ball is collided with the line segment of a balloon body if (CollisionCalculation.isCircleCollidesLine(bodyPositions[i].x, bodyPositions[i].y, bodyPositions[i + 1].x, bodyPositions[i + 1].y, cb.GetGameObject().transform.position.x, cb.GetGameObject().transform.position.y, cb.getRadius())) { //handle the collision by destroy the balloon which has been collided destroyAfterCannonBallCollision(((Balloon)balloonsList[k]), balloonList); break; //break since the balloon with current positions array is destroyed, so no further check has to be made } } } }