private float MoveShape(ShapePipePair pair, float dt)
    {
        GameShape shape = pair.Shape;
        GamePipe  pipe  = pair.AttachedPipe;

        float   distanceTravelled   = dt * shape.Speed;
        float   percentualTravelled = shape.PercentualTraveled + distanceTravelled;
        Vector3 newPosition         = pipe.GetPositionFromPercentual(percentualTravelled);

        shape.UpdatePosition(percentualTravelled, newPosition);
        return(percentualTravelled);
    }
    public GameShape CreateShape(GameShapeType newShapeType, GameSpawner spawner, float speed, float spawnSpeed)
    {
        GameShape shape = new GameShape(newShapeType, spawner, speed, spawnSpeed);

        ShapePipePair newPair = new ShapePipePair
        {
            Shape = shape
        };

        Pairs.Add(newPair);

        return(shape);
    }
    private int GetPairIndex(GameShape shape)
    {
        for (int index = 0; index < Pairs.Count; index++)
        {
            ShapePipePair pair = Pairs[index] as ShapePipePair;

            if (pair.Shape == shape)
            {
                return(index);
            }
        }
        return(-1);
    }
    public void MoveAllShapes(float dt)
    {
        for (int i = Pairs.Count - 1; i >= 0; i--)
        {
            ShapePipePair pair = Pairs[i] as ShapePipePair;

            GameShape shape = pair.Shape;

            if (shape.CanMove)
            {
                float percentualTravelled = MoveShape(pair, dt);
                if (percentualTravelled >= 1)
                {
                    UpdateState(shape, GameShapeState.FINISHED);
                }
            }
        }
    }
    public bool IsCorrect(GameShape shape)
    {
        ShapePipePair pair = GetShapePipePair(shape);

        return(pair.Shape.Type == pair.AttachedPipe.CurrentEndType);
    }
    public void AttachPipe(GameShape shape, GamePipe pipe)
    {
        ShapePipePair pair = GetShapePipePair(shape);

        pair.AttachedPipe = pipe;
    }