mirror of
https://github.com/ppy/osu.git
synced 2025-01-06 08:22:56 +08:00
Make DrawableStoryboardSample a SkinnableSound
Allows sharing pause logic with gameplay samples.
This commit is contained in:
parent
74e74e1c31
commit
136843c8e4
@ -4,10 +4,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Graphics.Audio;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
@ -106,9 +108,14 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio);
|
Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio);
|
||||||
SelectedMods.Value = new[] { testedMod };
|
SelectedMods.Value = new[] { testedMod };
|
||||||
|
|
||||||
Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, 0));
|
var beatmapSkinSourceContainer = new BeatmapSkinProvidingContainer(Beatmap.Value.Skin);
|
||||||
|
|
||||||
gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1))
|
Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, 0)
|
||||||
|
{
|
||||||
|
Child = beatmapSkinSourceContainer
|
||||||
|
});
|
||||||
|
|
||||||
|
beatmapSkinSourceContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1))
|
||||||
{
|
{
|
||||||
Clock = gameplayContainer.GameplayClock
|
Clock = gameplayContainer.GameplayClock
|
||||||
});
|
});
|
||||||
@ -116,7 +123,7 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
|
|
||||||
AddStep("start", () => gameplayContainer.Start());
|
AddStep("start", () => gameplayContainer.Start());
|
||||||
|
|
||||||
AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate);
|
AddAssert("sample playback rate matches mod rates", () => sample.ChildrenOfType<DrawableSample>().First().AggregateFrequency.Value == expectedRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestSkin : LegacySkin
|
private class TestSkin : LegacySkin
|
||||||
@ -168,8 +175,6 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
: base(sampleInfo)
|
: base(sampleInfo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public new SampleChannel Channel => base.Channel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Graphics.Audio;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IApplicableToSample : IApplicableMod
|
public interface IApplicableToSample : IApplicableMod
|
||||||
{
|
{
|
||||||
void ApplyToSample(SampleChannel sample);
|
void ApplyToSample(DrawableSample sample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics.Audio;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange);
|
track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ApplyToSample(SampleChannel sample)
|
public virtual void ApplyToSample(DrawableSample sample)
|
||||||
{
|
{
|
||||||
sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange);
|
sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange);
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,11 @@ using System.Linq;
|
|||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
AdjustPitch.TriggerChange();
|
AdjustPitch.TriggerChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyToSample(SampleChannel sample)
|
public void ApplyToSample(DrawableSample sample)
|
||||||
{
|
{
|
||||||
sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange);
|
sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange);
|
||||||
}
|
}
|
||||||
|
@ -191,9 +191,25 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
dependencies.CacheAs(gameplayBeatmap);
|
dependencies.CacheAs(gameplayBeatmap);
|
||||||
|
|
||||||
addUnderlayComponents(GameplayClockContainer);
|
var beatmapSkinProvider = new BeatmapSkinProvidingContainer(Beatmap.Value.Skin);
|
||||||
addGameplayComponents(GameplayClockContainer, Beatmap.Value, playableBeatmap);
|
|
||||||
addOverlayComponents(GameplayClockContainer, Beatmap.Value);
|
// the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation
|
||||||
|
// full access to all skin sources.
|
||||||
|
var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, playableBeatmap));
|
||||||
|
|
||||||
|
// load the skinning hierarchy first.
|
||||||
|
// this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.
|
||||||
|
GameplayClockContainer.Add(beatmapSkinProvider.WithChild(rulesetSkinProvider));
|
||||||
|
|
||||||
|
rulesetSkinProvider.AddRange(new[]
|
||||||
|
{
|
||||||
|
// underlay and gameplay should have access the to skinning sources.
|
||||||
|
createUnderlayComponents(),
|
||||||
|
createGameplayComponents(Beatmap.Value, playableBeatmap)
|
||||||
|
});
|
||||||
|
|
||||||
|
// add the overlay components as a separate step as they proxy some elements from the above underlay/gameplay components.
|
||||||
|
GameplayClockContainer.Add(createOverlayComponents(Beatmap.Value));
|
||||||
|
|
||||||
if (!DrawableRuleset.AllowGameplayOverlays)
|
if (!DrawableRuleset.AllowGameplayOverlays)
|
||||||
{
|
{
|
||||||
@ -238,45 +254,31 @@ namespace osu.Game.Screens.Play
|
|||||||
breakTracker.IsBreakTime.BindValueChanged(onBreakTimeChanged, true);
|
breakTracker.IsBreakTime.BindValueChanged(onBreakTimeChanged, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addUnderlayComponents(Container target)
|
private Drawable createUnderlayComponents() =>
|
||||||
|
DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
|
private Drawable createGameplayComponents(WorkingBeatmap working, IBeatmap playableBeatmap) => new ScalingContainer(ScalingMode.Gameplay)
|
||||||
{
|
{
|
||||||
target.Add(DimmableStoryboard = new DimmableStoryboard(Beatmap.Value.Storyboard) { RelativeSizeAxes = Axes.Both });
|
Children = new Drawable[]
|
||||||
}
|
|
||||||
|
|
||||||
private void addGameplayComponents(Container target, WorkingBeatmap working, IBeatmap playableBeatmap)
|
|
||||||
{
|
|
||||||
var beatmapSkinProvider = new BeatmapSkinProvidingContainer(working.Skin);
|
|
||||||
|
|
||||||
// the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation
|
|
||||||
// full access to all skin sources.
|
|
||||||
var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, playableBeatmap));
|
|
||||||
|
|
||||||
// load the skinning hierarchy first.
|
|
||||||
// this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.
|
|
||||||
target.Add(new ScalingContainer(ScalingMode.Gameplay)
|
|
||||||
.WithChild(beatmapSkinProvider
|
|
||||||
.WithChild(target = rulesetSkinProvider)));
|
|
||||||
|
|
||||||
target.AddRange(new Drawable[]
|
|
||||||
{
|
{
|
||||||
DrawableRuleset,
|
DrawableRuleset.With(r =>
|
||||||
|
r.FrameStableComponents.Children = new Drawable[]
|
||||||
|
{
|
||||||
|
ScoreProcessor,
|
||||||
|
HealthProcessor,
|
||||||
|
breakTracker = new BreakTracker(DrawableRuleset.GameplayStartTime, ScoreProcessor)
|
||||||
|
{
|
||||||
|
Breaks = working.Beatmap.Breaks
|
||||||
|
}
|
||||||
|
}),
|
||||||
new ComboEffects(ScoreProcessor)
|
new ComboEffects(ScoreProcessor)
|
||||||
});
|
}
|
||||||
|
};
|
||||||
|
|
||||||
DrawableRuleset.FrameStableComponents.AddRange(new Drawable[]
|
private Drawable createOverlayComponents(WorkingBeatmap working) => new Container
|
||||||
{
|
|
||||||
ScoreProcessor,
|
|
||||||
HealthProcessor,
|
|
||||||
breakTracker = new BreakTracker(DrawableRuleset.GameplayStartTime, ScoreProcessor)
|
|
||||||
{
|
|
||||||
Breaks = working.Beatmap.Breaks
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addOverlayComponents(Container target, WorkingBeatmap working)
|
|
||||||
{
|
{
|
||||||
target.AddRange(new[]
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new[]
|
||||||
{
|
{
|
||||||
DimmableStoryboard.OverlayLayerContainer.CreateProxy(),
|
DimmableStoryboard.OverlayLayerContainer.CreateProxy(),
|
||||||
BreakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
|
BreakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
|
||||||
@ -342,8 +344,8 @@ namespace osu.Game.Screens.Play
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
failAnimation = new FailAnimation(DrawableRuleset) { OnComplete = onFailComplete, },
|
failAnimation = new FailAnimation(DrawableRuleset) { OnComplete = onFailComplete, },
|
||||||
});
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
private void onBreakTimeChanged(ValueChangedEvent<bool> isBreakTime)
|
private void onBreakTimeChanged(ValueChangedEvent<bool> isBreakTime)
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,10 @@ namespace osu.Game.Skinning
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private ISampleStore samples { get; set; }
|
private ISampleStore samples { get; set; }
|
||||||
|
|
||||||
private bool requestedPlaying;
|
/// <summary>
|
||||||
|
/// Whether playback of this sound has been requested, regardless of whether it could be played or not (due to being paused, for instance).
|
||||||
|
/// </summary>
|
||||||
|
protected bool PlaybackRequested;
|
||||||
|
|
||||||
public override bool RemoveWhenNotAlive => false;
|
public override bool RemoveWhenNotAlive => false;
|
||||||
public override bool RemoveCompletedTransforms => false;
|
public override bool RemoveCompletedTransforms => false;
|
||||||
@ -39,7 +42,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
protected virtual bool PlayWhenPaused => false;
|
protected virtual bool PlayWhenPaused => false;
|
||||||
|
|
||||||
private readonly AudioContainer<DrawableSample> samplesContainer;
|
protected readonly AudioContainer<DrawableSample> SamplesContainer;
|
||||||
|
|
||||||
public SkinnableSound(ISampleInfo hitSamples)
|
public SkinnableSound(ISampleInfo hitSamples)
|
||||||
: this(new[] { hitSamples })
|
: this(new[] { hitSamples })
|
||||||
@ -49,7 +52,7 @@ namespace osu.Game.Skinning
|
|||||||
public SkinnableSound(IEnumerable<ISampleInfo> hitSamples)
|
public SkinnableSound(IEnumerable<ISampleInfo> hitSamples)
|
||||||
{
|
{
|
||||||
this.hitSamples = hitSamples.ToArray();
|
this.hitSamples = hitSamples.ToArray();
|
||||||
InternalChild = samplesContainer = new AudioContainer<DrawableSample>();
|
InternalChild = SamplesContainer = new AudioContainer<DrawableSample>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IBindable<bool> samplePlaybackDisabled = new Bindable<bool>();
|
private readonly IBindable<bool> samplePlaybackDisabled = new Bindable<bool>();
|
||||||
@ -63,7 +66,7 @@ namespace osu.Game.Skinning
|
|||||||
samplePlaybackDisabled.BindTo(samplePlaybackDisabler.SamplePlaybackDisabled);
|
samplePlaybackDisabled.BindTo(samplePlaybackDisabler.SamplePlaybackDisabled);
|
||||||
samplePlaybackDisabled.BindValueChanged(disabled =>
|
samplePlaybackDisabled.BindValueChanged(disabled =>
|
||||||
{
|
{
|
||||||
if (requestedPlaying)
|
if (PlaybackRequested)
|
||||||
{
|
{
|
||||||
if (disabled.NewValue && !PlayWhenPaused)
|
if (disabled.NewValue && !PlayWhenPaused)
|
||||||
stop();
|
stop();
|
||||||
@ -87,13 +90,13 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
looping = value;
|
looping = value;
|
||||||
|
|
||||||
samplesContainer.ForEach(c => c.Looping = looping);
|
SamplesContainer.ForEach(c => c.Looping = looping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Play()
|
public void Play()
|
||||||
{
|
{
|
||||||
requestedPlaying = true;
|
PlaybackRequested = true;
|
||||||
play();
|
play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +105,7 @@ namespace osu.Game.Skinning
|
|||||||
if (samplePlaybackDisabled.Value && !PlayWhenPaused)
|
if (samplePlaybackDisabled.Value && !PlayWhenPaused)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
samplesContainer.ForEach(c =>
|
SamplesContainer.ForEach(c =>
|
||||||
{
|
{
|
||||||
if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0)
|
if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0)
|
||||||
c.Play();
|
c.Play();
|
||||||
@ -111,13 +114,13 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
requestedPlaying = false;
|
PlaybackRequested = false;
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stop()
|
private void stop()
|
||||||
{
|
{
|
||||||
samplesContainer.ForEach(c => c.Stop());
|
SamplesContainer.ForEach(c => c.Stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
||||||
@ -146,7 +149,7 @@ namespace osu.Game.Skinning
|
|||||||
return ch;
|
return ch;
|
||||||
}).Where(c => c != null);
|
}).Where(c => c != null);
|
||||||
|
|
||||||
samplesContainer.ChildrenEnumerable = channels.Select(c => new DrawableSample(c));
|
SamplesContainer.ChildrenEnumerable = channels.Select(c => new DrawableSample(c));
|
||||||
|
|
||||||
// Start playback internally for the new samples if the previous ones were playing beforehand.
|
// Start playback internally for the new samples if the previous ones were playing beforehand.
|
||||||
if (wasPlaying)
|
if (wasPlaying)
|
||||||
@ -155,24 +158,24 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
#region Re-expose AudioContainer
|
#region Re-expose AudioContainer
|
||||||
|
|
||||||
public BindableNumber<double> Volume => samplesContainer.Volume;
|
public BindableNumber<double> Volume => SamplesContainer.Volume;
|
||||||
|
|
||||||
public BindableNumber<double> Balance => samplesContainer.Balance;
|
public BindableNumber<double> Balance => SamplesContainer.Balance;
|
||||||
|
|
||||||
public BindableNumber<double> Frequency => samplesContainer.Frequency;
|
public BindableNumber<double> Frequency => SamplesContainer.Frequency;
|
||||||
|
|
||||||
public BindableNumber<double> Tempo => samplesContainer.Tempo;
|
public BindableNumber<double> Tempo => SamplesContainer.Tempo;
|
||||||
|
|
||||||
public void AddAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable)
|
public void AddAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable)
|
||||||
=> samplesContainer.AddAdjustment(type, adjustBindable);
|
=> SamplesContainer.AddAdjustment(type, adjustBindable);
|
||||||
|
|
||||||
public void RemoveAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable)
|
public void RemoveAdjustment(AdjustableProperty type, BindableNumber<double> adjustBindable)
|
||||||
=> samplesContainer.RemoveAdjustment(type, adjustBindable);
|
=> SamplesContainer.RemoveAdjustment(type, adjustBindable);
|
||||||
|
|
||||||
public void RemoveAllAdjustments(AdjustableProperty type)
|
public void RemoveAllAdjustments(AdjustableProperty type)
|
||||||
=> samplesContainer.RemoveAllAdjustments(type);
|
=> SamplesContainer.RemoveAllAdjustments(type);
|
||||||
|
|
||||||
public bool IsPlaying => samplesContainer.Any(s => s.Playing);
|
public bool IsPlaying => SamplesContainer.Any(s => s.Playing);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio.Sample;
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Storyboards.Drawables
|
namespace osu.Game.Storyboards.Drawables
|
||||||
{
|
{
|
||||||
public class DrawableStoryboardSample : Component
|
public class DrawableStoryboardSample : SkinnableSound
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of time allowable beyond the start time of the sample, for the sample to start.
|
/// The amount of time allowable beyond the start time of the sample, for the sample to start.
|
||||||
@ -21,38 +19,37 @@ namespace osu.Game.Storyboards.Drawables
|
|||||||
|
|
||||||
private readonly StoryboardSampleInfo sampleInfo;
|
private readonly StoryboardSampleInfo sampleInfo;
|
||||||
|
|
||||||
protected SampleChannel Channel { get; private set; }
|
|
||||||
|
|
||||||
public override bool RemoveWhenNotAlive => false;
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
public DrawableStoryboardSample(StoryboardSampleInfo sampleInfo)
|
public DrawableStoryboardSample(StoryboardSampleInfo sampleInfo)
|
||||||
|
: base(sampleInfo)
|
||||||
{
|
{
|
||||||
this.sampleInfo = sampleInfo;
|
this.sampleInfo = sampleInfo;
|
||||||
LifetimeStart = sampleInfo.StartTime;
|
LifetimeStart = sampleInfo.StartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[Resolved]
|
||||||
private void load(IBindable<WorkingBeatmap> beatmap, IBindable<IReadOnlyList<Mod>> mods)
|
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
|
||||||
{
|
|
||||||
Channel = beatmap.Value.Skin.GetSample(sampleInfo);
|
|
||||||
if (Channel == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Channel.Volume.Value = sampleInfo.Volume / 100.0;
|
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
||||||
|
{
|
||||||
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
|
||||||
foreach (var mod in mods.Value.OfType<IApplicableToSample>())
|
foreach (var mod in mods.Value.OfType<IApplicableToSample>())
|
||||||
mod.ApplyToSample(Channel);
|
{
|
||||||
|
foreach (var sample in SamplesContainer)
|
||||||
|
mod.ApplyToSample(sample);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
// TODO: this logic will need to be consolidated with other game samples like hit sounds.
|
|
||||||
if (Time.Current < sampleInfo.StartTime)
|
if (Time.Current < sampleInfo.StartTime)
|
||||||
{
|
{
|
||||||
// We've rewound before the start time of the sample
|
// We've rewound before the start time of the sample
|
||||||
Channel?.Stop();
|
Stop();
|
||||||
|
|
||||||
// In the case that the user fast-forwards to a point far beyond the start time of the sample,
|
// In the case that the user fast-forwards to a point far beyond the start time of the sample,
|
||||||
// we want to be able to fall into the if-conditional below (therefore we must not have a life time end)
|
// we want to be able to fall into the if-conditional below (therefore we must not have a life time end)
|
||||||
@ -63,8 +60,8 @@ namespace osu.Game.Storyboards.Drawables
|
|||||||
{
|
{
|
||||||
// We've passed the start time of the sample. We only play the sample if we're within an allowable range
|
// We've passed the start time of the sample. We only play the sample if we're within an allowable range
|
||||||
// from the sample's start, to reduce layering if we've been fast-forwarded far into the future
|
// from the sample's start, to reduce layering if we've been fast-forwarded far into the future
|
||||||
if (Time.Current - sampleInfo.StartTime < allowable_late_start)
|
if (!PlaybackRequested && Time.Current - sampleInfo.StartTime < allowable_late_start)
|
||||||
Channel?.Play();
|
Play();
|
||||||
|
|
||||||
// In the case that the user rewinds to a point far behind the start time of the sample,
|
// In the case that the user rewinds to a point far behind the start time of the sample,
|
||||||
// we want to be able to fall into the if-conditional above (therefore we must not have a life time start)
|
// we want to be able to fall into the if-conditional above (therefore we must not have a life time start)
|
||||||
@ -72,13 +69,5 @@ namespace osu.Game.Storyboards.Drawables
|
|||||||
LifetimeEnd = sampleInfo.StartTime;
|
LifetimeEnd = sampleInfo.StartTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
|
||||||
{
|
|
||||||
Channel?.Stop();
|
|
||||||
Channel = null;
|
|
||||||
|
|
||||||
base.Dispose(isDisposing);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user