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:
commit
719d0fd974
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
66
osu.Game.Rulesets.Mania/UI/HitExplosion.cs
Normal file
66
osu.Game.Rulesets.Mania/UI/HitExplosion.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
||||||
|
@ -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" />
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user