//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
                }
            }
        }
    }
    //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);
                }
            }
        }
    }