mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 15:07:44 +08:00
Merge pull request #3100 from UselessToucan/replay_keycounter
Restore key counters state on replay rewinding
This commit is contained in:
commit
d18a86c5a7
@ -1,9 +1,14 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.EventArgs;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Screens.Play;
|
||||
using OpenTK.Input;
|
||||
|
||||
@ -12,21 +17,30 @@ namespace osu.Game.Tests.Visual
|
||||
[TestFixture]
|
||||
public class TestCaseKeyCounter : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(KeyCounterKeyboard),
|
||||
typeof(KeyCounterMouse),
|
||||
typeof(KeyCounterCollection)
|
||||
};
|
||||
|
||||
public TestCaseKeyCounter()
|
||||
{
|
||||
KeyCounterKeyboard rewindTestKeyCounterKeyboard;
|
||||
KeyCounterCollection kc = new KeyCounterCollection
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Children = new KeyCounter[]
|
||||
{
|
||||
new KeyCounterKeyboard(Key.Z),
|
||||
rewindTestKeyCounterKeyboard = new KeyCounterKeyboard(Key.X),
|
||||
new KeyCounterKeyboard(Key.X),
|
||||
new KeyCounterMouse(MouseButton.Left),
|
||||
new KeyCounterMouse(MouseButton.Right),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
AddStep("Add random", () =>
|
||||
{
|
||||
Key key = (Key)((int)Key.A + RNG.Next(26));
|
||||
@ -34,7 +48,57 @@ namespace osu.Game.Tests.Visual
|
||||
});
|
||||
AddSliderStep("Fade time", 0, 200, 50, v => kc.FadeTime = v);
|
||||
|
||||
Key testKey = ((KeyCounterKeyboard)kc.Children.First()).Key;
|
||||
double time1 = 0;
|
||||
|
||||
AddStep($"Press {testKey} key", () =>
|
||||
{
|
||||
rewindTestKeyCounterKeyboard.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = testKey, Repeat = false });
|
||||
rewindTestKeyCounterKeyboard.TriggerOnKeyUp(null, new KeyUpEventArgs { Key = testKey });
|
||||
});
|
||||
|
||||
AddAssert($"Check {testKey} counter after keypress", () => rewindTestKeyCounterKeyboard.CountPresses == 1);
|
||||
|
||||
AddStep($"Press {testKey} key", () =>
|
||||
{
|
||||
rewindTestKeyCounterKeyboard.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = testKey, Repeat = false });
|
||||
rewindTestKeyCounterKeyboard.TriggerOnKeyUp(null, new KeyUpEventArgs { Key = testKey });
|
||||
time1 = Clock.CurrentTime;
|
||||
});
|
||||
|
||||
AddAssert($"Check {testKey} counter after keypress", () => rewindTestKeyCounterKeyboard.CountPresses == 2);
|
||||
|
||||
IFrameBasedClock oldClock = null;
|
||||
|
||||
AddStep($"Rewind {testKey} counter once", () =>
|
||||
{
|
||||
oldClock = rewindTestKeyCounterKeyboard.Clock;
|
||||
rewindTestKeyCounterKeyboard.Clock = new FramedOffsetClock(new FixedClock(time1 - 10));
|
||||
});
|
||||
|
||||
AddAssert($"Check {testKey} counter after rewind", () => rewindTestKeyCounterKeyboard.CountPresses == 1);
|
||||
|
||||
AddStep($"Rewind {testKey} counter to zero", () => rewindTestKeyCounterKeyboard.Clock = new FramedOffsetClock(new FixedClock(0)));
|
||||
|
||||
AddAssert($"Check {testKey} counter after rewind", () => rewindTestKeyCounterKeyboard.CountPresses == 0);
|
||||
|
||||
AddStep("Restore clock", () => rewindTestKeyCounterKeyboard.Clock = oldClock);
|
||||
|
||||
Add(kc);
|
||||
}
|
||||
|
||||
private class FixedClock : IClock
|
||||
{
|
||||
private readonly double time;
|
||||
|
||||
public FixedClock(double time)
|
||||
{
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public double CurrentTime => time;
|
||||
public double Rate => 1;
|
||||
public bool IsRunning => false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ namespace osu.Game.Screens.Play
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
KeyCounter = CreateKeyCounter(),
|
||||
KeyCounter = CreateKeyCounter(adjustableClock as IFrameBasedClock),
|
||||
HoldToQuit = CreateQuitButton(),
|
||||
}
|
||||
}
|
||||
@ -194,12 +194,13 @@ namespace osu.Game.Screens.Play
|
||||
Margin = new MarginPadding { Top = 20 }
|
||||
};
|
||||
|
||||
protected virtual KeyCounterCollection CreateKeyCounter() => new KeyCounterCollection
|
||||
protected virtual KeyCounterCollection CreateKeyCounter(IFrameBasedClock offsetClock) => new KeyCounterCollection
|
||||
{
|
||||
FadeTime = 50,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Margin = new MarginPadding(10),
|
||||
AudioClock = offsetClock
|
||||
};
|
||||
|
||||
protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
|
||||
|
@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -19,6 +21,9 @@ namespace osu.Game.Screens.Play
|
||||
private Container textLayer;
|
||||
private SpriteText countSpriteText;
|
||||
|
||||
private readonly List<KeyCounterState> states = new List<KeyCounterState>();
|
||||
private KeyCounterState currentState;
|
||||
|
||||
public bool IsCounting { get; set; } = true;
|
||||
private int countPresses;
|
||||
public int CountPresses
|
||||
@ -45,7 +50,10 @@ namespace osu.Game.Screens.Play
|
||||
isLit = value;
|
||||
updateGlowSprite(value);
|
||||
if (value && IsCounting)
|
||||
{
|
||||
CountPresses++;
|
||||
saveState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -128,6 +136,32 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetCount() => CountPresses = 0;
|
||||
public void ResetCount()
|
||||
{
|
||||
CountPresses = 0;
|
||||
states.Clear();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (currentState?.Time > Clock.CurrentTime)
|
||||
restoreStateTo(Clock.CurrentTime);
|
||||
}
|
||||
|
||||
private void saveState()
|
||||
{
|
||||
if (currentState == null || currentState.Time < Clock.CurrentTime)
|
||||
states.Add(currentState = new KeyCounterState(Clock.CurrentTime, CountPresses));
|
||||
}
|
||||
|
||||
private void restoreStateTo(double time)
|
||||
{
|
||||
states.RemoveAll(state => state.Time > time);
|
||||
|
||||
currentState = states.LastOrDefault();
|
||||
CountPresses = currentState?.Count ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,15 +3,16 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Input.EventArgs;
|
||||
using osu.Framework.Input.States;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Configuration;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
@ -37,6 +38,9 @@ namespace osu.Game.Screens.Play
|
||||
key.FadeTime = FadeTime;
|
||||
key.KeyDownTextColor = KeyDownTextColor;
|
||||
key.KeyUpTextColor = KeyUpTextColor;
|
||||
// Use the same clock object as SongProgress for saving KeyCounter state
|
||||
if (AudioClock != null)
|
||||
key.Clock = AudioClock;
|
||||
}
|
||||
|
||||
public void ResetCount()
|
||||
@ -118,6 +122,8 @@ namespace osu.Game.Screens.Play
|
||||
public override bool HandleKeyboardInput => receptor == null;
|
||||
public override bool HandleMouseInput => receptor == null;
|
||||
|
||||
public IFrameBasedClock AudioClock { get; set; }
|
||||
|
||||
private Receptor receptor;
|
||||
|
||||
public Receptor GetReceptor()
|
||||
|
17
osu.Game/Screens/Play/KeyCounterState.cs
Normal file
17
osu.Game/Screens/Play/KeyCounterState.cs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class KeyCounterState
|
||||
{
|
||||
public KeyCounterState(double time, int count)
|
||||
{
|
||||
Time = time;
|
||||
Count = count;
|
||||
}
|
||||
|
||||
public readonly double Time;
|
||||
public readonly int Count;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user