diff --git a/osu-resources b/osu-resources index f85c594c18..00406e13d1 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit f85c594c182db2b01233e29ca52639b7baa00402 +Subproject commit 00406e13d1b15683b3565a126e207b08bca7555f diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs new file mode 100644 index 0000000000..ebe3800af4 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs @@ -0,0 +1,63 @@ +// 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 osu.Framework.Screens.Testing; +using osu.Game.Modes.Taiko.Objects.Drawable.Pieces; + +namespace osu.Desktop.VisualTests.Tests +{ + internal class TestCaseTaikoHitObjects : TestCase + { + public override string Description => "Taiko hit objects"; + + public override void Reset() + { + base.Reset(); + + Add(new CentreHitCirclePiece + { + Position = new Vector2(100, 100) + }); + + Add(new FinisherPiece(new CentreHitCirclePiece()) + { + Position = new Vector2(350, 100) + }); + + Add(new RimHitCirclePiece + { + Position = new Vector2(100, 300) + }); + + Add(new FinisherPiece(new RimHitCirclePiece()) + { + Position = new Vector2(350, 300) + }); + + Add(new BashCirclePiece + { + Position = new Vector2(100, 500) + }); + + Add(new FinisherPiece(new BashCirclePiece()) + { + Position = new Vector2(350, 500) + }); + + Add(new DrumRollCirclePiece + { + Width = 250, + Position = new Vector2(575, 100) + }); + + Add(new FinisherPiece(new DrumRollCirclePiece() + { + Width = 250 + }) + { + Position = new Vector2(575, 300) + }); + } + } +} diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 68aed38b34..28ca0655cc 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -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> @@ -194,6 +194,7 @@ <Compile Include="Tests\TestCaseReplay.cs" /> <Compile Include="Tests\TestCaseScoreCounter.cs" /> <Compile Include="Tests\TestCaseTabControl.cs" /> + <Compile Include="Tests\TestCaseTaikoHitObjects.cs" /> <Compile Include="Tests\TestCaseTextAwesome.cs" /> <Compile Include="Tests\TestCasePlaySongSelect.cs" /> <Compile Include="Tests\TestCaseTwoLayerButton.cs" /> diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/BashCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/BashCirclePiece.cs new file mode 100644 index 0000000000..8298c5a871 --- /dev/null +++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/BashCirclePiece.cs @@ -0,0 +1,36 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Graphics; + +namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces +{ + /// <summary> + /// A circle piece which is used to visualise Bash objects. + /// </summary> + public class BashCirclePiece : CirclePiece + { + private Sprite icon; + + [BackgroundDependencyLoader] + private void load(OsuColour colours, TextureStore textures) + { + AccentColour = colours.YellowDark; + + icon.Texture = textures.Get(@"Play/Taiko/bash-hit-inner"); + } + + protected override Framework.Graphics.Drawable CreateIcon() + { + return icon = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; + } + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CentreHitCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CentreHitCirclePiece.cs new file mode 100644 index 0000000000..922e377ef5 --- /dev/null +++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CentreHitCirclePiece.cs @@ -0,0 +1,45 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using OpenTK; + +namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces +{ + /// <summary> + /// A circle piece which is used to visualise CentreHit objects. + /// </summary> + public class CentreHitCirclePiece : CirclePiece + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.PinkDarker; + } + + protected override Framework.Graphics.Drawable CreateIcon() + { + return new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + + Size = new Vector2(45f), + + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + + Alpha = 1 + } + } + }; + } + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CirclePiece.cs new file mode 100644 index 0000000000..20971cb84d --- /dev/null +++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CirclePiece.cs @@ -0,0 +1,204 @@ +// 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics.Backgrounds; +using OpenTK.Graphics; +using OpenTK; + +namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces +{ + /// <summary> + /// A circle piece which is used uniformly through osu!taiko to visualise hitobjects. + /// <para> + /// The body of this piece will overshoot it by Height/2 on both sides of its length, such that + /// a regular "circle" the result of setting Width to 0. + /// </para> + /// <para> + /// Hitobjects that have a length need only to set Width and the extra corner radius will be added internally. + /// </para> + /// </summary> + public abstract class CirclePiece : ScrollingCirclePiece + { + /// <summary> + /// The colour of the inner circle and outer glows. + /// </summary> + public Color4 AccentColour { get; protected set; } + + private bool kiaiMode; + /// <summary> + /// Whether Kiai mode is active for this object. + /// </summary> + public bool KiaiMode + { + get { return kiaiMode; } + set + { + kiaiMode = value; + + if (innerCircleContainer != null) + innerCircleContainer.EdgeEffect = value ? createKiaiEdgeEffect() : default(EdgeEffect); + } + } + + public override Vector2 Size => new Vector2(base.Size.X, 128); + + private Container innerLayer; + private Container backingGlowContainer; + private Container innerCircleContainer; + private Box innerBackground; + private Triangles triangles; + + protected CirclePiece() + { + Container iconContainer; + + Children = new Framework.Graphics.Drawable[] + { + // The "inner layer" overshoots the ObjectPiece by 64px on both sides + innerLayer = new Container + { + Name = "Inner Layer", + + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + + RelativeSizeAxes = Axes.Y, + + Children = new Framework.Graphics.Drawable[] + { + backingGlowContainer = new CircularContainer + { + Name = "Backing Glow", + + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + + RelativeSizeAxes = Axes.Both, + + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + + Alpha = 0, + AlwaysPresent = true + } + } + }, + innerCircleContainer = new CircularContainer + { + Name = "Inner Circle", + + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + + RelativeSizeAxes = Axes.Both, + + Children = new Framework.Graphics.Drawable[] + { + innerBackground = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + + RelativeSizeAxes = Axes.Both, + }, + triangles = new Triangles + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + + RelativeSizeAxes = Axes.Both, + } + } + }, + new CircularContainer + { + Name = "Ring", + + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + + RelativeSizeAxes = Axes.Both, + + BorderThickness = 8, + BorderColour = Color4.White, + + Children = new[] + { + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + + RelativeSizeAxes = Axes.Both, + + Alpha = 0, + AlwaysPresent = true + } + } + }, + iconContainer = new Container + { + Name = "Icon Container", + + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + } + }, + }; + + Framework.Graphics.Drawable icon = CreateIcon(); + + if (icon != null) + iconContainer.Add(icon); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + backingGlowContainer.EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Glow, + Colour = AccentColour, + Radius = 8 + }; + + if (KiaiMode) + innerCircleContainer.EdgeEffect = createKiaiEdgeEffect(); + + innerBackground.Colour = AccentColour; + + triangles.ColourLight = AccentColour; + triangles.ColourDark = AccentColour.Darken(0.1f); + } + + protected override void Update() + { + innerLayer.Width = DrawWidth + DrawHeight; + } + + private EdgeEffect createKiaiEdgeEffect() + { + return new EdgeEffect + { + Type = EdgeEffectType.Glow, + Colour = AccentColour, + Radius = 50 + }; + } + + /// <summary> + /// Creates the icon that's shown in the middle of this object piece. + /// </summary> + /// <returns>The icon.</returns> + protected virtual Framework.Graphics.Drawable CreateIcon() => null; + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/DrumRollCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/DrumRollCirclePiece.cs new file mode 100644 index 0000000000..fea538d654 --- /dev/null +++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/DrumRollCirclePiece.cs @@ -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.Framework.Allocation; +using osu.Game.Graphics; + +namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces +{ + /// <summary> + /// A circle piece which is used to visualise DrumRoll objects. + /// </summary> + public class DrumRollCirclePiece : CirclePiece + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.YellowDark; + } + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/FinisherPiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/FinisherPiece.cs new file mode 100644 index 0000000000..699bac0bd0 --- /dev/null +++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/FinisherPiece.cs @@ -0,0 +1,31 @@ +// 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; + +namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces +{ + /// <summary> + /// A type of circle piece that encapsulates a circle piece to visualise it as a "finisher" hitobject. + /// <para> + /// Finisher hitobjects are 1.5x larger, while maintaining the same length. + /// </para> + /// </summary> + public class FinisherPiece : ScrollingCirclePiece + { + public FinisherPiece(ScrollingCirclePiece original) + { + // First we scale the note up + Scale = new Vector2(1.5f); + + Children = new[] + { + original + }; + + // Next we reduce the draw width for drum rolls to keep the width + // equal to that of a non-finisher drum roll + original.Width /= 1.5f; + } + } +} diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/RimHitCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/RimHitCirclePiece.cs new file mode 100644 index 0000000000..5f1c767063 --- /dev/null +++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/RimHitCirclePiece.cs @@ -0,0 +1,50 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces +{ + /// <summary> + /// A circle piece which is used to visualise RimHit objects. + /// </summary> + public class RimHitCirclePiece : CirclePiece + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.BlueDarker; + } + + protected override Framework.Graphics.Drawable CreateIcon() + { + return new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + + Size = new Vector2(61f), + + BorderThickness = 8, + BorderColour = Color4.White, + + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + + Alpha = 0, + AlwaysPresent = true + } + } + }; + } + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/ScrollingCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/ScrollingCirclePiece.cs new file mode 100644 index 0000000000..413fc55e80 --- /dev/null +++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/ScrollingCirclePiece.cs @@ -0,0 +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 osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces +{ + /// <summary> + /// A type of circle piece that will be scrolling the screen. + /// <para> + /// A scrolling circle piece must always have a centre-left origin due to how scroll position is calculated. + /// </para> + /// </summary> + public class ScrollingCirclePiece : Container + { + public override Anchor Origin => Anchor.CentreLeft; + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj index 7ea6dfeadb..81fb35be60 100644 --- a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj +++ b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj @@ -50,6 +50,13 @@ <Compile Include="Beatmaps\TaikoBeatmapConverter.cs" /> <Compile Include="Beatmaps\TaikoBeatmapProcessor.cs" /> <Compile Include="Judgements\TaikoJudgementInfo.cs" /> + <Compile Include="Objects\Drawable\Pieces\BashCirclePiece.cs" /> + <Compile Include="Objects\Drawable\Pieces\CentreHitCirclePiece.cs" /> + <Compile Include="Objects\Drawable\Pieces\CirclePiece.cs" /> + <Compile Include="Objects\Drawable\Pieces\DrumRollCirclePiece.cs" /> + <Compile Include="Objects\Drawable\Pieces\FinisherPiece.cs" /> + <Compile Include="Objects\Drawable\Pieces\RimHitCirclePiece.cs" /> + <Compile Include="Objects\Drawable\Pieces\ScrollingCirclePiece.cs" /> <Compile Include="TaikoDifficultyCalculator.cs" /> <Compile Include="Objects\Drawable\DrawableTaikoHit.cs" /> <Compile Include="Objects\TaikoHitObject.cs" /> @@ -81,6 +88,7 @@ <Name>osu.Game</Name> </ProjectReference> </ItemGroup> + <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.