1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 05:53:10 +08:00

Merge pull request #1239 from smoogipooo/mania-hit-explosions

Initial implementation of osu!mania hit explosions
This commit is contained in:
Dean Herbert 2017-09-11 19:01:40 +09:00 committed by GitHub
commit 719d0fd974
10 changed files with 149 additions and 32 deletions

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions; 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.Mania.UI;
using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.Timing;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Desktop.Tests.Visual namespace osu.Desktop.Tests.Visual
{ {
@ -29,6 +32,8 @@ namespace osu.Desktop.Tests.Visual
public TestCaseManiaPlayfield() public TestCaseManiaPlayfield()
{ {
var rng = new Random(1337);
AddStep("1 column", () => createPlayfield(1, SpecialColumnPosition.Normal)); AddStep("1 column", () => createPlayfield(1, SpecialColumnPosition.Normal));
AddStep("4 columns", () => createPlayfield(4, SpecialColumnPosition.Normal)); AddStep("4 columns", () => createPlayfield(4, SpecialColumnPosition.Normal));
AddStep("Left special style", () => createPlayfield(4, SpecialColumnPosition.Left)); 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 input (reversed)", () => createPlayfieldWithNotes(false, true));
AddStep("Notes with gravity", () => createPlayfieldWithNotes(true)); AddStep("Notes with gravity", () => createPlayfieldWithNotes(true));
AddStep("Notes with gravity (reversed)", () => createPlayfieldWithNotes(true, 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] [BackgroundDependencyLoader]
@ -56,7 +76,7 @@ namespace osu.Desktop.Tests.Visual
TimingPoint = { BeatLength = 1000 } TimingPoint = { BeatLength = 1000 }
}, gravity ? ScrollingAlgorithm.Gravity : ScrollingAlgorithm.Basic); }, 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(); Clear();
@ -72,6 +92,8 @@ namespace osu.Desktop.Tests.Visual
}); });
playfield.Inverted.Value = inverted; playfield.Inverted.Value = inverted;
return playfield;
} }
private void createPlayfieldWithNotes(bool gravity, bool inverted = false) private void createPlayfieldWithNotes(bool gravity, bool inverted = false)

View File

@ -59,9 +59,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
} }
} }
}; };
// Set the default glow
AccentColour = Color4.White;
} }
public override Color4 AccentColour public override Color4 AccentColour

View File

@ -105,12 +105,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
protected override void UpdateState(ArmedState state) protected override void UpdateState(ArmedState state)
{ {
switch (State)
{
case ArmedState.Hit:
Colour = Color4.Green;
break;
}
} }
public virtual bool OnPressed(ManiaAction action) public virtual bool OnPressed(ManiaAction action)

View File

@ -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;
}
}
/// <summary> /// <summary>
/// The head note of the hold. /// The head note of the hold.
/// </summary> /// </summary>
@ -80,7 +91,8 @@ namespace osu.Game.Rulesets.Mania.Objects
{ {
ret.Add(new HoldNoteTick ret.Add(new HoldNoteTick
{ {
StartTime = t StartTime = t,
Column = Column
}); });
} }

View File

@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.Mania.Objects
{ {
public abstract class ManiaHitObject : HitObject, IHasColumn public abstract class ManiaHitObject : HitObject, IHasColumn
{ {
public int Column { get; set; } public virtual int Column { get; set; }
} }
} }

View File

@ -36,6 +36,9 @@ namespace osu.Game.Rulesets.Mania.UI
private readonly Container hitTargetBar; private readonly Container hitTargetBar;
private readonly Container keyIcon; private readonly Container keyIcon;
internal readonly Container TopLevelContainer;
private readonly Container explosionContainer;
protected override Container<Drawable> Content => content; protected override Container<Drawable> Content => content;
private readonly Container<Drawable> content; private readonly Container<Drawable> content;
@ -98,6 +101,11 @@ namespace osu.Game.Rulesets.Mania.UI
{ {
Pressed = onPressed, Pressed = onPressed,
Released = onReleased 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; public override Axes RelativeSizeAxes => Axes.Y;
@ -194,6 +205,14 @@ namespace osu.Game.Rulesets.Mania.UI
HitObjects.Add(hitObject); HitObjects.Add(hitObject);
} }
public override void OnJudgement(DrawableHitObject<ManiaHitObject, ManiaJudgement> judgedObject)
{
if (judgedObject.Judgement.Result != HitResult.Hit)
return;
explosionContainer.Add(new HitExplosion(judgedObject));
}
private bool onPressed(ManiaAction action) private bool onPressed(ManiaAction action)
{ {
if (action == Action) if (action == Action)

View File

@ -0,0 +1,66 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// 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<ManiaHitObject, ManiaJudgement> 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);
}
}
}

View File

@ -65,21 +65,21 @@ namespace osu.Game.Rulesets.Mania.UI
Inverted.Value = true; Inverted.Value = true;
Container topLevelContainer;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
new Container new Container
{ {
Name = "Playfield elements",
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Y,
Masking = true, AutoSizeAxes = Axes.X,
Children = new Drawable[] Children = new Drawable[]
{ {
new Container new Container
{ {
Name = "Masked elements", Name = "Columns mask",
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X, AutoSizeAxes = Axes.X,
Masking = true, Masking = true,
@ -87,6 +87,7 @@ namespace osu.Game.Rulesets.Mania.UI
{ {
new Box new Box
{ {
Name = "Background",
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4.Black Colour = Color4.Black
}, },
@ -98,27 +99,28 @@ namespace osu.Game.Rulesets.Mania.UI
Direction = FillDirection.Horizontal, Direction = FillDirection.Horizontal,
Padding = new MarginPadding { Left = 1, Right = 1 }, Padding = new MarginPadding { Left = 1, Right = 1 },
Spacing = new Vector2(1, 0) Spacing = new Vector2(1, 0)
} },
} }
}, },
new Container new Container
{ {
Name = "Barlines mask",
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Y,
Padding = new MarginPadding { Top = HIT_TARGET_POSITION }, Width = 1366, // Bar lines should only be masked on the vertical axis
Children = new[] BypassAutoSizeAxes = Axes.Both,
{ Masking = true,
content = new Container Child = content = new Container
{ {
Name = "Bar lines", Name = "Bar lines",
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
// Width is set in the Update method 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.IsSpecial = isSpecialColumn(i);
c.Action = c.IsSpecial ? ManiaAction.Special : currentAction++; c.Action = c.IsSpecial ? ManiaAction.Special : currentAction++;
topLevelContainer.Add(c.TopLevelContainer.CreateProxy());
columns.Add(c); columns.Add(c);
AddNested(c); AddNested(c);
} }
@ -177,6 +181,8 @@ namespace osu.Game.Rulesets.Mania.UI
} }
} }
public override void OnJudgement(DrawableHitObject<ManiaHitObject, ManiaJudgement> judgedObject) => columns[judgedObject.HitObject.Column].OnJudgement(judgedObject);
/// <summary> /// <summary>
/// Whether the column index is a special column for this playfield. /// Whether the column index is a special column for this playfield.
/// </summary> /// </summary>

View File

@ -83,6 +83,7 @@
<Compile Include="Timing\GravityScrollingContainer.cs" /> <Compile Include="Timing\GravityScrollingContainer.cs" />
<Compile Include="Timing\ScrollingAlgorithm.cs" /> <Compile Include="Timing\ScrollingAlgorithm.cs" />
<Compile Include="UI\Column.cs" /> <Compile Include="UI\Column.cs" />
<Compile Include="UI\HitExplosion.cs" />
<Compile Include="UI\ManiaRulesetContainer.cs" /> <Compile Include="UI\ManiaRulesetContainer.cs" />
<Compile Include="UI\ManiaPlayfield.cs" /> <Compile Include="UI\ManiaPlayfield.cs" />
<Compile Include="ManiaRuleset.cs" /> <Compile Include="ManiaRuleset.cs" />

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// <summary> /// <summary>
/// The colour used for various elements of this DrawableHitObject. /// The colour used for various elements of this DrawableHitObject.
/// </summary> /// </summary>
public virtual Color4 AccentColour { get; set; } public virtual Color4 AccentColour { get; set; } = Color4.Gray;
protected DrawableHitObject(HitObject hitObject) protected DrawableHitObject(HitObject hitObject)
{ {