diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs index fb14bdb3bf..a0f1162ecb 100644 --- a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; @@ -13,6 +14,8 @@ using osu.Game.Rulesets.Mania.Timing; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Timing; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mania.Judgements; +using osu.Game.Rulesets.Objects.Drawables; namespace osu.Desktop.Tests.Visual { @@ -29,6 +32,8 @@ namespace osu.Desktop.Tests.Visual public TestCaseManiaPlayfield() { + var rng = new Random(1337); + AddStep("1 column", () => createPlayfield(1, SpecialColumnPosition.Normal)); AddStep("4 columns", () => createPlayfield(4, SpecialColumnPosition.Normal)); AddStep("Left special style", () => createPlayfield(4, SpecialColumnPosition.Left)); @@ -43,6 +48,21 @@ namespace osu.Desktop.Tests.Visual AddStep("Notes with input (reversed)", () => createPlayfieldWithNotes(false, true)); AddStep("Notes with gravity", () => createPlayfieldWithNotes(true)); AddStep("Notes with gravity (reversed)", () => createPlayfieldWithNotes(true, true)); + + AddStep("Hit explosion", () => + { + var playfield = createPlayfield(4, SpecialColumnPosition.Normal); + + int col = rng.Next(0, 4); + + var note = new DrawableNote(new Note { Column = col }, ManiaAction.Key1) + { + Judgement = new ManiaJudgement { Result = HitResult.Hit }, + AccentColour = playfield.Columns.ElementAt(col).AccentColour + }; + + playfield.OnJudgement(note); + }); } [BackgroundDependencyLoader] @@ -56,7 +76,7 @@ namespace osu.Desktop.Tests.Visual TimingPoint = { BeatLength = 1000 } }, gravity ? ScrollingAlgorithm.Gravity : ScrollingAlgorithm.Basic); - private void createPlayfield(int cols, SpecialColumnPosition specialPos, bool inverted = false) + private ManiaPlayfield createPlayfield(int cols, SpecialColumnPosition specialPos, bool inverted = false) { Clear(); @@ -72,6 +92,8 @@ namespace osu.Desktop.Tests.Visual }); playfield.Inverted.Value = inverted; + + return playfield; } private void createPlayfieldWithNotes(bool gravity, bool inverted = false) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 7f4ec8d8d2..74f775b49f 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -59,9 +59,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } }; - - // Set the default glow - AccentColour = Color4.White; } public override Color4 AccentColour diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index a58ae9b31c..11d3f970c3 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -105,12 +105,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void UpdateState(ArmedState state) { - switch (State) - { - case ArmedState.Hit: - Colour = Color4.Green; - break; - } } public virtual bool OnPressed(ManiaAction action) diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index c3a29b39a8..fc1331551e 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -37,6 +37,17 @@ namespace osu.Game.Rulesets.Mania.Objects } } + public override int Column + { + get { return base.Column; } + set + { + base.Column = value; + Head.Column = value; + Tail.Column = value; + } + } + /// /// The head note of the hold. /// @@ -80,7 +91,8 @@ namespace osu.Game.Rulesets.Mania.Objects { ret.Add(new HoldNoteTick { - StartTime = t + StartTime = t, + Column = Column }); } diff --git a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs index 93aaa94f45..7beb21f9e3 100644 --- a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs @@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.Mania.Objects { public abstract class ManiaHitObject : HitObject, IHasColumn { - public int Column { get; set; } + public virtual int Column { get; set; } } } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index d5bc7cc659..213144c84d 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -36,6 +36,9 @@ namespace osu.Game.Rulesets.Mania.UI private readonly Container hitTargetBar; private readonly Container keyIcon; + internal readonly Container TopLevelContainer; + private readonly Container explosionContainer; + protected override Container Content => content; private readonly Container content; @@ -98,6 +101,11 @@ namespace osu.Game.Rulesets.Mania.UI { Pressed = onPressed, Released = onReleased + }, + explosionContainer = new Container + { + Name = "Hit explosions", + RelativeSizeAxes = Axes.Both } } }, @@ -136,8 +144,11 @@ namespace osu.Game.Rulesets.Mania.UI } } } - } + }, + TopLevelContainer = new Container { RelativeSizeAxes = Axes.Both } }; + + TopLevelContainer.Add(explosionContainer.CreateProxy()); } public override Axes RelativeSizeAxes => Axes.Y; @@ -194,6 +205,14 @@ namespace osu.Game.Rulesets.Mania.UI HitObjects.Add(hitObject); } + public override void OnJudgement(DrawableHitObject judgedObject) + { + if (judgedObject.Judgement.Result != HitResult.Hit) + return; + + explosionContainer.Add(new HitExplosion(judgedObject)); + } + private bool onPressed(ManiaAction action) { if (action == Action) diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs new file mode 100644 index 0000000000..962082c368 --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -0,0 +1,66 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Mania.Judgements; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.Objects.Drawables; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Mania.UI +{ + internal class HitExplosion : CompositeDrawable + { + private readonly Box inner; + + public HitExplosion(DrawableHitObject judgedObject) + { + bool isTick = judgedObject is DrawableHoldNoteTick; + + Anchor = Anchor.TopCentre; + Origin = Anchor.Centre; + + RelativeSizeAxes = Axes.Both; + Size = new Vector2(isTick ? 0.5f : 1); + FillMode = FillMode.Fit; + + Blending = BlendingMode.Additive; + + Color4 accent = isTick ? Color4.White : judgedObject.AccentColour; + + InternalChild = new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Masking = true, + BorderThickness = 1, + BorderColour = accent, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = accent, + Radius = 10, + Hollow = true + }, + Child = inner = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = accent, + Alpha = 1, + AlwaysPresent = true, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500); + inner.FadeOut(250); + } + } +} diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index ce91fda023..5697da537e 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -65,21 +65,21 @@ namespace osu.Game.Rulesets.Mania.UI Inverted.Value = true; + Container topLevelContainer; InternalChildren = new Drawable[] { new Container { + Name = "Playfield elements", Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Both, - Masking = true, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, Children = new Drawable[] { new Container { - Name = "Masked elements", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, + Name = "Columns mask", RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, Masking = true, @@ -87,6 +87,7 @@ namespace osu.Game.Rulesets.Mania.UI { new Box { + Name = "Background", RelativeSizeAxes = Axes.Both, Colour = Color4.Black }, @@ -98,27 +99,28 @@ namespace osu.Game.Rulesets.Mania.UI Direction = FillDirection.Horizontal, Padding = new MarginPadding { Left = 1, Right = 1 }, Spacing = new Vector2(1, 0) - } + }, } }, new Container { + Name = "Barlines mask", Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = HIT_TARGET_POSITION }, - Children = new[] + RelativeSizeAxes = Axes.Y, + Width = 1366, // Bar lines should only be masked on the vertical axis + BypassAutoSizeAxes = Axes.Both, + Masking = true, + Child = content = new Container { - content = new Container - { - Name = "Bar lines", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Y, - // Width is set in the Update method - } + Name = "Bar lines", + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Y, + Padding = new MarginPadding { Top = HIT_TARGET_POSITION } } - } + }, + topLevelContainer = new Container { RelativeSizeAxes = Axes.Both } } } }; @@ -132,6 +134,8 @@ namespace osu.Game.Rulesets.Mania.UI c.IsSpecial = isSpecialColumn(i); c.Action = c.IsSpecial ? ManiaAction.Special : currentAction++; + topLevelContainer.Add(c.TopLevelContainer.CreateProxy()); + columns.Add(c); AddNested(c); } @@ -177,6 +181,8 @@ namespace osu.Game.Rulesets.Mania.UI } } + public override void OnJudgement(DrawableHitObject judgedObject) => columns[judgedObject.HitObject.Column].OnJudgement(judgedObject); + /// /// Whether the column index is a special column for this playfield. /// diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 5f39054d82..f9d8f6b358 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -83,6 +83,7 @@ + diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 369ea76028..7c09139302 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// The colour used for various elements of this DrawableHitObject. /// - public virtual Color4 AccentColour { get; set; } + public virtual Color4 AccentColour { get; set; } = Color4.Gray; protected DrawableHitObject(HitObject hitObject) {