diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index e06f71cb64..93e26927e9 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -49,6 +49,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, }, tickContainer = new Container { @@ -104,6 +105,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { } + protected override void Update() + { + base.Update(); + + bodyPiece.Y = head.Height; + bodyPiece.Height = DrawHeight - head.Height; + } + public bool OnPressed(ManiaAction action) { // Make sure the action happened within the body of the hold note diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index c201ab7bd0..6d4f921020 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables : base(hitObject, action) { RelativeSizeAxes = Axes.X; - Height = 100; + AutoSizeAxes = Axes.Y; Add(headPiece = new NotePiece { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs index 04e8df4ae2..ac7054abe8 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs @@ -1,7 +1,10 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using osu.Framework.Caching; using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -14,22 +17,61 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces /// internal class BodyPiece : Container, IHasAccentColour { - private readonly Box box; + private readonly Container subtractionLayer; + + private readonly Drawable background; + private readonly BufferedContainer foreground; + private readonly BufferedContainer subtractionContainer; public BodyPiece() { - RelativeSizeAxes = Axes.Both; + Blending = BlendingMode.Additive; Children = new[] { - box = new Box + background = new Box { RelativeSizeAxes = Axes.Both }, + foreground = new BufferedContainer { RelativeSizeAxes = Axes.Both, - Alpha = 0.3f + CacheDrawnFrameBuffer = true, + Children = new Drawable[] + { + new Box { RelativeSizeAxes = Axes.Both }, + subtractionContainer = new BufferedContainer + { + RelativeSizeAxes = Axes.Both, + // This is needed because we're blending with another object + BackgroundColour = Color4.White.Opacity(0), + CacheDrawnFrameBuffer = true, + // The 'hole' is achieved by subtracting the result of this container with the parent + Blending = new BlendingModeParameters { AlphaEquation = BlendingEquation.ReverseSubtract }, + Child = subtractionLayer = new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + // Height computed in Update + Width = 1, + Masking = true, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } + } + } + } } }; } + protected override void LoadComplete() + { + base.LoadComplete(); + + updateAccentColour(); + } + private Color4 accentColour; public Color4 AccentColour { @@ -40,8 +82,51 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces return; accentColour = value; - box.Colour = accentColour; + updateAccentColour(); } } + + private Cached subtractionCache = new Cached(); + + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) + { + if ((invalidation & Invalidation.DrawSize) > 0) + subtractionCache.Invalidate(); + + return base.Invalidate(invalidation, source, shallPropagate); + } + + protected override void Update() + { + base.Update(); + + if (!subtractionCache.IsValid) + { + subtractionLayer.Width = 5; + subtractionLayer.Height = Math.Max(0, DrawHeight - DrawWidth); + subtractionLayer.EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.White, + Type = EdgeEffectType.Glow, + Radius = DrawWidth + }; + + foreground.ForceRedraw(); + subtractionContainer.ForceRedraw(); + + subtractionCache.Validate(); + } + } + + private void updateAccentColour() + { + if (!IsLoaded) + return; + + foreground.Colour = AccentColour.Opacity(0.4f); + background.Colour = AccentColour.Opacity(0.2f); + + subtractionCache.Invalidate(); + } } }