2017-06-02 17:20:14 +08:00
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
2017-06-02 18:27:00 +08:00
using System ;
2017-06-09 01:42:17 +08:00
using osu.Framework.Allocation ;
2017-06-01 13:26:21 +08:00
using osu.Framework.Graphics ;
using osu.Framework.Graphics.Containers ;
using osu.Game.Rulesets.Objects.Drawables ;
2017-06-02 18:53:30 +08:00
using OpenTK ;
2017-06-01 13:26:21 +08:00
2017-06-02 19:17:44 +08:00
namespace osu.Game.Rulesets.Timing.Drawables
2017-06-01 13:26:21 +08:00
{
2017-06-02 18:27:00 +08:00
/// <summary>
2017-06-09 00:14:14 +08:00
/// A container for hit objects which applies applies the speed changes defined by the <see cref="Timing.TimingSection.BeatLength"/> and <see cref="Timing.TimingSection.SpeedMultiplier"/>
/// properties to its <see cref="Container{T}.Content"/> to affect the <see cref="HitObjectCollection"/> scroll speed.
2017-06-02 18:27:00 +08:00
/// </summary>
2017-06-08 22:40:24 +08:00
public abstract class DrawableTimingSection : Container < DrawableHitObject >
2017-06-01 13:26:21 +08:00
{
2017-06-09 00:14:14 +08:00
public readonly TimingSection TimingSection ;
2017-06-01 13:26:21 +08:00
protected override Container < DrawableHitObject > Content = > content ;
2017-06-09 01:42:17 +08:00
private Container < DrawableHitObject > content ;
2017-06-01 13:26:21 +08:00
2017-06-02 18:27:00 +08:00
private readonly Axes scrollingAxes ;
/// <summary>
2017-06-09 00:14:14 +08:00
/// Creates a new <see cref="DrawableTimingSection"/>.
2017-06-02 18:27:00 +08:00
/// </summary>
2017-06-09 00:14:14 +08:00
/// <param name="timingSection">The encapsulated timing section that provides the speed changes.</param>
/// <param name="scrollingAxes">The axes through which this drawable timing section scrolls through.</param>
protected DrawableTimingSection ( TimingSection timingSection , Axes scrollingAxes )
2017-06-01 13:26:21 +08:00
{
2017-06-02 18:27:00 +08:00
this . scrollingAxes = scrollingAxes ;
2017-06-01 13:26:21 +08:00
2017-06-09 00:14:14 +08:00
TimingSection = timingSection ;
2017-06-09 01:42:17 +08:00
}
2017-06-01 13:26:21 +08:00
2017-06-09 01:42:17 +08:00
[BackgroundDependencyLoader]
private void load ( )
{
AddInternal ( content = CreateHitObjectCollection ( ) ) ;
2017-06-09 00:14:14 +08:00
content . RelativeChildOffset = new Vector2 ( ( scrollingAxes & Axes . X ) > 0 ? ( float ) TimingSection . Time : 0 , ( scrollingAxes & Axes . Y ) > 0 ? ( float ) TimingSection . Time : 0 ) ;
2017-06-01 13:26:21 +08:00
}
2017-06-02 18:27:00 +08:00
public override Axes RelativeSizeAxes
2017-06-01 13:26:21 +08:00
{
2017-06-02 18:27:00 +08:00
get { return Axes . Both ; }
2017-06-08 22:40:24 +08:00
set { throw new InvalidOperationException ( $"{nameof(DrawableTimingSection)} must always be relatively-sized." ) ; }
2017-06-02 17:11:36 +08:00
}
2017-06-02 18:27:00 +08:00
protected override void Update ( )
2017-06-02 17:11:36 +08:00
{
2017-06-09 01:42:17 +08:00
var parent = Parent as TimingSectionCollection ;
2017-06-02 18:27:00 +08:00
if ( parent = = null )
return ;
2017-06-02 17:11:36 +08:00
2017-06-09 00:14:14 +08:00
float speedAdjustedSize = ( float ) ( 1000 / TimingSection . BeatLength / TimingSection . SpeedMultiplier ) ;
2017-06-02 15:39:31 +08:00
2017-06-09 00:14:14 +08:00
// The application of speed changes happens by modifying our size while maintaining the parent's relative child size as our own
// By doing this the scroll speed of the hit objects is changed by a factor of Size / RelativeChildSize
2017-06-05 19:02:44 +08:00
Size = new Vector2 ( ( scrollingAxes & Axes . X ) > 0 ? speedAdjustedSize : 1 , ( scrollingAxes & Axes . Y ) > 0 ? speedAdjustedSize : 1 ) ;
2017-06-09 01:42:17 +08:00
RelativeChildSize = new Vector2 ( ( scrollingAxes & Axes . X ) > 0 ? ( float ) parent . TimeSpan : 1 , ( scrollingAxes & Axes . Y ) > 0 ? ( float ) parent . TimeSpan : 1 ) ;
2017-06-01 13:26:21 +08:00
}
/// <summary>
2017-06-09 00:14:14 +08:00
/// Whether this timing change can contain a hit object. This is true if the hit object occurs after this timing change with respect to time.
2017-06-01 13:26:21 +08:00
/// </summary>
2017-06-09 00:14:14 +08:00
public bool CanContain ( DrawableHitObject hitObject ) = > TimingSection . Time < = hitObject . HitObject . StartTime ;
2017-06-01 13:26:21 +08:00
2017-06-02 18:27:00 +08:00
/// <summary>
2017-06-09 00:14:14 +08:00
/// Creates the container which handles the movement of a collection of hit objects.
2017-06-02 18:27:00 +08:00
/// </summary>
2017-06-09 01:42:17 +08:00
/// <returns>The hit object collection.</returns>
protected abstract HitObjectCollection CreateHitObjectCollection ( ) ;
2017-06-01 13:26:21 +08:00
}
}