Skip to content

Commit

Permalink
Merge pull request #564 from smoogipooo/taiko_drumroll_drawing
Browse files Browse the repository at this point in the history
Taiko drumroll drawing
  • Loading branch information
peppy authored Apr 3, 2017
2 parents 0e52bea + 8ae4d0f commit b8dbc69
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 49 deletions.
39 changes: 14 additions & 25 deletions osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// 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.Linq;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;

namespace osu.Desktop.VisualTests.Tests
Expand All @@ -24,7 +23,7 @@ public override void Reset()
AddToggleStep("Kiai", b =>
{
kiai = !kiai;
Reset();
updateKiaiState();
});

Add(new CirclePiece
Expand Down Expand Up @@ -87,37 +86,27 @@ public override void Reset()
}
});

Add(new DrumRollCircle(new CirclePiece
{
KiaiMode = kiai
})
Add(new CirclePiece
{
Width = 250,
Position = new Vector2(575, 100)
Position = new Vector2(575, 100),
Width = 0.25f,
AccentColour = Color4.Orange,
KiaiMode = kiai,
});

Add(new DrumRollCircle(new StrongCirclePiece
Add(new StrongCirclePiece
{
Position = new Vector2(575, 300),
Width = 0.25f,
AccentColour = Color4.Orange,
KiaiMode = kiai
})
{
Width = 250,
Position = new Vector2(575, 300)
});
}

private class DrumRollCircle : BaseCircle
private void updateKiaiState()
{
public DrumRollCircle(CirclePiece piece)
: base(piece)
{
}

[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Piece.AccentColour = colours.YellowDark;
}
foreach (var c in Children.OfType<CirclePiece>())
c.KiaiMode = kiai;
}

private abstract class BaseCircle : Container
Expand Down
16 changes: 14 additions & 2 deletions osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.MathUtils;
using osu.Framework.Testing;
using osu.Game.Modes.Objects.Drawables;
Expand All @@ -26,6 +25,8 @@ public override void Reset()

AddStep("Hit!", addHitJudgement);
AddStep("Miss :(", addMissJudgement);
AddStep("DrumRoll", () => addDrumRoll(false));
AddStep("Strong DrumRoll", () => addDrumRoll(true));
AddStep("Swell", addSwell);
AddStep("Centre", () => addCentreHit(false));
AddStep("Strong Centre", () => addCentreHit(true));
Expand All @@ -36,7 +37,6 @@ public override void Reset()
{
RelativeSizeAxes = Axes.X,
Y = 200,
Padding = new MarginPadding { Left = 200 },
Children = new[]
{
playfield = new TaikoPlayfield()
Expand Down Expand Up @@ -73,6 +73,18 @@ private void addMissJudgement()
});
}

private void addDrumRoll(bool strong)
{
var d = new DrumRoll
{
StartTime = Time.Current + 1000,
Distance = 20000,
PreEmpt = 1000,
};

playfield.Add(strong ? new DrawableStrongDrumRoll(d) : new DrawableDrumRoll(d));
}

private void addSwell()
{
playfield.Add(new DrawableSwell(new Swell
Expand Down
68 changes: 63 additions & 5 deletions osu.Game.Modes.Taiko/Objects/Drawable/DrawableDrumRoll.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,90 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.MathUtils;
using osu.Game.Graphics;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Judgements;
using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;
using System.Linq;

namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public class DrawableDrumRoll : DrawableTaikoHitObject
{
/// <summary>
/// Number of rolling hits required to reach the dark/final accent colour.
/// </summary>
private const int rolling_hits_for_dark_accent = 5;

private readonly DrumRoll drumRoll;

private readonly CirclePiece circle;

private Color4 accentDarkColour;

/// <summary>
/// Rolling number of tick hits. This increases for hits and decreases for misses.
/// </summary>
private int rollingHits;

public DrawableDrumRoll(DrumRoll drumRoll)
: base(drumRoll)
{
this.drumRoll = drumRoll;

int tickIndex = 0;
RelativeSizeAxes = Axes.X;
Width = (float)(drumRoll.Duration / drumRoll.PreEmpt);

Add(circle = CreateCirclePiece());

foreach (var tick in drumRoll.Ticks)
{
var newTick = new DrawableDrumRollTick(tick)
{
Depth = tickIndex,
X = (float)((tick.StartTime - HitObject.StartTime) / drumRoll.Duration)
};

AddNested(newTick);
newTick.OnJudgement += onTickJudgement;

tickIndex++;
AddNested(newTick);
Add(newTick);
}
}

protected override void UpdateState(ArmedState state)
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
circle.AccentColour = AccentColour = colours.YellowDark;
accentDarkColour = colours.YellowDarker;
}

protected override void LoadComplete()
{
base.LoadComplete();

// This is naive, however it's based on the reasoning that the hit target
// is further than mid point of the play field, so the time taken to scroll in should always
// be greater than the time taken to scroll out to the left of the screen.
// Thus, using PreEmpt here is enough for the drum roll to completely scroll out.
LifetimeEnd = drumRoll.EndTime + drumRoll.PreEmpt;
}

private void onTickJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> obj)
{
if (obj.Judgement.Result == HitResult.Hit)
rollingHits++;
else
rollingHits--;

rollingHits = MathHelper.Clamp(rollingHits, 0, rolling_hits_for_dark_accent);

Color4 newAccent = Interpolation.ValueAt((float)rollingHits / rolling_hits_for_dark_accent, AccentColour, accentDarkColour, 0, 1);
circle.FadeAccent(newAccent, 100);
}

protected override void CheckJudgement(bool userTriggered)
Expand All @@ -53,5 +105,11 @@ protected override void CheckJudgement(bool userTriggered)
else
Judgement.Result = HitResult.Miss;
}

protected override void UpdateState(ArmedState state)
{
}

protected virtual CirclePiece CreateCirclePiece() => new CirclePiece();
}
}
56 changes: 54 additions & 2 deletions osu.Game.Modes.Taiko/Objects/Drawable/DrawableDrumRollTick.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,66 @@
using osu.Game.Modes.Taiko.Judgements;
using System;
using osu.Game.Modes.Objects.Drawables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Sprites;

namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public class DrawableDrumRollTick : DrawableTaikoHitObject
{
/// <summary>
/// The size of a tick.
/// </summary>
private const float tick_size = TaikoHitObject.CIRCLE_RADIUS / 2;

/// <summary>
/// Any tick that is not the first for a drumroll is not filled, but is instead displayed
/// as a hollow circle. This is what controls the border width of that circle.
/// </summary>
private const float tick_border_width = tick_size / 4;

private readonly DrumRollTick tick;

private readonly CircularContainer bodyContainer;

public DrawableDrumRollTick(DrumRollTick tick)
: base(tick)
{
this.tick = tick;

Anchor = Anchor.CentreLeft;
Origin = Anchor.Centre;

RelativePositionAxes = Axes.X;
Size = new Vector2(tick_size);

Children = new[]
{
bodyContainer = new CircularContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = tick_border_width,
BorderColour = Color4.White,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = tick.FirstTick ? 1 : 0,
AlwaysPresent = true
}
}
}
};
}

protected override TaikoJudgement CreateJudgement() => new TaikoDrumRollTickJudgement();
protected override TaikoJudgement CreateJudgement() => new TaikoDrumRollTickJudgement { SecondHit = tick.IsStrong };

protected override void CheckJudgement(bool userTriggered)
{
Expand All @@ -38,11 +84,17 @@ protected override void CheckJudgement(bool userTriggered)

protected override void UpdateState(ArmedState state)
{
switch (state)
{
case ArmedState.Hit:
bodyContainer.ScaleTo(0, 100, EasingTypes.OutQuint);
break;
}
}

protected override void UpdateScrollPosition(double time)
{
// Drum roll ticks shouldn't move
// Ticks don't move
}

protected override bool HandleKeyPress(Key key)
Expand Down
20 changes: 20 additions & 0 deletions osu.Game.Modes.Taiko/Objects/Drawable/DrawableStrongDrumRoll.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using osu.Game.Modes.Taiko.Judgements;
using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;

namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public class DrawableStrongDrumRoll : DrawableDrumRoll
{
public DrawableStrongDrumRoll(DrumRoll drumRoll)
: base(drumRoll)
{
}

protected override TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = true };

protected override CirclePiece CreateCirclePiece() => new StrongCirclePiece();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ protected DrawableTaikoHitObject(TaikoHitObject hitObject)
: base(hitObject)
{
Anchor = Anchor.CentreLeft;
Origin = Anchor.Centre;
Origin = Anchor.CentreLeft;

RelativePositionAxes = Axes.X;
}
Expand Down
Loading

0 comments on commit b8dbc69

Please sign in to comment.