public static void TestTween()
    {
        Roga2dNode node = new Roga2dNode();

        Roga2dAlphaInterval interval1 = new Roga2dAlphaInterval(node, 0.1f, 1.0f, 3, true);
        Roga2dRotationIntervalOption option = new Roga2dRotationIntervalOption();
        Roga2dRotationInterval interval2 = new Roga2dRotationInterval(node, 0.0f, 180.0f, 5, true,  option);

        List<Roga2dBaseInterval> intervals = new List<Roga2dBaseInterval>();
        intervals.Add(interval1);
        intervals.Add(interval2);
        Roga2dParallel parallel = new Roga2dParallel(intervals);

        parallel.Start();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Match(node.LocalRotation, 0.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 0.4f);
        Tester.Match(node.LocalRotation, 36.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 0.7f);
        Tester.Match(node.LocalRotation, 72.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Match(node.LocalRotation, 108.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Match(node.LocalRotation, 144.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Match(node.LocalRotation, 180.0f);
        Tester.Ok(parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Match(node.LocalRotation, 180.0f);
        Tester.Ok(parallel.IsDone());

        parallel.Reset();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Match(node.LocalRotation, 0.0f);
        Tester.Ok(!parallel.IsDone());

        node.Destroy();
    }
        public void OnStepMoved(StepData step, float duration)
        {
            Vector2 piecePixelPos = this.playerPiece.LocalPixelPosition;
            Vector2 piecePos = Roga2dUtils.pixelToLocal(new Vector2(piecePixelPos.x, piecePixelPos.y));
            Vector2 movePos = Roga2dUtils.pixelToLocal(new Vector2(step.PosX + 16, step.PosY + 16));
            Vector2 cameraPos = this.camera.LocalPosition;
            Vector2 cameraFocusPos = Roga2dUtils.pixelToLocal(new Vector2(piecePixelPos.x - 16, piecePixelPos.y - 16));
            Vector2 cameraMovePos = Roga2dUtils.pixelToLocal(new Vector2(step.PosX , step.PosY));

            Roga2dFunc func = new Roga2dFunc(this.onPieceMoved);

            // Move camera and piece at the same time
            Roga2dParallel parallel = new Roga2dParallel(new List<Roga2dBaseInterval> {
                new Roga2dPositionInterval(this.playerPiece, piecePos, movePos, Roga2dUtils.TimeToFrame(duration), true, null),
                new Roga2dPositionInterval(this.camera, cameraFocusPos, cameraMovePos, Roga2dUtils.TimeToFrame(duration), true, null)
            });

            // At first move back to the piece position
            float distance = Vector2.Distance(cameraPos, piecePos);
            float cameraFocusDuration = distance * 0.2f;
            Roga2dSequence sequence = new Roga2dSequence(new List<Roga2dBaseInterval> {
                new Roga2dPositionInterval(this.camera, cameraPos, cameraFocusPos, Roga2dUtils.TimeToFrame(cameraFocusDuration), true, null),
                parallel,
                func
            });

            Roga2dIntervalPlayer.GetInstance().Play(sequence);
        }