1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-30 07:32:55 +08:00
osu-lazer/osu.Game/Graphics/Containers/FacadeContainer.cs

103 lines
4.0 KiB
C#
Raw Normal View History

2019-03-22 18:01:32 +08:00
// 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.
2019-03-22 19:01:58 +08:00
using osu.Framework.Graphics;
2019-03-22 18:01:32 +08:00
using osu.Framework.Graphics.Containers;
2019-03-26 09:48:29 +08:00
using osu.Framework.MathUtils;
2019-03-22 18:01:32 +08:00
using osu.Game.Screens.Menu;
using osuTK;
namespace osu.Game.Graphics.Containers
{
2019-03-26 16:18:35 +08:00
/// <summary>
/// A container that creates a <see cref="Facade"/> to be used by its children.
/// This container also updates the position and size of the Facade, and contains logic for tracking an <see cref="OsuLogo"/> on the Facade's position.
/// </summary>
2019-03-22 18:01:32 +08:00
public class FacadeContainer : Container
{
2019-03-26 16:18:35 +08:00
protected virtual Facade CreateFacade() => new Facade();
2019-03-27 10:44:50 +08:00
public Facade Facade { get; }
2019-03-26 16:18:35 +08:00
/// <summary>
/// Whether or not the logo assigned to this FacadeContainer should be tracking the position its facade.
/// </summary>
public bool Tracking;
2019-03-22 19:01:58 +08:00
private OsuLogo logo;
2019-03-26 16:18:35 +08:00
private float facadeScale;
private Vector2 startPosition;
private Easing easing;
private double startTime;
private double duration;
2019-03-24 14:18:38 +08:00
2019-03-22 18:01:32 +08:00
public FacadeContainer()
{
Facade = CreateFacade();
2019-03-22 18:01:32 +08:00
}
2019-03-26 16:18:35 +08:00
/// <summary>
/// Assign the logo that should track the Facade's position, as well as how it should transform to its initial position.
2019-03-26 16:18:35 +08:00
/// </summary>
/// <param name="logo"> The instance of the logo to be used for tracking. </param>
/// <param name="facadeScale"> The scale of the facade. </param>
/// <param name="duration"> The duration of the initial transform. Default is instant.</param>
/// <param name="easing"> The easing type of the initial transform. </param>
public void SetLogo(OsuLogo logo, float facadeScale, double duration = 0, Easing easing = Easing.None)
2019-03-22 19:01:58 +08:00
{
if (logo != null)
{
this.logo = logo;
}
2019-03-26 16:18:35 +08:00
this.facadeScale = facadeScale;
this.duration = duration;
this.easing = easing;
}
2019-03-26 09:48:29 +08:00
private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(Facade.ScreenSpaceDrawQuad.Centre);
2019-03-26 09:48:29 +08:00
2019-03-22 19:01:58 +08:00
protected override void UpdateAfterChildren()
2019-03-22 18:01:32 +08:00
{
2019-03-22 19:01:58 +08:00
base.UpdateAfterChildren();
2019-03-26 16:18:35 +08:00
if (logo == null || !Tracking)
2019-03-22 19:01:58 +08:00
return;
Facade.Size = new Vector2(logo.SizeForFlow * facadeScale);
2019-03-22 19:01:58 +08:00
if (Facade.IsLoaded && logo.Position != logoTrackingPosition)
2019-03-22 19:01:58 +08:00
{
2019-03-26 16:18:35 +08:00
// Required for the correct position of the logo to be set with respect to logoTrackingPosition
logo.RelativePositionAxes = Axes.None;
2019-03-26 09:48:29 +08:00
2019-03-26 16:18:35 +08:00
// If this is our first update since tracking has started, initialize our starting values for interpolation
2019-03-26 09:48:29 +08:00
if (startTime == 0)
{
startTime = Time.Current;
2019-03-26 16:18:35 +08:00
startPosition = logo.Position;
2019-03-26 09:48:29 +08:00
}
var endTime = startTime + duration;
var remainingDuration = endTime - Time.Current;
2019-03-26 16:18:35 +08:00
// If our transform should be instant, our position should already be at logoTrackingPosition, thus set the blend to 0.
// If we are already past when the transform should be finished playing, set the blend to 0 so that the logo is always at the position of the facade.
var blend = duration > 0 && remainingDuration > 0
? (float)Interpolation.ApplyEasing(easing, remainingDuration / duration)
: 0;
2019-03-26 09:48:29 +08:00
2019-03-26 16:18:35 +08:00
// Interpolate the position of the logo, where blend 0 is the position of the Facade, and blend 1 is where the logo was when it first began interpolating.
logo.Position = Vector2.Lerp(logoTrackingPosition, startPosition, blend);
2019-03-22 19:01:58 +08:00
}
2019-03-22 18:01:32 +08:00
}
}
}
2019-03-26 09:48:29 +08:00
2019-03-26 16:18:35 +08:00
/// <summary>
/// A placeholder container that serves as a dummy object to denote another object's location and size.
/// </summary>
2019-03-26 09:48:29 +08:00
public class Facade : Container
{
2019-03-26 16:18:35 +08:00
}