mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 07:33:20 +08:00
Integrate GameplayBeatmap changes
This commit is contained in:
parent
43342c57b8
commit
e5821ff2b2
@ -7,7 +7,6 @@ using System.Linq;
|
||||
using Humanizer;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing;
|
||||
@ -76,23 +75,14 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
||||
{
|
||||
AddStep("set beatmap", () => setBeatmap());
|
||||
|
||||
// the bindables need to be independent for each content cell to prevent interference,
|
||||
// as if some of the skins don't implement the animation they'll immediately revert to the previous state from the clear state.
|
||||
var states = new List<Bindable<TaikoMascotAnimationState>>();
|
||||
AddStep("create mascot", () => SetContents(() => new DrawableTaikoMascot { RelativeSizeAxes = Axes.Both }));
|
||||
|
||||
AddStep("create mascot", () => SetContents(() =>
|
||||
{
|
||||
var state = new Bindable<TaikoMascotAnimationState>(TaikoMascotAnimationState.Clear);
|
||||
states.Add(state);
|
||||
return new DrawableTaikoMascot { State = { BindTarget = state }, RelativeSizeAxes = Axes.Both };
|
||||
}));
|
||||
|
||||
AddStep("set clear state", () => states.ForEach(state => state.Value = TaikoMascotAnimationState.Clear));
|
||||
AddStep("miss", () => mascots.ForEach(mascot => mascot.OnNewResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Miss })));
|
||||
AddStep("set clear state", () => mascots.ForEach(mascot => mascot.State.Value = TaikoMascotAnimationState.Clear));
|
||||
AddStep("miss", () => mascots.ForEach(mascot => mascot.LastResult.Value = new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Miss }));
|
||||
AddAssert("skins with animations remain in clear state", () => someMascotsIn(TaikoMascotAnimationState.Clear));
|
||||
AddUntilStep("state reverts to fail", () => allMascotsIn(TaikoMascotAnimationState.Fail));
|
||||
|
||||
AddStep("set clear state again", () => states.ForEach(state => state.Value = TaikoMascotAnimationState.Clear));
|
||||
AddStep("set clear state again", () => mascots.ForEach(mascot => mascot.State.Value = TaikoMascotAnimationState.Clear));
|
||||
AddAssert("skins with animations change to clear", () => someMascotsIn(TaikoMascotAnimationState.Clear));
|
||||
}
|
||||
|
||||
@ -220,6 +210,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
||||
|
||||
playfield.OnNewResult(hit, judgementResult);
|
||||
}
|
||||
|
||||
foreach (var mascot in mascots)
|
||||
{
|
||||
mascot.LastResult.Value = judgementResult;
|
||||
}
|
||||
}
|
||||
|
||||
private bool allMascotsIn(TaikoMascotAnimationState state) => mascots.All(d => d.State.Value == state);
|
||||
|
@ -12,14 +12,15 @@ using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Taiko.Judgements;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
public class DrawableTaikoMascot : BeatSyncedContainer
|
||||
{
|
||||
public IBindable<TaikoMascotAnimationState> State => state;
|
||||
public readonly Bindable<TaikoMascotAnimationState> State;
|
||||
public readonly Bindable<JudgementResult> LastResult;
|
||||
|
||||
private readonly Bindable<TaikoMascotAnimationState> state;
|
||||
private readonly Dictionary<TaikoMascotAnimationState, TaikoMascotAnimation> animations;
|
||||
private TaikoMascotAnimation currentAnimation;
|
||||
|
||||
@ -30,12 +31,14 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
Origin = Anchor = Anchor.BottomLeft;
|
||||
|
||||
state = new Bindable<TaikoMascotAnimationState>(startingState);
|
||||
State = new Bindable<TaikoMascotAnimationState>(startingState);
|
||||
LastResult = new Bindable<JudgementResult>();
|
||||
|
||||
animations = new Dictionary<TaikoMascotAnimationState, TaikoMascotAnimation>();
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(TextureStore textures, GameplayBeatmap gameplayBeatmap)
|
||||
{
|
||||
InternalChildren = new[]
|
||||
{
|
||||
@ -44,6 +47,9 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
animations[TaikoMascotAnimationState.Kiai] = new TaikoMascotAnimation(TaikoMascotAnimationState.Kiai),
|
||||
animations[TaikoMascotAnimationState.Fail] = new TaikoMascotAnimation(TaikoMascotAnimationState.Fail),
|
||||
};
|
||||
|
||||
if (gameplayBeatmap != null)
|
||||
((IBindable<JudgementResult>)LastResult).BindTo(gameplayBeatmap.LastJudgementResult);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
@ -51,16 +57,22 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
base.LoadComplete();
|
||||
|
||||
animations.Values.ForEach(animation => animation.Hide());
|
||||
state.BindValueChanged(mascotStateChanged, true);
|
||||
|
||||
State.BindValueChanged(mascotStateChanged, true);
|
||||
LastResult.BindValueChanged(onNewResult);
|
||||
}
|
||||
|
||||
public void OnNewResult(JudgementResult result)
|
||||
private void onNewResult(ValueChangedEvent<JudgementResult> resultChangedEvent)
|
||||
{
|
||||
var result = resultChangedEvent.NewValue;
|
||||
if (result == null)
|
||||
return;
|
||||
|
||||
// TODO: missing support for clear/fail state transition at end of beatmap gameplay
|
||||
|
||||
if (triggerComboClear(result) || triggerSwellClear(result))
|
||||
{
|
||||
state.Value = TaikoMascotAnimationState.Clear;
|
||||
State.Value = TaikoMascotAnimationState.Clear;
|
||||
// always consider a clear equivalent to a hit to avoid clear -> miss transitions
|
||||
lastObjectHit = true;
|
||||
}
|
||||
@ -79,7 +91,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
state.Value = getNextState();
|
||||
State.Value = getNextState();
|
||||
}
|
||||
|
||||
private TaikoMascotAnimationState getNextState()
|
||||
@ -87,7 +99,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
// don't change state if current animation is playing
|
||||
// (used for clear state - others are manually animated on new beats)
|
||||
if (currentAnimation != null && !currentAnimation.Completed)
|
||||
return state.Value;
|
||||
return State.Value;
|
||||
|
||||
if (!lastObjectHit)
|
||||
return TaikoMascotAnimationState.Fail;
|
||||
|
@ -40,8 +40,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
|
||||
private Container hitTargetOffsetContent;
|
||||
|
||||
private SkinnableDrawable mascotDrawable;
|
||||
|
||||
public TaikoPlayfield(ControlPointInfo controlPoints)
|
||||
{
|
||||
this.controlPoints = controlPoints;
|
||||
@ -127,7 +125,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
},
|
||||
}
|
||||
},
|
||||
mascotDrawable = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoDon), _ => Empty())
|
||||
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoDon), _ => Empty())
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.TopLeft,
|
||||
@ -212,11 +210,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
addExplosion(judgedObject, type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mascotDrawable.Drawable is DrawableTaikoMascot mascot)
|
||||
{
|
||||
mascot.OnNewResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
private void addDrumRollHit(DrawableDrumRollTick drawableTick) =>
|
||||
|
Loading…
Reference in New Issue
Block a user