// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { public class MainCirclePiece : CompositeDrawable { private readonly CirclePiece circle; private readonly RingPiece ring; private readonly FlashPiece flash; private readonly ExplodePiece explode; private readonly NumberPiece number; private readonly GlowPiece glow; public MainCirclePiece() { Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Anchor = Anchor.Centre; Origin = Anchor.Centre; InternalChildren = new Drawable[] { glow = new GlowPiece(), circle = new CirclePiece(), number = new NumberPiece(), ring = new RingPiece(), flash = new FlashPiece(), explode = new ExplodePiece(), }; } private readonly IBindable accentColour = new Bindable(); private readonly IBindable indexInCurrentCombo = new Bindable(); [Resolved] private DrawableHitObject drawableObject { get; set; } = null!; [BackgroundDependencyLoader] private void load() { var drawableOsuObject = (DrawableOsuHitObject)drawableObject; accentColour.BindTo(drawableObject.AccentColour); indexInCurrentCombo.BindTo(drawableOsuObject.IndexInCurrentComboBindable); } protected override void LoadComplete() { base.LoadComplete(); accentColour.BindValueChanged(colour => { explode.Colour = colour.NewValue; glow.Colour = colour.NewValue; circle.Colour = colour.NewValue; }, true); indexInCurrentCombo.BindValueChanged(index => number.Text = (index.NewValue + 1).ToString(), true); drawableObject.ApplyCustomUpdateState += updateStateTransforms; updateStateTransforms(drawableObject, drawableObject.State.Value); } private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) { using (BeginAbsoluteSequence(drawableObject.StateUpdateTime)) glow.FadeOut(400); using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime)) { switch (state) { case ArmedState.Hit: const double flash_in = 40; const double flash_out = 100; flash.FadeTo(0.8f, flash_in) .Then() .FadeOut(flash_out); explode.FadeIn(flash_in); this.ScaleTo(1.5f, 400, Easing.OutQuad); using (BeginDelayedSequence(flash_in)) { // after the flash, we can hide some elements that were behind it ring.FadeOut(); circle.FadeOut(); number.FadeOut(); this.FadeOut(800); } break; } } } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); if (drawableObject.IsNotNull()) drawableObject.ApplyCustomUpdateState -= updateStateTransforms; } } }