1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 09:22:54 +08:00

Merge pull request #1142 from peppy/taiko-actions

Add key binding support to taiko
This commit is contained in:
Dan Balasescu 2017-08-21 00:32:21 +09:00 committed by GitHub
commit aa5afc30ef
17 changed files with 106 additions and 85 deletions

View File

@ -16,6 +16,8 @@ using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps;
using osu.Desktop.Tests.Beatmaps;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
namespace osu.Desktop.Tests.Visual
@ -30,10 +32,11 @@ namespace osu.Desktop.Tests.Visual
protected override double TimePerAction => default_duration * 2;
private readonly Random rng = new Random(1337);
private readonly TaikoRulesetContainer rulesetContainer;
private readonly Container playfieldContainer;
private TaikoRulesetContainer rulesetContainer;
private Container playfieldContainer;
public TestCaseTaikoPlayfield()
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
AddStep("Hit!", () => addHitJudgement(false));
AddStep("Kiai hit", () => addHitJudgement(true));
@ -82,7 +85,7 @@ namespace osu.Desktop.Tests.Visual
RelativeSizeAxes = Axes.X,
Height = 768,
Clock = new FramedClock(rateAdjustClock),
Children = new[] { rulesetContainer = new TaikoRulesetContainer(null, beatmap, true) }
Children = new[] { rulesetContainer = new TaikoRulesetContainer(rulesets.GetRuleset(1).CreateInstance(), beatmap, true) }
});
}

View File

@ -29,8 +29,8 @@ namespace osu.Game.Rulesets.Osu
{
new KeyBinding(InputKey.Z, OsuAction.LeftButton),
new KeyBinding(InputKey.X, OsuAction.RightButton),
new KeyBinding(InputKey.LastKey + 1, OsuAction.LeftButton),
new KeyBinding(InputKey.LastKey + 2, OsuAction.RightButton),
new KeyBinding(InputKey.MouseLeft, OsuAction.LeftButton),
new KeyBinding(InputKey.MouseRight, OsuAction.RightButton),
};
public override IEnumerable<BeatmapStatistic> GetBeatmapStatistics(WorkingBeatmap beatmap) => new[]

View File

@ -4,13 +4,12 @@
using osu.Framework.Allocation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableCentreHit : DrawableHit
{
protected override Key[] HitKeys { get; } = { Key.F, Key.J };
protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre };
public DrawableCentreHit(Hit hit)
: base(hit)

View File

@ -4,13 +4,12 @@
using osu.Framework.Allocation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableCentreHitStrong : DrawableHitStrong
{
protected override Key[] HitKeys { get; } = { Key.F, Key.J };
protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre };
public DrawableCentreHitStrong(Hit hit)
: base(hit)

View File

@ -56,6 +56,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece();
public override bool OnPressed(TaikoAction action) => false;
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{

View File

@ -5,7 +5,6 @@ using System;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Judgements;
using OpenTK.Input;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
@ -59,7 +58,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
}
protected override bool HandleKeyPress(Key key)
public override bool OnPressed(TaikoAction action)
{
return Judgement.Result == HitResult.None && UpdateJudgement(true);
}

View File

@ -7,7 +7,6 @@ using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
@ -16,7 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
/// <summary>
/// A list of keys which can result in hits for this HitObject.
/// </summary>
protected abstract Key[] HitKeys { get; }
protected abstract TaikoAction[] HitActions { get; }
/// <summary>
/// Whether the last key pressed is a valid hit key.
@ -62,12 +61,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Judgement.Result = HitResult.Miss;
}
protected override bool HandleKeyPress(Key key)
public override bool OnPressed(TaikoAction action)
{
if (Judgement.Result != HitResult.None)
return false;
validKeyPressed = HitKeys.Contains(key);
validKeyPressed = HitActions.Contains(action);
return UpdateJudgement(true);
}

View File

@ -3,10 +3,8 @@
using System;
using System.Linq;
using osu.Framework.Input;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Judgements;
using OpenTK.Input;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
private double firstHitTime;
private bool firstKeyHeld;
private Key firstHitKey;
private TaikoAction firstHitAction;
protected DrawableHitStrong(Hit hit)
: base(hit)
@ -46,18 +44,26 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Judgement.SecondHit = true;
}
protected override bool HandleKeyPress(Key key)
public override bool OnReleased(TaikoAction action)
{
if (action == firstHitAction)
firstKeyHeld = false;
return base.OnReleased(action);
}
public override bool OnPressed(TaikoAction action)
{
// Check if we've handled the first key
if (Judgement.Result == HitResult.None)
{
// First key hasn't been handled yet, attempt to handle it
bool handled = base.HandleKeyPress(key);
bool handled = base.OnPressed(action);
if (handled)
{
firstHitTime = Time.Current;
firstHitKey = key;
firstHitAction = action;
firstKeyHeld = true;
}
return handled;
@ -68,22 +74,15 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
return false;
// Don't handle represses of the first key
if (firstHitKey == key)
if (firstHitAction == action)
return false;
// Don't handle invalid hit key presses
if (!HitKeys.Contains(key))
// Don't handle invalid hit action presses
if (!HitActions.Contains(action))
return false;
// Assume the intention was to hit the strong hit with both keys only if the first key is still being held down
return firstKeyHeld && UpdateJudgement(true);
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
firstKeyHeld = state.Keyboard.Keys.Contains(firstHitKey);
return base.OnKeyDown(state, args);
}
}
}

View File

@ -4,13 +4,12 @@
using osu.Framework.Allocation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableRimHit : DrawableHit
{
protected override Key[] HitKeys { get; } = { Key.D, Key.K };
protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftRim, TaikoAction.RightRim };
public DrawableRimHit(Hit hit)
: base(hit)

View File

@ -4,13 +4,12 @@
using osu.Framework.Allocation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableRimHitStrong : DrawableHitStrong
{
protected override Key[] HitKeys { get; } = { Key.D, Key.K };
protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftRim, TaikoAction.RightRim };
public DrawableRimHitStrong(Hit hit)
: base(hit)

View File

@ -13,7 +13,6 @@ using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
using osu.Framework.Graphics.Shapes;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
@ -35,9 +34,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
private readonly CircularContainer targetRing;
private readonly CircularContainer expandingRing;
private readonly Key[] rimKeys = { Key.D, Key.K };
private readonly Key[] centreKeys = { Key.F, Key.J };
private Key[] lastKeySet;
private readonly TaikoAction[] rimActions = { TaikoAction.LeftRim, TaikoAction.RightRim };
private readonly TaikoAction[] centreActions = { TaikoAction.LeftCentre, TaikoAction.RightCentre };
private TaikoAction[] lastAction;
/// <summary>
/// The amount of times the user has hit this swell.
@ -211,8 +210,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
}
protected override bool HandleKeyPress(Key key)
public override bool OnPressed(TaikoAction action)
{
if (Judgement.Result != HitResult.None)
return false;
@ -222,12 +220,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
return false;
// Find the keyset which this key corresponds to
var keySet = rimKeys.Contains(key) ? rimKeys : centreKeys;
var keySet = rimActions.Contains(action) ? rimActions : centreActions;
// Ensure alternating keysets
if (keySet == lastKeySet)
if (keySet == lastAction)
return false;
lastKeySet = keySet;
lastAction = keySet;
UpdateJudgement(true);

View File

@ -1,26 +1,19 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK;
using OpenTK.Input;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public abstract class DrawableTaikoHitObject<TaikoHitType> : DrawableScrollingHitObject<TaikoHitObject, TaikoJudgement>
where TaikoHitType : TaikoHitObject
public abstract class DrawableTaikoHitObject<TaikoHitType>
: DrawableScrollingHitObject<TaikoHitObject, TaikoJudgement>, IKeyBindingHandler<TaikoAction>
where TaikoHitType : TaikoHitObject
{
/// <summary>
/// A list of keys which this hit object will accept. These are the standard Taiko keys for now.
/// These should be moved to bindings later.
/// </summary>
private readonly List<Key> validKeys = new List<Key>(new[] { Key.D, Key.F, Key.J, Key.K });
public override Vector2 OriginPosition => new Vector2(DrawHeight / 2);
protected readonly TaikoPiece MainPiece;
@ -46,20 +39,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
protected virtual bool HandleKeyPress(Key key) => false;
public abstract bool OnPressed(TaikoAction action);
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
// Make sure we don't handle held-down keys
if (args.Repeat)
return false;
// Check if we've pressed a valid taiko key
if (!validKeys.Contains(args.Key))
return false;
// Handle it!
return HandleKeyPress(args.Key);
}
public virtual bool OnReleased(TaikoAction action) => false;
}
}

View File

@ -0,0 +1,29 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
namespace osu.Game.Rulesets.Taiko
{
public class TaikoInputManager : DatabasedKeyBindingInputManager<TaikoAction>
{
public TaikoInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique)
{
}
}
public enum TaikoAction
{
[Description("Left (Rim)")]
LeftRim,
[Description("Left (Centre)")]
LeftCentre,
[Description("Right (Centre)")]
RightCentre,
[Description("Right (Rim)")]
RightRim
}
}

View File

@ -13,6 +13,7 @@ using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Scoring;
using osu.Framework.Input.Bindings;
namespace osu.Game.Rulesets.Taiko
{
@ -20,6 +21,18 @@ namespace osu.Game.Rulesets.Taiko
{
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoRulesetContainer(this, beatmap, isForCurrentRuleset);
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
{
new KeyBinding(InputKey.D, TaikoAction.LeftRim),
new KeyBinding(InputKey.F, TaikoAction.LeftCentre),
new KeyBinding(InputKey.J, TaikoAction.RightCentre),
new KeyBinding(InputKey.K, TaikoAction.RightRim),
new KeyBinding(InputKey.MouseLeft, TaikoAction.LeftCentre),
new KeyBinding(InputKey.MouseLeft, TaikoAction.RightCentre),
new KeyBinding(InputKey.MouseRight, TaikoAction.LeftRim),
new KeyBinding(InputKey.MouseRight, TaikoAction.RightRim),
};
public override IEnumerable<Mod> GetModsFor(ModType type)
{
switch (type)

View File

@ -3,13 +3,12 @@
using System;
using OpenTK;
using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Taiko.UI
@ -36,8 +35,8 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.X,
X = -middle_split / 2,
RimKey = Key.D,
CentreKey = Key.F
RimAction = TaikoAction.LeftRim,
CentreAction = TaikoAction.LeftCentre
},
new TaikoHalfDrum(true)
{
@ -47,8 +46,8 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.X,
X = middle_split / 2,
RimKey = Key.K,
CentreKey = Key.J
RimAction = TaikoAction.RightRim,
CentreAction = TaikoAction.RightCentre
}
};
}
@ -56,17 +55,17 @@ namespace osu.Game.Rulesets.Taiko.UI
/// <summary>
/// A half-drum. Contains one centre and one rim hit.
/// </summary>
private class TaikoHalfDrum : Container
private class TaikoHalfDrum : Container, IKeyBindingHandler<TaikoAction>
{
/// <summary>
/// The key to be used for the rim of the half-drum.
/// </summary>
public Key RimKey;
public TaikoAction RimAction;
/// <summary>
/// The key to be used for the centre of the half-drum.
/// </summary>
public Key CentreKey;
public TaikoAction CentreAction;
private readonly Sprite rim;
private readonly Sprite rimHit;
@ -124,20 +123,17 @@ namespace osu.Game.Rulesets.Taiko.UI
centreHit.Colour = colours.Pink;
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
public bool OnPressed(TaikoAction action)
{
if (args.Repeat)
return false;
Drawable target = null;
Drawable back = null;
if (args.Key == CentreKey)
if (action == CentreAction)
{
target = centreHit;
back = centre;
}
else if (args.Key == RimKey)
else if (action == RimAction)
{
target = rimHit;
back = rim;
@ -166,6 +162,8 @@ namespace osu.Game.Rulesets.Taiko.UI
return false;
}
public bool OnReleased(TaikoAction action) => false;
}
}
}

View File

@ -18,6 +18,7 @@ using osu.Game.Rulesets.Taiko.Replays;
using OpenTK;
using osu.Game.Rulesets.Beatmaps;
using System.Linq;
using osu.Framework.Input;
namespace osu.Game.Rulesets.Taiko.UI
{
@ -92,6 +93,8 @@ namespace osu.Game.Rulesets.Taiko.UI
protected override BeatmapConverter<TaikoHitObject> CreateBeatmapConverter() => new TaikoBeatmapConverter();
public override PassThroughInputManager CreateKeyBindingInputManager() => new TaikoInputManager(Ruleset?.RulesetInfo);
protected override Playfield<TaikoHitObject, TaikoJudgement> CreatePlayfield() => new TaikoPlayfield
{
Anchor = Anchor.CentreLeft,

View File

@ -86,6 +86,7 @@
<Compile Include="TaikoDifficultyCalculator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Scoring\TaikoScoreProcessor.cs" />
<Compile Include="TaikoInputManager.cs" />
<Compile Include="UI\HitTarget.cs" />
<Compile Include="UI\InputDrum.cs" />
<Compile Include="UI\KiaiHitExplosion.cs" />