1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 20:32:55 +08:00

Merge pull request #22820 from peppy/mania-shadow-icon-changes

Update osu!mania argon design in line with proposal
This commit is contained in:
Bartłomiej Dach 2023-03-20 20:34:33 +01:00 committed by GitHub
commit 88700c85fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 182 additions and 74 deletions

View File

@ -236,6 +236,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
};
// Position and resize the body to lie half-way under the head and the tail notes.
// The rationale for this is account for heads/tails with corner radius.
bodyPiece.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2;
bodyPiece.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2;

View File

@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
protected override ManiaSkinComponents Component => ManiaSkinComponents.HoldNoteTail;
protected DrawableHoldNote HoldNote => (DrawableHoldNote)ParentHitObject;
protected internal DrawableHoldNote HoldNote => (DrawableHoldNote)ParentHitObject;
public DrawableHoldNoteTail()
: this(null)

View File

@ -43,9 +43,10 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
{
largeFaint = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.Both,
Height = ArgonNotePiece.NOTE_ACCENT_RATIO,
Masking = true,
CornerRadius = ArgonNotePiece.CORNER_RADIUS,
Blending = BlendingParameters.Additive,

View File

@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
private void load(IScrollingInfo scrollingInfo)
{
RelativeSizeAxes = Axes.X;
Height = ArgonNotePiece.NOTE_HEIGHT;
Height = ArgonNotePiece.NOTE_HEIGHT * ArgonNotePiece.NOTE_ACCENT_RATIO;
Masking = true;
CornerRadius = ArgonNotePiece.CORNER_RADIUS;

View File

@ -20,10 +20,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
public partial class ArgonHoldBodyPiece : CompositeDrawable, IHoldNoteBody
{
protected readonly Bindable<Color4> AccentColour = new Bindable<Color4>();
protected readonly IBindable<bool> IsHitting = new Bindable<bool>();
private Drawable background = null!;
private Box foreground = null!;
private ArgonHoldNoteHittingLayer hittingLayer = null!;
public ArgonHoldBodyPiece()
{
@ -32,7 +31,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
// Without this, the width of the body will be slightly larger than the head/tail.
Masking = true;
CornerRadius = ArgonNotePiece.CORNER_RADIUS;
Blending = BlendingParameters.Additive;
}
[BackgroundDependencyLoader(true)]
@ -41,12 +39,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
InternalChildren = new[]
{
background = new Box { RelativeSizeAxes = Axes.Both },
foreground = new Box
{
RelativeSizeAxes = Axes.Both,
Blending = BlendingParameters.Additive,
Alpha = 0,
},
hittingLayer = new ArgonHoldNoteHittingLayer()
};
if (drawableObject != null)
@ -54,44 +47,19 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
var holdNote = (DrawableHoldNote)drawableObject;
AccentColour.BindTo(holdNote.AccentColour);
IsHitting.BindTo(holdNote.IsHitting);
hittingLayer.AccentColour.BindTo(holdNote.AccentColour);
((IBindable<bool>)hittingLayer.IsHitting).BindTo(holdNote.IsHitting);
}
AccentColour.BindValueChanged(colour =>
{
background.Colour = colour.NewValue.Darken(1.2f);
foreground.Colour = colour.NewValue.Opacity(0.2f);
background.Colour = colour.NewValue.Darken(0.6f);
}, true);
IsHitting.BindValueChanged(hitting =>
{
const float animation_length = 50;
foreground.ClearTransforms();
if (hitting.NewValue)
{
// wait for the next sync point
double synchronisedOffset = animation_length * 2 - Time.Current % (animation_length * 2);
using (foreground.BeginDelayedSequence(synchronisedOffset))
{
foreground.FadeTo(1, animation_length).Then()
.FadeTo(0.5f, animation_length)
.Loop();
}
}
else
{
foreground.FadeOut(animation_length);
}
});
}
public void Recycle()
{
foreground.ClearTransforms();
foreground.Alpha = 0;
hittingLayer.Recycle();
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osuTK;
namespace osu.Game.Rulesets.Mania.Skinning.Argon
{
internal partial class ArgonHoldNoteHeadPiece : ArgonNotePiece
{
protected override Drawable CreateIcon() => new Circle
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Y = 2,
Size = new Vector2(20, 5),
};
}
}

View File

@ -0,0 +1,64 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osuTK.Graphics;
using Box = osu.Framework.Graphics.Shapes.Box;
namespace osu.Game.Rulesets.Mania.Skinning.Argon
{
public partial class ArgonHoldNoteHittingLayer : Box
{
public readonly Bindable<Color4> AccentColour = new Bindable<Color4>();
public readonly Bindable<bool> IsHitting = new Bindable<bool>();
public ArgonHoldNoteHittingLayer()
{
RelativeSizeAxes = Axes.Both;
Blending = BlendingParameters.Additive;
Alpha = 0;
}
protected override void LoadComplete()
{
base.LoadComplete();
AccentColour.BindValueChanged(colour =>
{
Colour = colour.NewValue.Lighten(0.2f).Opacity(0.3f);
}, true);
IsHitting.BindValueChanged(hitting =>
{
const float animation_length = 80;
ClearTransforms();
if (hitting.NewValue)
{
// wait for the next sync point
double synchronisedOffset = animation_length * 2 - Time.Current % (animation_length * 2);
using (BeginDelayedSequence(synchronisedOffset))
{
this.FadeTo(1, animation_length, Easing.OutSine).Then()
.FadeTo(0.5f, animation_length, Easing.InSine)
.Loop();
}
}
else
{
this.FadeOut(animation_length);
}
}, true);
}
public void Recycle()
{
ClearTransforms();
Alpha = 0;
}
}
}

View File

@ -5,8 +5,10 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
using osuTK;
@ -16,47 +18,68 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
{
internal partial class ArgonHoldNoteTailPiece : CompositeDrawable
{
[Resolved]
private DrawableHitObject? drawableObject { get; set; }
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
private readonly IBindable<Color4> accentColour = new Bindable<Color4>();
private readonly Box shadeBackground;
private readonly Box shadeForeground;
private readonly Box foreground;
private readonly ArgonHoldNoteHittingLayer hittingLayer;
private readonly Box foregroundAdditive;
public ArgonHoldNoteTailPiece()
{
RelativeSizeAxes = Axes.X;
Height = ArgonNotePiece.NOTE_HEIGHT;
CornerRadius = ArgonNotePiece.CORNER_RADIUS;
Masking = true;
InternalChildren = new Drawable[]
{
shadeBackground = new Box
{
RelativeSizeAxes = Axes.Both,
},
new Container
{
RelativeSizeAxes = Axes.Both,
Height = ArgonNotePiece.NOTE_ACCENT_RATIO,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.X,
Height = ArgonNotePiece.NOTE_HEIGHT,
CornerRadius = ArgonNotePiece.CORNER_RADIUS,
Masking = true,
Children = new Drawable[]
{
shadeForeground = new Box
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Colour4.Black),
// Avoid ugly single pixel overlap.
Height = 0.9f,
},
},
new Container
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Height = ArgonNotePiece.NOTE_ACCENT_RATIO,
CornerRadius = ArgonNotePiece.CORNER_RADIUS,
Masking = true,
Children = new Drawable[]
{
foreground = new Box
{
RelativeSizeAxes = Axes.Both,
},
hittingLayer = new ArgonHoldNoteHittingLayer(),
foregroundAdditive = new Box
{
RelativeSizeAxes = Axes.Both,
Blending = BlendingParameters.Additive,
Height = 0.5f,
},
},
},
}
},
};
}
[BackgroundDependencyLoader(true)]
private void load(IScrollingInfo scrollingInfo, DrawableHitObject? drawableObject)
private void load(IScrollingInfo scrollingInfo)
{
direction.BindTo(scrollingInfo.Direction);
direction.BindValueChanged(onDirectionChanged, true);
@ -65,9 +88,24 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
{
accentColour.BindTo(drawableObject.AccentColour);
accentColour.BindValueChanged(onAccentChanged, true);
drawableObject.HitObjectApplied += hitObjectApplied;
}
}
private void hitObjectApplied(DrawableHitObject drawableHitObject)
{
var holdNoteTail = (DrawableHoldNoteTail)drawableHitObject;
hittingLayer.Recycle();
hittingLayer.AccentColour.UnbindBindings();
hittingLayer.AccentColour.BindTo(holdNoteTail.HoldNote.AccentColour);
hittingLayer.IsHitting.UnbindBindings();
((IBindable<bool>)hittingLayer.IsHitting).BindTo(holdNoteTail.HoldNote.IsHitting);
}
private void onDirectionChanged(ValueChangedEvent<ScrollingDirection> direction)
{
Scale = new Vector2(1, direction.NewValue == ScrollingDirection.Up ? -1 : 1);
@ -75,8 +113,20 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
private void onAccentChanged(ValueChangedEvent<Color4> accent)
{
shadeBackground.Colour = accent.NewValue.Darken(1.7f);
shadeForeground.Colour = accent.NewValue.Darken(1.1f);
foreground.Colour = accent.NewValue.Darken(0.6f); // matches body
foregroundAdditive.Colour = ColourInfo.GradientVertical(
accent.NewValue.Opacity(0.4f),
accent.NewValue.Opacity(0)
);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (drawableObject != null)
drawableObject.HitObjectApplied -= hitObjectApplied;
}
}
}

View File

@ -26,7 +26,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
private readonly IBindable<Color4> accentColour = new Bindable<Color4>();
private readonly Box colouredBox;
private readonly Box shadow;
public ArgonNotePiece()
{
@ -36,11 +35,12 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
CornerRadius = CORNER_RADIUS;
Masking = true;
InternalChildren = new Drawable[]
InternalChildren = new[]
{
shadow = new Box
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Colour4.Black)
},
new Container
{
@ -65,18 +65,22 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
RelativeSizeAxes = Axes.X,
Height = CORNER_RADIUS * 2,
},
new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Y = 4,
Icon = FontAwesome.Solid.AngleDown,
Size = new Vector2(20),
Scale = new Vector2(1, 0.7f)
}
CreateIcon(),
};
}
protected virtual Drawable CreateIcon() => new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Y = 4,
// TODO: replace with a non-squashed version.
// The 0.7f height scale should be removed.
Icon = FontAwesome.Solid.AngleDown,
Size = new Vector2(20),
Scale = new Vector2(1, 0.7f)
};
[BackgroundDependencyLoader(true)]
private void load(IScrollingInfo scrollingInfo, DrawableHitObject? drawableObject)
{
@ -105,8 +109,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
accent.NewValue.Lighten(0.1f),
accent.NewValue
);
shadow.Colour = accent.NewValue.Darken(0.5f);
}
}
}

View File

@ -50,6 +50,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
return new ArgonHoldNoteTailPiece();
case ManiaSkinComponents.HoldNoteHead:
return new ArgonHoldNoteHeadPiece();
case ManiaSkinComponents.Note:
return new ArgonNotePiece();