Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Taiko Playfield Implementation #517

Merged
merged 38 commits into from
Mar 23, 2017
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
58be454
Late-add the HitObjects container in the Playfield.
smoogipoo Mar 21, 2017
27a21cd
Add taiko playfield.
smoogipoo Mar 21, 2017
10ed6ef
Move TaikoPlayfield to separate file.
smoogipoo Mar 21, 2017
9b5cb7e
Merge branch 'taiko_judgement_scoring' into taiko_playfield_2
smoogipoo Mar 21, 2017
4c398b1
Add explosion rings.
smoogipoo Mar 21, 2017
1ac9898
Add judgement texts.
smoogipoo Mar 21, 2017
4e7a44c
Add license + general fixes.
smoogipoo Mar 21, 2017
eec4a1b
Redesign HitTarget.
smoogipoo Mar 21, 2017
60e866a
Increase RingExplosion base size for finishers.
smoogipoo Mar 21, 2017
2cfab75
Remove now unnecessary field.
smoogipoo Mar 21, 2017
aac4f24
10% chance to get finisher hits in testcase.
smoogipoo Mar 21, 2017
7cb2377
Add a 1px offset for the playfield border.
smoogipoo Mar 21, 2017
e2b510f
Add comments.
smoogipoo Mar 21, 2017
259ed03
Reduce some container nesting.
smoogipoo Mar 21, 2017
afcd42b
Merge remote-tracking branch 'origin/master' into taiko_playfield_2
smoogipoo Mar 21, 2017
b769c43
Update framework.
smoogipoo Mar 21, 2017
e7a9307
Fix post-merge errors.
smoogipoo Mar 21, 2017
8f6cee2
Override is unnecessary.
smoogipoo Mar 21, 2017
790997d
Merge remote-tracking branch 'origin/master' into taiko_playfield_2
smoogipoo Mar 22, 2017
9c325dd
Cleanups + fix CircularContainer usages.
smoogipoo Mar 23, 2017
2c580f4
Merge branch 'master' into taiko_playfield_2
smoogipoo Mar 23, 2017
8b71d70
Add a way to get the score string from JugementInfo.
smoogipoo Mar 23, 2017
c9fe9e6
Make judgement text generic to be used between game modes.
smoogipoo Mar 23, 2017
39ff026
Reimplement JudgementText with the new DrawableJudgementInfo.
smoogipoo Mar 23, 2017
7f33e10
Renaming + don't use List.
smoogipoo Mar 23, 2017
00054f1
Comment out unused container for now.
smoogipoo Mar 23, 2017
cedcab1
s/Ring/Hit + privatize Judgement inside RingExplosion.
smoogipoo Mar 23, 2017
aa2b22f
Fix usings.
smoogipoo Mar 23, 2017
8e1eef2
Fix some lone newlines.
smoogipoo Mar 23, 2017
d441114
Merge branch 'master' into taiko_playfield_2
peppy Mar 23, 2017
9a3fd8b
Add readonly attributes.
peppy Mar 23, 2017
acfa4a4
JudgementText -> DrawableTaikoJudgementInfo.
peppy Mar 23, 2017
02fba00
Tidy up and tweak transitions of DrawableJudgementInfo.
peppy Mar 23, 2017
b83db18
HitExplosion -> DrawableOsuJudgementInfo.
peppy Mar 23, 2017
1af17fc
Remove cross-reference to osu.Game.Modes.Osu from Taiko.
peppy Mar 23, 2017
ef8830a
Adjust InputDrum's appearance a touch.
peppy Mar 23, 2017
ebb64e0
Add constant for HitTarget line thickness and make slightly thicker (…
peppy Mar 23, 2017
0863efb
Remove unused variable.
peppy Mar 23, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// 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.Framework.MathUtils;
using osu.Framework.Screens.Testing;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Judgements;
using osu.Game.Modes.Taiko.Objects;
using osu.Game.Modes.Taiko.UI;

namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseTaikoPlayfield : TestCase
{
public override string Description => "Taiko playfield";

private TaikoPlayfield playfield;

public override void Reset()
{
base.Reset();

AddButton("Hit!", addHitJudgement);
AddButton("Miss :(", addMissJudgement);

Add(playfield = new TaikoPlayfield
{
Y = 200
});
}

private void addHitJudgement()
{
TaikoHitResult hitResult = RNG.Next(2) == 0 ? TaikoHitResult.Good : TaikoHitResult.Great;

playfield.OnJudgement(new DrawableTestHit(new TaikoHitObject())
{
X = RNG.NextSingle(hitResult == TaikoHitResult.Good ? -0.1f : -0.05f, hitResult == TaikoHitResult.Good ? 0.1f : 0.05f),
Judgement = new TaikoJudgementInfo
{
Result = HitResult.Hit,
TaikoResult = hitResult,
TimeOffset = 0,
ComboAtHit = 1,
SecondHit = RNG.Next(10) == 0
}
});
}

private void addMissJudgement()
{
playfield.OnJudgement(new DrawableTestHit(new TaikoHitObject())
{
Judgement = new TaikoJudgementInfo
{
Result = HitResult.Miss,
TimeOffset = 0,
ComboAtHit = 0
}
});
}

private class DrawableTestHit : DrawableHitObject<TaikoHitObject, TaikoJudgementInfo>
{
public DrawableTestHit(TaikoHitObject hitObject)
: base(hitObject)
{
}

protected override TaikoJudgementInfo CreateJudgementInfo() => new TaikoJudgementInfo();

protected override void UpdateState(ArmedState state)
{
}
}
}
}
3 changes: 2 additions & 1 deletion osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<SignAssembly>false</SignAssembly>
<TargetZone>LocalIntranet</TargetZone>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
Expand Down Expand Up @@ -194,6 +194,7 @@
<Compile Include="Tests\TestCaseReplay.cs" />
<Compile Include="Tests\TestCaseScoreCounter.cs" />
<Compile Include="Tests\TestCaseTabControl.cs" />
<Compile Include="Tests\TestCaseTaikoPlayfield.cs" />
<Compile Include="Tests\TestCaseTextAwesome.cs" />
<Compile Include="Tests\TestCasePlaySongSelect.cs" />
<Compile Include="Tests\TestCaseTwoLayerButton.cs" />
Expand Down
100 changes: 100 additions & 0 deletions osu.Game.Modes.Taiko/UI/HitTarget.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// 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.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Modes.Taiko.Objects;

namespace osu.Game.Modes.Taiko.UI
{
/// <summary>
/// A component that is displayed at the hit position in the taiko playfield.
/// </summary>
internal class HitTarget : Container
{
/// <summary>
/// Diameter of normal hit object circles.
/// </summary>
private const float normal_diameter = TaikoHitObject.CIRCLE_RADIUS * 2 * TaikoPlayfield.PLAYFIELD_SCALE;

/// <summary>
/// Diameter of finisher hit object circles.
/// </summary>
private const float finisher_diameter = normal_diameter * 1.5f;

/// <summary>
/// The 1px inner border of the taiko playfield.
/// </summary>
private const float border_offset = 1;

This comment was marked as off-topic.


public HitTarget()
{
RelativeSizeAxes = Axes.Y;

Children = new Drawable[]
{
new Box
{
Name = "Bar Upper",
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Y = border_offset,
Size = new Vector2(3, (TaikoPlayfield.PlayfieldHeight - finisher_diameter) / 2f - border_offset),
Alpha = 0.1f
},
new CircularContainer
{
Name = "Finisher Ring",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(finisher_diameter),
Masking = true,
BorderColour = Color4.White,
BorderThickness = 2,
Alpha = 0.1f,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
}
},
new CircularContainer
{
Name = "Normal Ring",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(normal_diameter),
Masking = true,
BorderColour = Color4.White,
BorderThickness = 2,
Alpha = 0.5f,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
}
},
new Box
{
Name = "Bar Lower",
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Y = -border_offset,
Size = new Vector2(3, (TaikoPlayfield.PlayfieldHeight - finisher_diameter) / 2f - border_offset),
Alpha = 0.1f
},
};
}
}
}
139 changes: 139 additions & 0 deletions osu.Game.Modes.Taiko/UI/InputDrum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// 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.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.Graphics.Transforms;
using osu.Framework.Input;
using osu.Game.Graphics;
using System.Collections.Generic;

namespace osu.Game.Modes.Taiko.UI
{
/// <summary>
/// A component of the playfield that captures input and displays input as a drum.
/// </summary>
internal class InputDrum : Container
{
public InputDrum()
{
Size = new Vector2(TaikoPlayfield.PlayfieldHeight);

Children = new Drawable[]
{
new TaikoHalfDrum(false)
{
Name = "Left Half",
Anchor = Anchor.Centre,
Origin = Anchor.CentreRight,
RelativeSizeAxes = Axes.Both,
Keys = new List<Key>(new[] { Key.F, Key.D })
},
new TaikoHalfDrum(true)
{
Name = "Right Half",
Anchor = Anchor.Centre,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Both,
Position = new Vector2(-1f, 0),
Keys = new List<Key>(new[] { Key.J, Key.K })
}
};
}

/// <summary>
/// A half-drum. Contains one centre and one rim hit.
/// </summary>
private class TaikoHalfDrum : Container
{
/// <summary>
/// A list of keys which this half-drum accepts.
/// <para>
/// [0] => Inner key, [1] => Outer key
/// </para>
/// </summary>
public List<Key> Keys = new List<Key>();

This comment was marked as off-topic.


private Sprite outer;
private Sprite outerHit;
private Sprite inner;
private Sprite innerHit;

public TaikoHalfDrum(bool flipped)
{
Masking = true;

Children = new Drawable[]
{
outer = new Sprite
{
Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both
},
outerHit = new Sprite
{
Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Alpha = 0,
BlendingMode = BlendingMode.Additive
},
inner = new Sprite
{
Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.7f)
},
innerHit = new Sprite
{
Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.7f),
Alpha = 0,
BlendingMode = BlendingMode.Additive
}
};
}

[BackgroundDependencyLoader]
private void load(TextureStore textures, OsuColour colours)
{
outer.Texture = textures.Get(@"Play/Taiko/taiko-drum-outer");
outerHit.Texture = textures.Get(@"Play/Taiko/taiko-drum-outer-hit");
inner.Texture = textures.Get(@"Play/Taiko/taiko-drum-inner");
innerHit.Texture = textures.Get(@"Play/Taiko/taiko-drum-inner-hit");

outerHit.Colour = colours.Blue;
innerHit.Colour = colours.Pink;
}

protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
if (args.Repeat)
return false;

if (args.Key == Keys[0])
{
innerHit.FadeIn();
innerHit.FadeOut(500, EasingTypes.OutQuint);
}

if (args.Key == Keys[1])
{
outerHit.FadeIn();
outerHit.FadeOut(500, EasingTypes.OutQuint);
}

return false;
}
}
}
}
Loading