mirror of
https://github.com/osukey/osukey.git
synced 2025-06-08 12:58:01 +09:00
Merge pull request #833 from peppy/logo-beat
Animate osu! logo with playing beatmap
This commit is contained in:
commit
5efe693e79
@ -1 +1 @@
|
|||||||
Subproject commit 773d60eb6b811f395e32a22dc66bb4d2e63a6dbc
|
Subproject commit 777996fb9731ba1895a5ab1323cbbc97259ff741
|
@ -12,20 +12,26 @@ namespace osu.Game.Graphics.Containers
|
|||||||
{
|
{
|
||||||
public class BeatSyncedContainer : Container
|
public class BeatSyncedContainer : Container
|
||||||
{
|
{
|
||||||
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
protected readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||||
|
|
||||||
private int lastBeat;
|
private int lastBeat;
|
||||||
private TimingControlPoint lastTimingPoint;
|
private TimingControlPoint lastTimingPoint;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of time before a beat we should fire <see cref="OnNewBeat(int, TimingControlPoint, EffectControlPoint, TrackAmplitudes)"/>.
|
||||||
|
/// This allows for adding easing to animations that may be synchronised to the beat.
|
||||||
|
/// </summary>
|
||||||
|
protected double EarlyActivationMilliseconds;
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
if (beatmap.Value?.Track == null)
|
if (Beatmap.Value?.Track == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double currentTrackTime = beatmap.Value.Track.CurrentTime;
|
double currentTrackTime = Beatmap.Value.Track.CurrentTime + EarlyActivationMilliseconds;
|
||||||
|
|
||||||
TimingControlPoint timingPoint = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(currentTrackTime);
|
TimingControlPoint timingPoint = Beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(currentTrackTime);
|
||||||
EffectControlPoint effectPoint = beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(currentTrackTime);
|
EffectControlPoint effectPoint = Beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(currentTrackTime);
|
||||||
|
|
||||||
if (timingPoint.BeatLength == 0)
|
if (timingPoint.BeatLength == 0)
|
||||||
return;
|
return;
|
||||||
@ -42,7 +48,7 @@ namespace osu.Game.Graphics.Containers
|
|||||||
double offsetFromBeat = (timingPoint.Time - currentTrackTime) % timingPoint.BeatLength;
|
double offsetFromBeat = (timingPoint.Time - currentTrackTime) % timingPoint.BeatLength;
|
||||||
|
|
||||||
using (BeginDelayedSequence(offsetFromBeat, true))
|
using (BeginDelayedSequence(offsetFromBeat, true))
|
||||||
OnNewBeat(beatIndex, timingPoint, effectPoint, beatmap.Value.Track.CurrentAmplitudes);
|
OnNewBeat(beatIndex, timingPoint, effectPoint, Beatmap.Value.Track.CurrentAmplitudes);
|
||||||
|
|
||||||
lastBeat = beatIndex;
|
lastBeat = beatIndex;
|
||||||
lastTimingPoint = timingPoint;
|
lastTimingPoint = timingPoint;
|
||||||
@ -51,7 +57,7 @@ namespace osu.Game.Graphics.Containers
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase game)
|
private void load(OsuGameBase game)
|
||||||
{
|
{
|
||||||
beatmap.BindTo(game.Beatmap);
|
Beatmap.BindTo(game.Beatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||||
|
@ -5,13 +5,16 @@ using System;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
@ -20,13 +23,15 @@ namespace osu.Game.Screens.Menu
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// osu! logo and its attachments (pulsing, visualiser etc.)
|
/// osu! logo and its attachments (pulsing, visualiser etc.)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OsuLogo : Container
|
public class OsuLogo : BeatSyncedContainer
|
||||||
{
|
{
|
||||||
public readonly Color4 OsuPink = OsuColour.FromHex(@"e967a1");
|
public readonly Color4 OsuPink = OsuColour.FromHex(@"e967a1");
|
||||||
|
|
||||||
private readonly Sprite logo;
|
private readonly Sprite logo;
|
||||||
private readonly CircularContainer logoContainer;
|
private readonly CircularContainer logoContainer;
|
||||||
private readonly Container logoBounceContainer;
|
private readonly Container logoBounceContainer;
|
||||||
|
private readonly Container logoBeatContainer;
|
||||||
|
private readonly Container logoAmplitudeContainer;
|
||||||
private readonly Container logoHoverContainer;
|
private readonly Container logoHoverContainer;
|
||||||
|
|
||||||
private SampleChannel sampleClick;
|
private SampleChannel sampleClick;
|
||||||
@ -67,8 +72,12 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
private const float default_size = 480;
|
private const float default_size = 480;
|
||||||
|
|
||||||
|
private const double beat_in_time = 60;
|
||||||
|
|
||||||
public OsuLogo()
|
public OsuLogo()
|
||||||
{
|
{
|
||||||
|
EarlyActivationMilliseconds = beat_in_time;
|
||||||
|
|
||||||
Size = new Vector2(default_size);
|
Size = new Vector2(default_size);
|
||||||
|
|
||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
@ -76,6 +85,11 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
logoHoverContainer = new Container
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
logoBounceContainer = new Container
|
logoBounceContainer = new Container
|
||||||
@ -83,7 +97,28 @@ namespace osu.Game.Screens.Menu
|
|||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
logoHoverContainer = new Container
|
rippleContainer = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
ripple = new Sprite
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
BlendingMode = BlendingMode.Additive,
|
||||||
|
Alpha = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
logoAmplitudeContainer = new Container
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
logoBeatContainer = new Container
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -139,22 +174,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rippleContainer = new Container
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
ripple = new Sprite
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
BlendingMode = BlendingMode.Additive,
|
|
||||||
Alpha = 0.15f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
impactContainer = new CircularContainer
|
impactContainer = new CircularContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -186,6 +205,10 @@ namespace osu.Game.Screens.Menu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,13 +220,48 @@ namespace osu.Game.Screens.Menu
|
|||||||
ripple.Texture = textures.Get(@"Menu/logo");
|
ripple.Texture = textures.Get(@"Menu/logo");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
private int lastBeatIndex;
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
ripple.ScaleTo(ripple.Scale * 1.1f, 500);
|
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||||
ripple.FadeOut(500);
|
{
|
||||||
ripple.Loop(300);
|
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||||
|
|
||||||
|
lastBeatIndex = beatIndex;
|
||||||
|
|
||||||
|
var beatLength = timingPoint.BeatLength;
|
||||||
|
|
||||||
|
float amplitudeAdjust = Math.Min(1, 0.4f + amplitudes.Maximum);
|
||||||
|
|
||||||
|
if (beatIndex < 0) return;
|
||||||
|
|
||||||
|
logoBeatContainer.ScaleTo(1 - 0.02f * amplitudeAdjust, beat_in_time, EasingTypes.Out);
|
||||||
|
using (logoBeatContainer.BeginDelayedSequence(beat_in_time))
|
||||||
|
logoBeatContainer.ScaleTo(1, beatLength * 2, EasingTypes.OutQuint);
|
||||||
|
|
||||||
|
ripple.ClearTransforms();
|
||||||
|
|
||||||
|
ripple.ScaleTo(logoAmplitudeContainer.Scale);
|
||||||
|
ripple.Alpha = 0.15f * amplitudeAdjust;
|
||||||
|
|
||||||
|
ripple.ScaleTo(logoAmplitudeContainer.Scale * (1 + 0.04f * amplitudeAdjust), beatLength, EasingTypes.OutQuint);
|
||||||
|
ripple.FadeOut(beatLength, EasingTypes.OutQuint);
|
||||||
|
|
||||||
|
if (effectPoint.KiaiMode && flashLayer.Alpha < 0.4f)
|
||||||
|
{
|
||||||
|
flashLayer.ClearTransforms();
|
||||||
|
|
||||||
|
flashLayer.FadeTo(0.2f * amplitudeAdjust, beat_in_time, EasingTypes.Out);
|
||||||
|
using (flashLayer.BeginDelayedSequence(beat_in_time))
|
||||||
|
flashLayer.FadeOut(beatLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
var maxAmplitude = lastBeatIndex >= 0 ? Beatmap.Value?.Track?.CurrentAmplitudes.Maximum ?? 0 : 0;
|
||||||
|
logoAmplitudeContainer.ScaleTo(1 - maxAmplitude * 0.04f, 50, EasingTypes.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user