protected override void OnMouseDown(MouseButtonArgs e)
        {
            if (CurrentMouseWorldPositionIsValid)
            {
                var translatedPos = (new Vector4(CurrentMouseWorldPosition, 1) * BoardTranslationMatrix).Xyz;
                Console.WriteLine(translatedPos);
                var pos = translatedPos.Round().Xy.ToVector2i();

                if (!Board.PositionInMap(pos))
                {
                    return;
                }

                //ScaleAnim.Start();
                var selector = BoardActor.GetComponent <SceneComponent>("MarbleSelector");

                if (MoveTween.Enabled || RemoveTween.Enabled || CreateTween.Enabled)
                {
                    return;
                }

                if (Board[pos]?.Color == MarbleColor.BombJoker)
                {
                    return;
                }

                var marble = Board[pos];
                Log.Verbose("Clicked: {position}. Marble: {marble}", pos, marble);
                if (marble != null)
                {
                    SelectedMarble = marble;
                    selector.RelativeTranslation = new Vector3(pos.X, pos.Y, selector.RelativeTranslation.Z);
                    selector.Visible             = true;
                    AudioManager.Default.PlayAsync("Sounds/marble-select.wav");
                }
                else
                {
                    if (SelectedMarble != null)
                    {
                        var path = Board.FindPath(SelectedMarble, pos);
                        if (path != null && path.Count > 0)
                        {
                            CurrentPath = path;
                            var moveStepDuration = TimeSpan.FromSeconds(0.1);
                            //var moveStepDuration = TimeSpan.FromSeconds(2);
                            MoveTween.Duration = moveStepDuration.Multiply(path.Count);
                            MoveTween.Start();
                            AudioManager.Default.PlayAsync("Sounds/marble-moving.wav");
                            selector.Visible = false;
                        }
                    }
                }
            }
        }
 private void OnMatch()
 {
     RemoveTween.Start();
     if (!Board.MatchHasBomb)
     {
         AudioManager.Default.PlayAsync("Sounds/marble-removing.wav");
     }
     else
     {
         AudioManager.Default.PlayAsync("Sounds/marble-explode.wav");
     }
 }
 private void OnNewMarbles()
 {
     CreateTween.Start();
     AudioManager.Default.PlayAsync("Sounds/marble-adding.wav");
 }
        protected override void SetupScene()
        {
            Board = new MarbleBoard
            {
                OnMatch      = OnMatch,
                OnNewMarbles = OnNewMarbles,
            };

            //RenderContext.WorldPositionMatrix = Matrix4.CreateScale(1, -1, 1);
            //RenderContext.PrimaryRenderPipeline = RenderContext.GetPipeline<ForwardRenderPipeline>();
            DefaultKeyBindings = false;

            SceneContext.AddActor(BoardActor = new Actor(BoardComponent = new SceneComponent()
            {
                //RelativeRotation = new Vector3(0, 0, 0.02f).ToQuaternion(),
                RelativeTranslation = new Vector3(0, 0, 0.05f),
            }));

            BoardComponent.AddComponent(NextMarbleComponent = new SceneComponent()
            {
                RelativeTranslation = new Vector3(10, -3, 0),
                RelativeScale       = new Vector3(0.5f),
            });

            BoardComponent.AddComponent(NextMarbleBoardComponent = new SceneComponent()
            {
                RelativeTranslation = new Vector3(0, 0, -0.2f),
                // RelativeScale = new Vector3(0.5f),
                // TranslationMatrix = Matrix4.CreateScale(2),
                // IsAbsoluteRotation = true,
                // IsAbsoluteScale = true,
                // IsAbsoluteTranslation = true,
            });

            var camSize = new Vector2(9 * RenderContext.ScreenAspectRatio, 9);

            RenderContext.Camera = new OrthographicCamera(new Vector3(4.5f + ((camSize.X - camSize.Y) / 2f) - 0.5f, -4.5f + 0.5f, 25))
            {
                Size      = camSize,
                NearPlane = 1f,
                FarPlane  = 100.0f,
                Facing    = (float)Math.PI / 2,
                Pitch     = -((float)(Math.PI / 2) - 0.00001f),
            };

            SceneContext.AddActor(new Actor(new CubeComponent()
            {
                Name     = "Ground",
                Material = new Material
                {
                    Color     = new Vector4(0.4f, 0.6f, 0.6f, 1),
                    Shininess = 1.0f,
                },
                RelativeScale       = new Vector3(50, 50, 1),
                RelativeTranslation = new Vector3(0f, 0f, -0.5f),
            }));

            BoardComponent.AddComponent(new CubeComponent()
            {
                Name     = "Board",
                Material = new Material
                {
                    Color     = new Vector4(0.4f, 0.6f, 0.6f, 1) * 1.1f,
                    Shininess = 1.0f,
                },
                RelativeScale       = new Vector3(Board.Width, Board.Height, 1),
                RelativeTranslation = new Vector3((Board.Width / 2f) - 0.5f, (Board.Height / 2f) - 0.5f, -0.5f),
                TranslationMatrix   = BoardTranslationMatrix,
            });

            BoardComponent.AddComponent(new GridPlaneComponent(9, false)
            {
                Name = "Grid",
                RelativeTranslation = new Vector3(-0.5f, -0.5f + 9, 0.01f),
                TranslationMatrix   = BoardTranslationMatrix,
            });
            SceneContext.AddActor(new Actor(new CrossLineComponent(10, true)
            {
                Name = "CenterCross",
                RelativeTranslation = new Vector3(0f, 0f, 0.02f),
                RelativeScale       = new Vector3(1.0f),
            }));

            var alchemyCircleOptions = new Generators.AlchemyCircle.AlchemyCircleOptions
            {
                Seed      = 1919654508,
                Size      = 256,
                Thickness = 4,
            };
            var decalMaterial = new Material()
            {
                DiffuseTexture   = Texture.CreateFromFile(AssetManager.GetAssetsPath("Textures/AlchemyCircle/.png", alchemyCircleOptions)),
                Color            = new Vector4(57f / 255f, 1, 20f / 255f, 1),
                Ambient          = 0.3f,
                Shininess        = 32.0f,
                SpecularStrength = 0.5f,
                CastShadow       = false,
                PipelineType     = PipelineType.Forward,
                UseTransparency  = true,
            };

            BoardComponent.AddComponent(new QuadComponent()
            {
                Material            = decalMaterial,
                Name                = "GroundCursor",
                RelativeTranslation = new Vector3(0, 1, 0.051f),
                RelativeScale       = new Vector3(2f, 2f, 0.1f),
                DrawPriority        = 101,
            });

            BoardComponent.AddComponent(new QuadComponent()
            {
                Name              = "MarbleSelector",
                Material          = decalMaterial,
                TranslationMatrix = BoardTranslationMatrix,
                //Material = material,
                RelativeTranslation = new Vector3(0, 1, 0.05f),
                RelativeScale       = new Vector3(2f, 2f, 0.1f),
                Visible             = false,
                DrawPriority        = 100,
            });

            SceneContext.AddActor(new Actor(new PointLightComponent()
            {
                RelativeTranslation = new Vector3(0, 2, 3.5f),
                Name = "MovingLight",
                //Enabled = false,
            }));

            SceneContext.AddActor(new Actor(new PointLightComponent()
            {
                RelativeTranslation = new Vector3(2f, 0.5f, 4.25f),
                Name = "StaticLight",
            }));

            var flowContainer = new UIFlowContainer()
            {
                Name = "UI",
                DefaultChildSizes = new Vector2(0, 50),
                ExtraChildMargin  = new UIAnchors(10, 10, 10, 0),
                Location          = new Vector2(1000, 0),
                Size = new Vector2(200, 0),
            };

            SceneContext.AddActor(new Actor(flowContainer));

            // flowContainer.AddComponent(new UIMarbles()
            // {
            //     Name = "UI",
            // });

            flowContainer.AddComponent(new UILabelComponent()
            {
                Name  = "LastScore",
                Color = Color.White,
            });
            flowContainer.AddComponent(new UILabelComponent()
            {
                Name  = "TotalScore",
                Color = Color.White,
            });

            SceneContext.AddActor(new Actor(new StatsComponent()
            {
                Name = "Stats",
            }));

            UIButton bt;

            flowContainer.AddComponent(bt = new UIButton()
            {
                Name           = "Exit",
                Text           = "Exit",
                Color          = Color.White,
                BackColor      = new Color(new Rgba32(0, 0, 0, 0.5f)),
                BackColorHover = new Color(new Rgba32(0, 0, 0, 0.8f)),
                BorderColor    = new Color(new Rgba32(0, 0, 0, 0.8f)),
                // Location = new Vector2(620, 200),
                // Size = new Vector2(100, 100),
            });
            bt.Click += (e) =>
            {
                Stop();
            };

            SelectorTween = new Tween1
            {
                Duration  = TimeSpan.FromSeconds(10),
                ScaleFunc = ScaleFuncs.Linear(MathF.PI * 2),
                Repeat    = true,
            };
            SelectorTween.Start();

            RemoveTween = new Tween1
            {
                Duration  = TimeSpan.FromSeconds(0.75),
                ScaleFunc = ScaleFuncs.LinearReverse(MarbleScale),
            };
            RemoveTween.TweenComplete += OnAnimFinshed_MarbleRemoved;

            CreateTween = new Tween1
            {
                Duration  = TimeSpan.FromSeconds(0.75),
                ScaleFunc = ScaleFuncs.Linear(MarbleScale),
            };
            CreateTween.TweenComplete += OnAnimationFinished_MarbleCreated;

            MoveTween = new Tween1()
            {
                ScaleFunc = ScaleFuncs.Power10EaseInOut,
            };
            MoveTween.TweenComplete += OnAnimFinished_MarbleMoved;
        }