mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 23:24:04 +09:00
Move play modes to Modes namespace.
This commit is contained in:
65
osu.Game/Modes/Catch/CatchComboCounter.cs
Normal file
65
osu.Game/Modes/Catch/CatchComboCounter.cs
Normal file
@ -0,0 +1,65 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Modes.Osu;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Modes.Catch
|
||||
{
|
||||
/// <summary>
|
||||
/// Similar to Standard, but without the 'x' and has tinted pop-ups. Used in osu!catch.
|
||||
/// </summary>
|
||||
public class CatchComboCounter : OsuComboCounter
|
||||
{
|
||||
protected override bool CanPopOutWhileRolling => true;
|
||||
|
||||
protected virtual double FadeOutDelay => 1000;
|
||||
protected override double FadeOutDuration => 300;
|
||||
|
||||
protected override string FormatCount(ulong count)
|
||||
{
|
||||
return $@"{count:#,0}";
|
||||
}
|
||||
|
||||
private void animateFade()
|
||||
{
|
||||
Show();
|
||||
Delay(FadeOutDelay);
|
||||
FadeOut(FadeOutDuration);
|
||||
DelayReset();
|
||||
}
|
||||
|
||||
protected override void OnCountChange(ulong currentValue, ulong newValue)
|
||||
{
|
||||
if (newValue != 0)
|
||||
animateFade();
|
||||
base.OnCountChange(currentValue, newValue);
|
||||
}
|
||||
|
||||
protected override void OnCountRolling(ulong currentValue, ulong newValue)
|
||||
{
|
||||
if (!IsRolling)
|
||||
{
|
||||
PopOutSpriteText.Colour = DisplayedCountSpriteText.Colour;
|
||||
FadeOut(FadeOutDuration);
|
||||
}
|
||||
base.OnCountRolling(currentValue, newValue);
|
||||
}
|
||||
|
||||
protected override void OnCountIncrement(ulong currentValue, ulong newValue)
|
||||
{
|
||||
animateFade();
|
||||
base.OnCountIncrement(currentValue, newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increaces counter and tints pop-out before animation.
|
||||
/// </summary>
|
||||
/// <param name="colour">Last grabbed fruit colour.</param>
|
||||
public void CatchFruit(Color4 colour)
|
||||
{
|
||||
PopOutSpriteText.Colour = colour;
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
}
|
17
osu.Game/Modes/Catch/CatchHitRenderer.cs
Normal file
17
osu.Game/Modes/Catch/CatchHitRenderer.cs
Normal file
@ -0,0 +1,17 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Modes.Objects;
|
||||
using osu.Game.Modes.Objects.Catch;
|
||||
|
||||
namespace osu.Game.Modes.Catch
|
||||
{
|
||||
public class CatchHitRenderer : HitRenderer<CatchBaseHit>
|
||||
{
|
||||
protected override HitObjectConverter<CatchBaseHit> Converter => new CatchConverter();
|
||||
|
||||
protected override Playfield CreatePlayfield() => new CatchPlayfield();
|
||||
|
||||
protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) => null;// new DrawableFruit(h);
|
||||
}
|
||||
}
|
22
osu.Game/Modes/Catch/CatchPlayfield.cs
Normal file
22
osu.Game/Modes/Catch/CatchPlayfield.cs
Normal file
@ -0,0 +1,22 @@
|
||||
//Copyright (c) 2007-2016 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.Sprites;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Modes.Catch
|
||||
{
|
||||
public class CatchPlayfield : Playfield
|
||||
{
|
||||
public CatchPlayfield()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Size = new Vector2(512, 0.9f);
|
||||
Anchor = Anchor.BottomCentre;
|
||||
Origin = Anchor.BottomCentre;
|
||||
|
||||
Add(new Box { RelativeSizeAxes = Axes.Both, Alpha = 0.5f });
|
||||
}
|
||||
}
|
||||
}
|
16
osu.Game/Modes/Catch/CatchRuleset.cs
Normal file
16
osu.Game/Modes/Catch/CatchRuleset.cs
Normal file
@ -0,0 +1,16 @@
|
||||
//Copyright (c) 2007-2016 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.Game.Modes.Objects;
|
||||
using osu.Game.Modes.Osu;
|
||||
|
||||
namespace osu.Game.Modes.Catch
|
||||
{
|
||||
class CatchRuleset : Ruleset
|
||||
{
|
||||
public override ScoreOverlay CreateScoreOverlay() => new ScoreOverlayOsu();
|
||||
|
||||
public override HitRenderer CreateHitRendererWith(List<HitObject> objects) => new CatchHitRenderer { Objects = objects };
|
||||
}
|
||||
}
|
260
osu.Game/Modes/ComboCounter.cs
Normal file
260
osu.Game/Modes/ComboCounter.cs
Normal file
@ -0,0 +1,260 @@
|
||||
//Copyright (c) 2007-2016 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;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using osu.Framework.MathUtils;
|
||||
|
||||
namespace osu.Game.Modes
|
||||
{
|
||||
public abstract class ComboCounter : Container
|
||||
{
|
||||
public bool IsRolling
|
||||
{
|
||||
get; protected set;
|
||||
}
|
||||
|
||||
protected SpriteText PopOutSpriteText;
|
||||
|
||||
protected virtual double PopOutDuration => 150;
|
||||
protected virtual float PopOutScale => 2.0f;
|
||||
protected virtual EasingTypes PopOutEasing => EasingTypes.None;
|
||||
protected virtual float PopOutInitialAlpha => 0.75f;
|
||||
|
||||
protected virtual double FadeOutDuration => 100;
|
||||
|
||||
/// <summary>
|
||||
/// Duration in milliseconds for the counter roll-up animation for each element.
|
||||
/// </summary>
|
||||
protected virtual double RollingDuration => 20;
|
||||
|
||||
/// <summary>
|
||||
/// Easing for the counter rollover animation.
|
||||
/// </summary>
|
||||
protected EasingTypes RollingEasing => EasingTypes.None;
|
||||
|
||||
private ulong displayedCount;
|
||||
|
||||
/// <summary>
|
||||
/// Value shown at the current moment.
|
||||
/// </summary>
|
||||
public virtual ulong DisplayedCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return displayedCount;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
if (displayedCount.Equals(value))
|
||||
return;
|
||||
updateDisplayedCount(displayedCount, value, IsRolling);
|
||||
}
|
||||
}
|
||||
|
||||
protected ulong count;
|
||||
|
||||
/// <summary>
|
||||
/// Actual value of counter.
|
||||
/// </summary>
|
||||
public virtual ulong Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return count;
|
||||
}
|
||||
set
|
||||
{
|
||||
updateCount(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Increment(ulong amount = 1)
|
||||
{
|
||||
Count = Count + amount;
|
||||
}
|
||||
|
||||
protected SpriteText DisplayedCountSpriteText;
|
||||
|
||||
private float textSize;
|
||||
public float TextSize
|
||||
{
|
||||
get { return textSize; }
|
||||
set
|
||||
{
|
||||
textSize = value;
|
||||
DisplayedCountSpriteText.TextSize = TextSize;
|
||||
PopOutSpriteText.TextSize = TextSize;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base of all combo counters.
|
||||
/// </summary>
|
||||
protected ComboCounter()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
DisplayedCountSpriteText = new SpriteText
|
||||
{
|
||||
Alpha = 0,
|
||||
},
|
||||
PopOutSpriteText = new SpriteText
|
||||
{
|
||||
Alpha = 0,
|
||||
}
|
||||
};
|
||||
|
||||
TextSize = 80;
|
||||
|
||||
DisplayedCountSpriteText.Text = FormatCount(Count);
|
||||
DisplayedCountSpriteText.Anchor = Anchor;
|
||||
DisplayedCountSpriteText.Origin = Origin;
|
||||
|
||||
StopRolling();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops rollover animation, forcing the displayed count to be the actual count.
|
||||
/// </summary>
|
||||
public void StopRolling()
|
||||
{
|
||||
updateCount(Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Animates roll-back to 0.
|
||||
/// </summary>
|
||||
public void Roll()
|
||||
{
|
||||
Roll(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Animates roll-up/roll-back to an specific value.
|
||||
/// </summary>
|
||||
/// <param name="newValue">Target value.</param>
|
||||
public virtual void Roll(ulong newValue)
|
||||
{
|
||||
updateCount(newValue, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets count to default value.
|
||||
/// </summary>
|
||||
public virtual void ResetCount()
|
||||
{
|
||||
updateCount(0);
|
||||
}
|
||||
|
||||
protected virtual string FormatCount(ulong count)
|
||||
{
|
||||
return count.ToString();
|
||||
}
|
||||
|
||||
protected abstract void OnDisplayedCountRolling(ulong currentValue, ulong newValue);
|
||||
protected abstract void OnDisplayedCountIncrement(ulong newValue);
|
||||
protected abstract void OnDisplayedCountChange(ulong newValue);
|
||||
|
||||
protected virtual void OnCountRolling(ulong currentValue, ulong newValue)
|
||||
{
|
||||
transformRoll(new TransformComboRoll(), currentValue, newValue);
|
||||
}
|
||||
|
||||
protected virtual void OnCountIncrement(ulong currentValue, ulong newValue) {
|
||||
DisplayedCount = newValue;
|
||||
}
|
||||
|
||||
protected virtual void OnCountChange(ulong currentValue, ulong newValue) {
|
||||
DisplayedCount = newValue;
|
||||
}
|
||||
|
||||
private double getProportionalDuration(ulong currentValue, ulong newValue)
|
||||
{
|
||||
double difference = currentValue > newValue ? currentValue - newValue : newValue - currentValue;
|
||||
return difference * RollingDuration;
|
||||
}
|
||||
|
||||
private void updateDisplayedCount(ulong currentValue, ulong newValue, bool rolling)
|
||||
{
|
||||
displayedCount = newValue;
|
||||
if (rolling)
|
||||
OnDisplayedCountRolling(currentValue, newValue);
|
||||
else if (currentValue + 1 == newValue)
|
||||
OnDisplayedCountIncrement(newValue);
|
||||
else
|
||||
OnDisplayedCountChange(newValue);
|
||||
}
|
||||
|
||||
private void updateCount(ulong value, bool rolling = false)
|
||||
{
|
||||
count = value;
|
||||
|
||||
if (!IsLoaded)
|
||||
return;
|
||||
|
||||
ulong prevCount = count;
|
||||
|
||||
if (!rolling)
|
||||
{
|
||||
Flush(false, typeof(TransformComboRoll));
|
||||
IsRolling = false;
|
||||
DisplayedCount = prevCount;
|
||||
|
||||
if (prevCount + 1 == count)
|
||||
OnCountIncrement(prevCount, count);
|
||||
else
|
||||
OnCountChange(prevCount, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCountRolling(displayedCount, count);
|
||||
IsRolling = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void transformRoll(TransformComboRoll transform, ulong currentValue, ulong newValue)
|
||||
{
|
||||
Flush(false, typeof(TransformComboRoll));
|
||||
|
||||
if (RollingDuration < 1)
|
||||
{
|
||||
DisplayedCount = Count;
|
||||
return;
|
||||
}
|
||||
|
||||
transform.StartTime = Time.Current;
|
||||
transform.EndTime = Time.Current + getProportionalDuration(currentValue, newValue);
|
||||
transform.StartValue = currentValue;
|
||||
transform.EndValue = newValue;
|
||||
transform.Easing = RollingEasing;
|
||||
|
||||
Transforms.Add(transform);
|
||||
}
|
||||
|
||||
protected class TransformComboRoll : Transform<ulong>
|
||||
{
|
||||
protected override ulong CurrentValue
|
||||
{
|
||||
get
|
||||
{
|
||||
double time = Time?.Current ?? 0;
|
||||
if (time < StartTime) return StartValue;
|
||||
if (time >= EndTime) return EndValue;
|
||||
|
||||
return (ulong)Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(Drawable d)
|
||||
{
|
||||
base.Apply(d);
|
||||
(d as ComboCounter).DisplayedCount = CurrentValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
58
osu.Game/Modes/ComboResultCounter.cs
Normal file
58
osu.Game/Modes/ComboResultCounter.cs
Normal file
@ -0,0 +1,58 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Modes
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to display combo with a roll-up animation in results screen.
|
||||
/// </summary>
|
||||
public class ComboResultCounter : RollingCounter<ulong>
|
||||
{
|
||||
protected override Type TransformType => typeof(TransformComboResult);
|
||||
|
||||
protected override double RollingDuration => 500;
|
||||
protected override EasingTypes RollingEasing => EasingTypes.Out;
|
||||
|
||||
protected override double GetProportionalDuration(ulong currentValue, ulong newValue)
|
||||
{
|
||||
return currentValue > newValue ? currentValue - newValue : newValue - currentValue;
|
||||
}
|
||||
|
||||
protected override string FormatCount(ulong count)
|
||||
{
|
||||
return $@"{count}x";
|
||||
}
|
||||
|
||||
public override void Increment(ulong amount)
|
||||
{
|
||||
Count = Count + amount;
|
||||
}
|
||||
|
||||
protected class TransformComboResult : Transform<ulong>
|
||||
{
|
||||
protected override ulong CurrentValue
|
||||
{
|
||||
get
|
||||
{
|
||||
double time = Time?.Current ?? 0;
|
||||
if (time < StartTime) return StartValue;
|
||||
if (time >= EndTime) return EndValue;
|
||||
|
||||
return (ulong)Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(Drawable d)
|
||||
{
|
||||
base.Apply(d);
|
||||
(d as ComboResultCounter).DisplayedCount = CurrentValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
89
osu.Game/Modes/HitRenderer.cs
Normal file
89
osu.Game/Modes/HitRenderer.cs
Normal file
@ -0,0 +1,89 @@
|
||||
//Copyright (c) 2007-2016 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Modes.Objects;
|
||||
|
||||
namespace osu.Game.Modes
|
||||
{
|
||||
public abstract class HitRenderer : Container
|
||||
{
|
||||
public Action<HitObject> OnHit;
|
||||
public Action<HitObject> OnMiss;
|
||||
|
||||
protected Playfield Playfield;
|
||||
|
||||
public IEnumerable<DrawableHitObject> DrawableObjects => Playfield.Children.Cast<DrawableHitObject>();
|
||||
}
|
||||
|
||||
public abstract class HitRenderer<T> : HitRenderer
|
||||
where T : HitObject
|
||||
{
|
||||
private List<T> objects;
|
||||
|
||||
public List<HitObject> Objects
|
||||
{
|
||||
set
|
||||
{
|
||||
objects = Convert(value);
|
||||
if (IsLoaded)
|
||||
loadObjects();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Playfield CreatePlayfield();
|
||||
|
||||
protected abstract HitObjectConverter<T> Converter { get; }
|
||||
|
||||
protected virtual List<T> Convert(List<HitObject> objects) => Converter.Convert(objects);
|
||||
|
||||
public HitRenderer()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Playfield = CreatePlayfield()
|
||||
};
|
||||
|
||||
loadObjects();
|
||||
}
|
||||
|
||||
private void loadObjects()
|
||||
{
|
||||
if (objects == null) return;
|
||||
foreach (T h in objects)
|
||||
{
|
||||
var drawableObject = GetVisualRepresentation(h);
|
||||
|
||||
if (drawableObject == null) continue;
|
||||
|
||||
drawableObject.OnHit = onHit;
|
||||
drawableObject.OnMiss = onMiss;
|
||||
|
||||
Playfield.Add(drawableObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMiss(DrawableHitObject obj)
|
||||
{
|
||||
OnMiss?.Invoke(obj.HitObject);
|
||||
}
|
||||
|
||||
private void onHit(DrawableHitObject obj)
|
||||
{
|
||||
OnHit?.Invoke(obj.HitObject);
|
||||
}
|
||||
|
||||
protected abstract DrawableHitObject GetVisualRepresentation(T h);
|
||||
}
|
||||
}
|
78
osu.Game/Modes/Mania/ManiaComboCounter.cs
Normal file
78
osu.Game/Modes/Mania/ManiaComboCounter.cs
Normal file
@ -0,0 +1,78 @@
|
||||
//Copyright (c) 2007-2016 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.Transformations;
|
||||
using osu.Game.Modes.Taiko;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Modes.Mania
|
||||
{
|
||||
/// <summary>
|
||||
/// Similar to osu!taiko, with a pop-out animation when failing (rolling). Used in osu!mania.
|
||||
/// </summary>
|
||||
public class ManiaComboCounter : TaikoComboCounter
|
||||
{
|
||||
protected ushort KeysHeld = 0;
|
||||
|
||||
protected Color4 OriginalColour;
|
||||
|
||||
protected Color4 TintColour => Color4.Orange;
|
||||
protected EasingTypes TintEasing => EasingTypes.None;
|
||||
protected int TintDuration => 500;
|
||||
|
||||
protected Color4 PopOutColor => Color4.Red;
|
||||
protected override float PopOutInitialAlpha => 1.0f;
|
||||
protected override double PopOutDuration => 300;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
PopOutSpriteText.Anchor = Anchor.BottomCentre;
|
||||
PopOutSpriteText.Origin = Anchor.Centre;
|
||||
PopOutSpriteText.FadeColour(PopOutColor, 0);
|
||||
OriginalColour = DisplayedCountSpriteText.Colour;
|
||||
}
|
||||
|
||||
protected override void OnCountRolling(ulong currentValue, ulong newValue)
|
||||
{
|
||||
if (!IsRolling && newValue < currentValue)
|
||||
{
|
||||
PopOutSpriteText.Text = FormatCount(currentValue);
|
||||
|
||||
PopOutSpriteText.FadeTo(PopOutInitialAlpha);
|
||||
PopOutSpriteText.ScaleTo(1.0f);
|
||||
|
||||
PopOutSpriteText.FadeOut(PopOutDuration, PopOutEasing);
|
||||
PopOutSpriteText.ScaleTo(PopOutScale, PopOutDuration, PopOutEasing);
|
||||
}
|
||||
|
||||
base.OnCountRolling(currentValue, newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tints text while holding a key.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Does not alter combo. This has to be done depending of the scoring system.
|
||||
/// (i.e. v1 = each period of time; v2 = when starting and ending a key hold)
|
||||
/// </remarks>
|
||||
public void HoldStart()
|
||||
{
|
||||
if (KeysHeld == 0)
|
||||
DisplayedCountSpriteText.FadeColour(TintColour, TintDuration, TintEasing);
|
||||
KeysHeld++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ends tinting.
|
||||
/// </summary>
|
||||
public void HoldEnd()
|
||||
{
|
||||
KeysHeld--;
|
||||
if (KeysHeld == 0)
|
||||
DisplayedCountSpriteText.FadeColour(OriginalColour, TintDuration, TintEasing);
|
||||
}
|
||||
}
|
||||
}
|
32
osu.Game/Modes/Mania/ManiaHitRenderer.cs
Normal file
32
osu.Game/Modes/Mania/ManiaHitRenderer.cs
Normal file
@ -0,0 +1,32 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Modes.Objects;
|
||||
using osu.Game.Modes.Objects.Mania;
|
||||
|
||||
namespace osu.Game.Modes.Mania
|
||||
{
|
||||
public class ManiaHitRenderer : HitRenderer<ManiaBaseHit>
|
||||
{
|
||||
private readonly int columns;
|
||||
|
||||
public ManiaHitRenderer(int columns = 5)
|
||||
{
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
protected override HitObjectConverter<ManiaBaseHit> Converter => new ManiaConverter(columns);
|
||||
|
||||
protected override Playfield CreatePlayfield() => new ManiaPlayfield(columns);
|
||||
|
||||
protected override DrawableHitObject GetVisualRepresentation(ManiaBaseHit h)
|
||||
{
|
||||
return null;
|
||||
//return new DrawableNote(h)
|
||||
//{
|
||||
// Position = new Vector2((float)(h.Column + 0.5) / columns, -0.1f),
|
||||
// RelativePositionAxes = Axes.Both
|
||||
//};
|
||||
}
|
||||
}
|
||||
}
|
37
osu.Game/Modes/Mania/ManiaPlayfield.cs
Normal file
37
osu.Game/Modes/Mania/ManiaPlayfield.cs
Normal file
@ -0,0 +1,37 @@
|
||||
//Copyright (c) 2007-2016 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.Sprites;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Modes.Mania
|
||||
{
|
||||
public class ManiaPlayfield : Playfield
|
||||
{
|
||||
private readonly int columns;
|
||||
|
||||
public ManiaPlayfield(int columns)
|
||||
{
|
||||
this.columns = columns;
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Size = new Vector2(columns / 20f, 1f);
|
||||
Anchor = Anchor.BottomCentre;
|
||||
Origin = Anchor.BottomCentre;
|
||||
|
||||
Add(new Box { RelativeSizeAxes = Axes.Both, Alpha = 0.5f });
|
||||
|
||||
for (int i = 0; i < columns; i++)
|
||||
Add(new Box()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Size = new Vector2(2, 1),
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Position = new Vector2((float)i / columns, 0),
|
||||
Alpha = 0.5f,
|
||||
Colour = Color4.Black
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
16
osu.Game/Modes/Mania/ManiaRuleset.cs
Normal file
16
osu.Game/Modes/Mania/ManiaRuleset.cs
Normal file
@ -0,0 +1,16 @@
|
||||
//Copyright (c) 2007-2016 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.Game.Modes.Objects;
|
||||
using osu.Game.Modes.Osu;
|
||||
|
||||
namespace osu.Game.Modes.Mania
|
||||
{
|
||||
class ManiaRuleset : Ruleset
|
||||
{
|
||||
public override ScoreOverlay CreateScoreOverlay() => new ScoreOverlayOsu();
|
||||
|
||||
public override HitRenderer CreateHitRendererWith(List<HitObject> objects) => new ManiaHitRenderer { Objects = objects };
|
||||
}
|
||||
}
|
10
osu.Game/Modes/Objects/Catch/CatchBaseHit.cs
Normal file
10
osu.Game/Modes/Objects/Catch/CatchBaseHit.cs
Normal file
@ -0,0 +1,10 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Modes.Objects.Catch
|
||||
{
|
||||
public abstract class CatchBaseHit : HitObject
|
||||
{
|
||||
public float Position;
|
||||
}
|
||||
}
|
38
osu.Game/Modes/Objects/Catch/CatchConverter.cs
Normal file
38
osu.Game/Modes/Objects/Catch/CatchConverter.cs
Normal file
@ -0,0 +1,38 @@
|
||||
//Copyright (c) 2007-2016 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.Game.Modes.Objects.Osu;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Catch
|
||||
{
|
||||
class CatchConverter : HitObjectConverter<CatchBaseHit>
|
||||
{
|
||||
public override List<CatchBaseHit> Convert(List<HitObject> input)
|
||||
{
|
||||
List<CatchBaseHit> output = new List<CatchBaseHit>();
|
||||
|
||||
foreach (HitObject i in input)
|
||||
{
|
||||
CatchBaseHit h = i as CatchBaseHit;
|
||||
|
||||
if (h == null)
|
||||
{
|
||||
OsuBaseHit o = i as OsuBaseHit;
|
||||
|
||||
if (o == null) throw new HitObjectConvertException(@"Catch", i);
|
||||
|
||||
h = new Fruit
|
||||
{
|
||||
StartTime = o.StartTime,
|
||||
Position = o.Position.X,
|
||||
};
|
||||
}
|
||||
|
||||
output.Add(h);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
37
osu.Game/Modes/Objects/Catch/Drawable/DrawableFruit.cs
Normal file
37
osu.Game/Modes/Objects/Catch/Drawable/DrawableFruit.cs
Normal file
@ -0,0 +1,37 @@
|
||||
//Copyright (c) 2007-2016 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.Framework.Graphics.Transformations;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Catch.Drawable
|
||||
{
|
||||
class DrawableFruit : Sprite
|
||||
{
|
||||
private CatchBaseHit h;
|
||||
|
||||
public DrawableFruit(CatchBaseHit h)
|
||||
{
|
||||
this.h = h;
|
||||
|
||||
Origin = Anchor.Centre;
|
||||
Scale = new Vector2(0.1f);
|
||||
RelativePositionAxes = Axes.Y;
|
||||
Position = new Vector2(h.Position, -0.1f);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Texture = textures.Get(@"Menu/logo");
|
||||
|
||||
Transforms.Add(new TransformPosition { StartTime = h.StartTime - 200, EndTime = h.StartTime, StartValue = new Vector2(h.Position, -0.1f), EndValue = new Vector2(h.Position, 0.9f) });
|
||||
Transforms.Add(new TransformAlpha { StartTime = h.StartTime + h.Duration + 200, EndTime = h.StartTime + h.Duration + 400, StartValue = 1, EndValue = 0 });
|
||||
Expire(true);
|
||||
}
|
||||
}
|
||||
}
|
9
osu.Game/Modes/Objects/Catch/Droplet.cs
Normal file
9
osu.Game/Modes/Objects/Catch/Droplet.cs
Normal file
@ -0,0 +1,9 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Modes.Objects.Catch
|
||||
{
|
||||
public class Droplet : CatchBaseHit
|
||||
{
|
||||
}
|
||||
}
|
9
osu.Game/Modes/Objects/Catch/Fruit.cs
Normal file
9
osu.Game/Modes/Objects/Catch/Fruit.cs
Normal file
@ -0,0 +1,9 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Modes.Objects.Catch
|
||||
{
|
||||
public class Fruit : CatchBaseHit
|
||||
{
|
||||
}
|
||||
}
|
86
osu.Game/Modes/Objects/DrawableHitObject.cs
Normal file
86
osu.Game/Modes/Objects/DrawableHitObject.cs
Normal file
@ -0,0 +1,86 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Modes.Objects
|
||||
{
|
||||
public abstract class DrawableHitObject : Container, IStateful<ArmedState>
|
||||
{
|
||||
//todo: move to a more central implementation. this logic should not be at a drawable level.
|
||||
public Action<DrawableHitObject> OnHit;
|
||||
public Action<DrawableHitObject> OnMiss;
|
||||
|
||||
public Func<DrawableHitObject, bool> AllowHit;
|
||||
|
||||
public HitObject HitObject;
|
||||
|
||||
public DrawableHitObject(HitObject hitObject)
|
||||
{
|
||||
HitObject = hitObject;
|
||||
Depth = -(float)hitObject.StartTime;
|
||||
}
|
||||
|
||||
private ArmedState state;
|
||||
public ArmedState State
|
||||
{
|
||||
get { return state; }
|
||||
|
||||
set
|
||||
{
|
||||
if (state == value) return;
|
||||
state = value;
|
||||
|
||||
UpdateState(state);
|
||||
}
|
||||
}
|
||||
|
||||
protected double? HitTime;
|
||||
|
||||
protected virtual bool Hit()
|
||||
{
|
||||
if (State != ArmedState.Disarmed)
|
||||
return false;
|
||||
|
||||
if (AllowHit?.Invoke(this) == false)
|
||||
return false;
|
||||
|
||||
HitTime = Time.Current;
|
||||
|
||||
State = ArmedState.Armed;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
UpdateState(state);
|
||||
}
|
||||
|
||||
private bool counted;
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (Time.Current >= HitObject.EndTime && !counted)
|
||||
{
|
||||
counted = true;
|
||||
if (state == ArmedState.Armed)
|
||||
OnHit?.Invoke(this);
|
||||
else
|
||||
OnMiss?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void UpdateState(ArmedState state);
|
||||
}
|
||||
|
||||
public enum ArmedState
|
||||
{
|
||||
Disarmed,
|
||||
Armed
|
||||
}
|
||||
}
|
38
osu.Game/Modes/Objects/HitObject.cs
Normal file
38
osu.Game/Modes/Objects/HitObject.cs
Normal file
@ -0,0 +1,38 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps.Samples;
|
||||
using osu.Game.Modes.Objects.Osu;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Modes.Objects
|
||||
{
|
||||
/// <summary>
|
||||
/// A hitobject describes a point in a beatmap
|
||||
/// </summary>
|
||||
public abstract class HitObject
|
||||
{
|
||||
public double StartTime;
|
||||
public virtual double EndTime => StartTime;
|
||||
|
||||
public bool NewCombo { get; set; }
|
||||
|
||||
public Color4 Colour = new Color4(17, 136, 170, 255);
|
||||
|
||||
public double Duration => EndTime - StartTime;
|
||||
|
||||
public HitSampleInfo Sample;
|
||||
|
||||
public static HitObject Parse(PlayMode mode, string val)
|
||||
{
|
||||
//TODO: move to modular HitObjectParser system rather than static parsing. (https://github.com/ppy/osu/pull/60/files#r83135780)
|
||||
switch (mode)
|
||||
{
|
||||
case PlayMode.Osu:
|
||||
return OsuBaseHit.Parse(val);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
osu.Game/Modes/Objects/HitObjectConverter.cs
Normal file
23
osu.Game/Modes/Objects/HitObjectConverter.cs
Normal file
@ -0,0 +1,23 @@
|
||||
//Copyright (c) 2007-2016 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;
|
||||
|
||||
namespace osu.Game.Modes.Objects
|
||||
{
|
||||
public abstract class HitObjectConverter<T>
|
||||
where T : HitObject
|
||||
{
|
||||
public abstract List<T> Convert(List<HitObject> input);
|
||||
}
|
||||
public class HitObjectConvertException : Exception
|
||||
{
|
||||
public HitObject Input { get; }
|
||||
public HitObjectConvertException(string modeName, HitObject input)
|
||||
: base($@"Can't convert from {input.GetType().Name} to {modeName} HitObject!")
|
||||
{
|
||||
Input = input;
|
||||
}
|
||||
}
|
||||
}
|
34
osu.Game/Modes/Objects/Mania/Drawable/DrawableNote.cs
Normal file
34
osu.Game/Modes/Objects/Mania/Drawable/DrawableNote.cs
Normal file
@ -0,0 +1,34 @@
|
||||
//Copyright (c) 2007-2016 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.Framework.Graphics.Transformations;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Mania.Drawable
|
||||
{
|
||||
public class DrawableNote : Sprite
|
||||
{
|
||||
private readonly ManiaBaseHit note;
|
||||
|
||||
public DrawableNote(ManiaBaseHit note)
|
||||
{
|
||||
this.note = note;
|
||||
Origin = Anchor.Centre;
|
||||
Scale = new Vector2(0.1f);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Texture = textures.Get(@"Menu/logo");
|
||||
|
||||
Transforms.Add(new TransformPositionY() { StartTime = note.StartTime - 200, EndTime = note.StartTime, StartValue = -0.1f, EndValue = 0.9f });
|
||||
Transforms.Add(new TransformAlpha() { StartTime = note.StartTime + note.Duration + 200, EndTime = note.StartTime + note.Duration + 400, StartValue = 1, EndValue = 0 });
|
||||
Expire(true);
|
||||
}
|
||||
}
|
||||
}
|
9
osu.Game/Modes/Objects/Mania/HoldNote.cs
Normal file
9
osu.Game/Modes/Objects/Mania/HoldNote.cs
Normal file
@ -0,0 +1,9 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Modes.Objects.Mania
|
||||
{
|
||||
public class HoldNote : Note
|
||||
{
|
||||
}
|
||||
}
|
10
osu.Game/Modes/Objects/Mania/ManiaBaseHit.cs
Normal file
10
osu.Game/Modes/Objects/Mania/ManiaBaseHit.cs
Normal file
@ -0,0 +1,10 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Modes.Objects.Mania
|
||||
{
|
||||
public abstract class ManiaBaseHit : HitObject
|
||||
{
|
||||
public int Column;
|
||||
}
|
||||
}
|
46
osu.Game/Modes/Objects/Mania/ManiaConverter.cs
Normal file
46
osu.Game/Modes/Objects/Mania/ManiaConverter.cs
Normal file
@ -0,0 +1,46 @@
|
||||
//Copyright (c) 2007-2016 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 osu.Game.Modes.Objects.Osu;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Mania
|
||||
{
|
||||
class ManiaConverter : HitObjectConverter<ManiaBaseHit>
|
||||
{
|
||||
private readonly int columns;
|
||||
|
||||
public ManiaConverter(int columns)
|
||||
{
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
public override List<ManiaBaseHit> Convert(List<HitObject> input)
|
||||
{
|
||||
List<ManiaBaseHit> output = new List<ManiaBaseHit>();
|
||||
|
||||
foreach (HitObject i in input)
|
||||
{
|
||||
ManiaBaseHit h = i as ManiaBaseHit;
|
||||
|
||||
if (h == null)
|
||||
{
|
||||
OsuBaseHit o = i as OsuBaseHit;
|
||||
|
||||
if (o == null) throw new HitObjectConvertException(@"Mania", i);
|
||||
|
||||
h = new Note
|
||||
{
|
||||
StartTime = o.StartTime,
|
||||
Column = (int)Math.Round(o.Position.X / 512 * columns)
|
||||
};
|
||||
}
|
||||
|
||||
output.Add(h);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
9
osu.Game/Modes/Objects/Mania/Note.cs
Normal file
9
osu.Game/Modes/Objects/Mania/Note.cs
Normal file
@ -0,0 +1,9 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Modes.Objects.Mania
|
||||
{
|
||||
public class Note : ManiaBaseHit
|
||||
{
|
||||
}
|
||||
}
|
9
osu.Game/Modes/Objects/Osu/Circle.cs
Normal file
9
osu.Game/Modes/Objects/Osu/Circle.cs
Normal file
@ -0,0 +1,9 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Modes.Objects.Osu
|
||||
{
|
||||
public class Circle : OsuBaseHit
|
||||
{
|
||||
}
|
||||
}
|
337
osu.Game/Modes/Objects/Osu/Drawable/DrawableCircle.cs
Normal file
337
osu.Game/Modes/Objects/Osu/Drawable/DrawableCircle.cs
Normal file
@ -0,0 +1,337 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework;
|
||||
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.Transformations;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.MathUtils;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Osu.Drawable
|
||||
{
|
||||
public class DrawableCircle : DrawableHitObject
|
||||
{
|
||||
private Sprite approachCircle;
|
||||
private CircleLayer circle;
|
||||
private RingLayer ring;
|
||||
private FlashLayer flash;
|
||||
private ExplodeLayer explode;
|
||||
private NumberLayer number;
|
||||
private GlowLayer glow;
|
||||
private OsuBaseHit h;
|
||||
|
||||
public DrawableCircle(Circle h) : base(h)
|
||||
{
|
||||
this.h = h;
|
||||
|
||||
Origin = Anchor.Centre;
|
||||
RelativePositionAxes = Axes.Both;
|
||||
Position = new Vector2(h.Position.X / 512, h.Position.Y / 384);
|
||||
|
||||
Children = new Framework.Graphics.Drawable[]
|
||||
{
|
||||
glow = new GlowLayer
|
||||
{
|
||||
Colour = h.Colour
|
||||
},
|
||||
circle = new CircleLayer
|
||||
{
|
||||
Colour = h.Colour,
|
||||
Hit = Hit,
|
||||
},
|
||||
number = new NumberLayer(),
|
||||
ring = new RingLayer(),
|
||||
flash = new FlashLayer(),
|
||||
explode = new ExplodeLayer
|
||||
{
|
||||
Colour = h.Colour,
|
||||
},
|
||||
approachCircle = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = h.Colour
|
||||
}
|
||||
};
|
||||
|
||||
//may not be so correct
|
||||
Size = circle.DrawSize;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(BaseGame game)
|
||||
{
|
||||
approachCircle.Texture = game.Textures.Get(@"Play/osu/approachcircle@2x");
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
//force application of the state that was set before we loaded.
|
||||
UpdateState(State);
|
||||
}
|
||||
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
if (!IsLoaded) return;
|
||||
|
||||
Flush(true); //move to DrawableHitObject
|
||||
|
||||
double t = HitTime ?? h.StartTime;
|
||||
|
||||
//sane defaults
|
||||
ring.Alpha = circle.Alpha = number.Alpha = approachCircle.Alpha = glow.Alpha = 1;
|
||||
explode.Alpha = 0;
|
||||
Scale = Vector2.One;
|
||||
|
||||
//always-present transforms
|
||||
Transforms.Add(new TransformAlpha { StartTime = t - 1000, EndTime = t - 800, StartValue = 0, EndValue = 1 });
|
||||
approachCircle.Transforms.Add(new TransformScale { StartTime = t - 1000, EndTime = t, StartValue = new Vector2(2f), EndValue = new Vector2(0.6f) });
|
||||
|
||||
//set transform delay to t==hitTime
|
||||
Delay(t - Time.Current, true);
|
||||
|
||||
approachCircle.FadeOut();
|
||||
glow.FadeOut(400);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Disarmed:
|
||||
Delay(h.Duration + 200);
|
||||
FadeOut(200);
|
||||
break;
|
||||
case ArmedState.Armed:
|
||||
const double flash_in = 30;
|
||||
|
||||
flash.FadeTo(0.8f, flash_in);
|
||||
flash.Delay(flash_in);
|
||||
flash.FadeOut(100);
|
||||
|
||||
explode.FadeIn(flash_in);
|
||||
|
||||
Delay(flash_in, true);
|
||||
|
||||
//after the flash, we can hide some elements that were behind it
|
||||
ring.FadeOut();
|
||||
circle.FadeOut();
|
||||
number.FadeOut();
|
||||
|
||||
FadeOut(800);
|
||||
ScaleTo(Scale * 1.5f, 400, EasingTypes.OutQuad);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private class NumberLayer : Container
|
||||
{
|
||||
private Sprite number;
|
||||
|
||||
public NumberLayer()
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
number = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Alpha = 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
number.Texture = textures.Get(@"Play/osu/number@2x");
|
||||
}
|
||||
}
|
||||
|
||||
private class GlowLayer : Container
|
||||
{
|
||||
private Sprite layer;
|
||||
|
||||
public GlowLayer()
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
layer = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
BlendingMode = BlendingMode.Additive,
|
||||
Alpha = 0.5f
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
layer.Texture = textures.Get(@"Play/osu/ring-glow@2x");
|
||||
}
|
||||
}
|
||||
|
||||
private class RingLayer : Container
|
||||
{
|
||||
private Sprite ring;
|
||||
|
||||
public RingLayer()
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Children = new Framework.Graphics.Drawable[]
|
||||
{
|
||||
ring = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
ring.Texture = textures.Get(@"Play/osu/ring@2x");
|
||||
}
|
||||
}
|
||||
|
||||
private class FlashLayer : Container
|
||||
{
|
||||
public FlashLayer()
|
||||
{
|
||||
Size = new Vector2(144);
|
||||
|
||||
Masking = true;
|
||||
CornerRadius = Size.X / 2;
|
||||
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
BlendingMode = BlendingMode.Additive;
|
||||
Alpha = 0;
|
||||
|
||||
Children = new Framework.Graphics.Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class ExplodeLayer : Container
|
||||
{
|
||||
public ExplodeLayer()
|
||||
{
|
||||
Size = new Vector2(144);
|
||||
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
BlendingMode = BlendingMode.Additive;
|
||||
Alpha = 0;
|
||||
|
||||
Children = new Framework.Graphics.Drawable[]
|
||||
{
|
||||
new Triangles
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class CircleLayer : Container
|
||||
{
|
||||
|
||||
private Sprite disc;
|
||||
private Triangles triangles;
|
||||
|
||||
public Func<bool> Hit;
|
||||
|
||||
public CircleLayer()
|
||||
{
|
||||
Size = new Vector2(144);
|
||||
Masking = true;
|
||||
CornerRadius = DrawSize.X / 2;
|
||||
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Children = new Framework.Graphics.Drawable[]
|
||||
{
|
||||
disc = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
},
|
||||
triangles = new Triangles
|
||||
{
|
||||
BlendingMode = BlendingMode.Additive,
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
disc.Texture = textures.Get(@"Play/osu/disc@2x");
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||
{
|
||||
Hit?.Invoke();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class Triangles : Container
|
||||
{
|
||||
private Texture tex;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
tex = textures.Get(@"Play/osu/triangle@2x");
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Add(new Sprite
|
||||
{
|
||||
Texture = tex,
|
||||
Origin = Anchor.Centre,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()),
|
||||
Scale = new Vector2(RNG.NextSingle() * 0.4f + 0.2f),
|
||||
Alpha = RNG.NextSingle() * 0.3f
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
foreach (Framework.Graphics.Drawable d in Children)
|
||||
d.Position -= new Vector2(0, (float)(d.Scale.X * (Time.Elapsed / 2880)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
58
osu.Game/Modes/Objects/Osu/OsuBaseHit.cs
Normal file
58
osu.Game/Modes/Objects/Osu/OsuBaseHit.cs
Normal file
@ -0,0 +1,58 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Game.Beatmaps.Samples;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Osu
|
||||
{
|
||||
public abstract class OsuBaseHit : HitObject
|
||||
{
|
||||
public Vector2 Position { get; set; }
|
||||
|
||||
[Flags]
|
||||
private enum HitObjectType
|
||||
{
|
||||
Circle = 1,
|
||||
Slider = 2,
|
||||
NewCombo = 4,
|
||||
CircleNewCombo = 5,
|
||||
SliderNewCombo = 6,
|
||||
Spinner = 8,
|
||||
ColourHax = 122,
|
||||
Hold = 128,
|
||||
ManiaLong = 128,
|
||||
}
|
||||
|
||||
public static OsuBaseHit Parse(string val)
|
||||
{
|
||||
string[] split = val.Split(',');
|
||||
var type = (HitObjectType)int.Parse(split[3]);
|
||||
bool combo = type.HasFlag(HitObjectType.NewCombo);
|
||||
type &= (HitObjectType)0xF;
|
||||
type &= ~HitObjectType.NewCombo;
|
||||
OsuBaseHit result;
|
||||
switch (type)
|
||||
{
|
||||
case HitObjectType.Circle:
|
||||
result = new Circle();
|
||||
break;
|
||||
case HitObjectType.Slider:
|
||||
result = new Slider();
|
||||
break;
|
||||
case HitObjectType.Spinner:
|
||||
result = new Spinner();
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException($@"Unknown hit object type {type}");
|
||||
}
|
||||
result.Position = new Vector2(int.Parse(split[0]), int.Parse(split[1]));
|
||||
result.StartTime = double.Parse(split[2]);
|
||||
result.Sample = new HitSampleInfo { Type = (SampleType)int.Parse(split[4]) };
|
||||
result.NewCombo = combo;
|
||||
// TODO: "addition" field
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
20
osu.Game/Modes/Objects/Osu/OsuConverter.cs
Normal file
20
osu.Game/Modes/Objects/Osu/OsuConverter.cs
Normal file
@ -0,0 +1,20 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Osu
|
||||
{
|
||||
class OsuConverter : HitObjectConverter<OsuBaseHit>
|
||||
{
|
||||
public override List<OsuBaseHit> Convert(List<HitObject> input)
|
||||
{
|
||||
List<OsuBaseHit> output = new List<OsuBaseHit>();
|
||||
|
||||
foreach (HitObject h in input)
|
||||
output.Add(h as OsuBaseHit);
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
15
osu.Game/Modes/Objects/Osu/Slider.cs
Normal file
15
osu.Game/Modes/Objects/Osu/Slider.cs
Normal file
@ -0,0 +1,15 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Osu
|
||||
{
|
||||
public class Slider : OsuBaseHit
|
||||
{
|
||||
public List<Vector2> Path;
|
||||
|
||||
public int RepeatCount;
|
||||
}
|
||||
}
|
9
osu.Game/Modes/Objects/Osu/Spinner.cs
Normal file
9
osu.Game/Modes/Objects/Osu/Spinner.cs
Normal file
@ -0,0 +1,9 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Modes.Objects.Osu
|
||||
{
|
||||
public class Spinner : OsuBaseHit
|
||||
{
|
||||
}
|
||||
}
|
37
osu.Game/Modes/Objects/Taiko/Drawable/DrawableTaikoHit.cs
Normal file
37
osu.Game/Modes/Objects/Taiko/Drawable/DrawableTaikoHit.cs
Normal file
@ -0,0 +1,37 @@
|
||||
//Copyright (c) 2007-2016 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.Framework.Graphics.Transformations;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Taiko.Drawable
|
||||
{
|
||||
class DrawableTaikoHit : Sprite
|
||||
{
|
||||
private TaikoBaseHit h;
|
||||
|
||||
public DrawableTaikoHit(TaikoBaseHit h)
|
||||
{
|
||||
this.h = h;
|
||||
|
||||
Origin = Anchor.Centre;
|
||||
Scale = new Vector2(0.2f);
|
||||
RelativePositionAxes = Axes.Both;
|
||||
Position = new Vector2(1.1f, 0.5f);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Texture = textures.Get(@"Menu/logo");
|
||||
|
||||
Transforms.Add(new TransformPositionX { StartTime = h.StartTime - 200, EndTime = h.StartTime, StartValue = 1.1f, EndValue = 0.1f });
|
||||
Transforms.Add(new TransformAlpha { StartTime = h.StartTime + h.Duration + 200, EndTime = h.StartTime + h.Duration + 400, StartValue = 1, EndValue = 0 });
|
||||
Expire(true);
|
||||
}
|
||||
}
|
||||
}
|
18
osu.Game/Modes/Objects/Taiko/TaikoBaseHit.cs
Normal file
18
osu.Game/Modes/Objects/Taiko/TaikoBaseHit.cs
Normal file
@ -0,0 +1,18 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Modes.Objects.Taiko
|
||||
{
|
||||
public class TaikoBaseHit : HitObject
|
||||
{
|
||||
public float Scale = 1;
|
||||
|
||||
public TaikoColour Type;
|
||||
}
|
||||
|
||||
public enum TaikoColour
|
||||
{
|
||||
Red,
|
||||
Blue
|
||||
}
|
||||
}
|
37
osu.Game/Modes/Objects/Taiko/TaikoConverter.cs
Normal file
37
osu.Game/Modes/Objects/Taiko/TaikoConverter.cs
Normal file
@ -0,0 +1,37 @@
|
||||
//Copyright (c) 2007-2016 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.Game.Modes.Objects.Osu;
|
||||
|
||||
namespace osu.Game.Modes.Objects.Taiko
|
||||
{
|
||||
class TaikoConverter : HitObjectConverter<TaikoBaseHit>
|
||||
{
|
||||
public override List<TaikoBaseHit> Convert(List<HitObject> input)
|
||||
{
|
||||
List<TaikoBaseHit> output = new List<TaikoBaseHit>();
|
||||
|
||||
foreach (HitObject i in input)
|
||||
{
|
||||
TaikoBaseHit h = i as TaikoBaseHit;
|
||||
|
||||
if (h == null)
|
||||
{
|
||||
OsuBaseHit o = i as OsuBaseHit;
|
||||
|
||||
if (o == null) throw new HitObjectConvertException(@"Taiko", i);
|
||||
|
||||
h = new TaikoBaseHit
|
||||
{
|
||||
StartTime = o.StartTime,
|
||||
};
|
||||
}
|
||||
|
||||
output.Add(h);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
150
osu.Game/Modes/Osu/OsuComboCounter.cs
Normal file
150
osu.Game/Modes/Osu/OsuComboCounter.cs
Normal file
@ -0,0 +1,150 @@
|
||||
//Copyright (c) 2007-2016 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.Osu
|
||||
{
|
||||
/// <summary>
|
||||
/// Uses the 'x' symbol and has a pop-out effect while rolling over. Used in osu! standard.
|
||||
/// </summary>
|
||||
public class OsuComboCounter : ComboCounter
|
||||
{
|
||||
protected uint ScheduledPopOutCurrentId = 0;
|
||||
|
||||
protected virtual float PopOutSmallScale => 1.1f;
|
||||
protected virtual bool CanPopOutWhileRolling => false;
|
||||
|
||||
public Vector2 InnerCountPosition
|
||||
{
|
||||
get
|
||||
{
|
||||
return DisplayedCountSpriteText.Position;
|
||||
}
|
||||
set
|
||||
{
|
||||
DisplayedCountSpriteText.Position = value;
|
||||
}
|
||||
}
|
||||
|
||||
public OsuComboCounter()
|
||||
{
|
||||
PopOutSpriteText.Origin = Origin;
|
||||
PopOutSpriteText.Anchor = Anchor;
|
||||
|
||||
Add(PopOutSpriteText);
|
||||
}
|
||||
|
||||
protected override string FormatCount(ulong count)
|
||||
{
|
||||
return $@"{count}x";
|
||||
}
|
||||
|
||||
protected virtual void TransformPopOut(ulong newValue)
|
||||
{
|
||||
PopOutSpriteText.Text = FormatCount(newValue);
|
||||
|
||||
PopOutSpriteText.ScaleTo(PopOutScale);
|
||||
PopOutSpriteText.FadeTo(PopOutInitialAlpha);
|
||||
PopOutSpriteText.MoveTo(Vector2.Zero);
|
||||
|
||||
PopOutSpriteText.ScaleTo(1, PopOutDuration, PopOutEasing);
|
||||
PopOutSpriteText.FadeOut(PopOutDuration, PopOutEasing);
|
||||
PopOutSpriteText.MoveTo(DisplayedCountSpriteText.Position, PopOutDuration, PopOutEasing);
|
||||
}
|
||||
|
||||
protected virtual void TransformPopOutRolling(ulong newValue)
|
||||
{
|
||||
TransformPopOut(newValue);
|
||||
TransformPopOutSmall(newValue);
|
||||
}
|
||||
|
||||
protected virtual void TransformNoPopOut(ulong newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.Text = FormatCount(newValue);
|
||||
DisplayedCountSpriteText.ScaleTo(1);
|
||||
}
|
||||
|
||||
protected virtual void TransformPopOutSmall(ulong newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.Text = FormatCount(newValue);
|
||||
DisplayedCountSpriteText.ScaleTo(PopOutSmallScale);
|
||||
DisplayedCountSpriteText.ScaleTo(1, PopOutDuration, PopOutEasing);
|
||||
}
|
||||
|
||||
protected virtual void ScheduledPopOutSmall(uint id)
|
||||
{
|
||||
// Too late; scheduled task invalidated
|
||||
if (id != ScheduledPopOutCurrentId)
|
||||
return;
|
||||
|
||||
DisplayedCount++;
|
||||
}
|
||||
|
||||
protected override void OnCountRolling(ulong currentValue, ulong newValue)
|
||||
{
|
||||
ScheduledPopOutCurrentId++;
|
||||
|
||||
// Hides displayed count if was increasing from 0 to 1 but didn't finish
|
||||
if (currentValue == 0 && newValue == 0)
|
||||
DisplayedCountSpriteText.FadeOut(FadeOutDuration);
|
||||
|
||||
base.OnCountRolling(currentValue, newValue);
|
||||
}
|
||||
|
||||
protected override void OnCountIncrement(ulong currentValue, ulong newValue)
|
||||
{
|
||||
ScheduledPopOutCurrentId++;
|
||||
|
||||
if (DisplayedCount < currentValue)
|
||||
DisplayedCount++;
|
||||
|
||||
DisplayedCountSpriteText.Show();
|
||||
|
||||
TransformPopOut(newValue);
|
||||
|
||||
uint newTaskId = ScheduledPopOutCurrentId;
|
||||
Scheduler.AddDelayed(delegate
|
||||
{
|
||||
ScheduledPopOutSmall(newTaskId);
|
||||
}, PopOutDuration);
|
||||
}
|
||||
|
||||
protected override void OnCountChange(ulong currentValue, ulong newValue)
|
||||
{
|
||||
ScheduledPopOutCurrentId++;
|
||||
|
||||
if (newValue == 0)
|
||||
DisplayedCountSpriteText.FadeOut();
|
||||
|
||||
base.OnCountChange(currentValue, newValue);
|
||||
}
|
||||
|
||||
protected override void OnDisplayedCountRolling(ulong currentValue, ulong newValue)
|
||||
{
|
||||
if (newValue == 0)
|
||||
DisplayedCountSpriteText.FadeOut(FadeOutDuration);
|
||||
else
|
||||
DisplayedCountSpriteText.Show();
|
||||
|
||||
if (CanPopOutWhileRolling)
|
||||
TransformPopOutRolling(newValue);
|
||||
else
|
||||
TransformNoPopOut(newValue);
|
||||
}
|
||||
|
||||
protected override void OnDisplayedCountChange(ulong newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.FadeTo(newValue == 0 ? 0 : 1);
|
||||
|
||||
TransformNoPopOut(newValue);
|
||||
}
|
||||
|
||||
protected override void OnDisplayedCountIncrement(ulong newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.Show();
|
||||
|
||||
TransformPopOutSmall(newValue);
|
||||
}
|
||||
}
|
||||
}
|
19
osu.Game/Modes/Osu/OsuHitRenderer.cs
Normal file
19
osu.Game/Modes/Osu/OsuHitRenderer.cs
Normal file
@ -0,0 +1,19 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Modes.Objects;
|
||||
using osu.Game.Modes.Objects.Osu;
|
||||
using osu.Game.Modes.Objects.Osu.Drawable;
|
||||
|
||||
namespace osu.Game.Modes.Osu
|
||||
{
|
||||
public class OsuHitRenderer : HitRenderer<OsuBaseHit>
|
||||
{
|
||||
protected override HitObjectConverter<OsuBaseHit> Converter => new OsuConverter();
|
||||
|
||||
protected override Playfield CreatePlayfield() => new OsuPlayfield();
|
||||
|
||||
protected override DrawableHitObject GetVisualRepresentation(OsuBaseHit h)
|
||||
=> h is Circle ? new DrawableCircle(h as Circle) : null;
|
||||
}
|
||||
}
|
58
osu.Game/Modes/Osu/OsuPlayfield.cs
Normal file
58
osu.Game/Modes/Osu/OsuPlayfield.cs
Normal file
@ -0,0 +1,58 @@
|
||||
//Copyright (c) 2007-2016 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;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Modes.Osu
|
||||
{
|
||||
public class OsuPlayfield : Playfield
|
||||
{
|
||||
protected override Container<Drawable> Content => hitObjectContainer;
|
||||
|
||||
private Container hitObjectContainer;
|
||||
|
||||
public override Vector2 Size
|
||||
{
|
||||
get
|
||||
{
|
||||
var parentSize = Parent.DrawSize;
|
||||
var aspectSize = parentSize.X * 0.75f < parentSize.Y ? new Vector2(parentSize.X, parentSize.X * 0.75f) : new Vector2(parentSize.Y * 4f / 3f, parentSize.Y);
|
||||
|
||||
return new Vector2(aspectSize.X / parentSize.X, aspectSize.Y / parentSize.Y) * base.Size;
|
||||
}
|
||||
}
|
||||
|
||||
public OsuPlayfield()
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Size = new Vector2(0.75f);
|
||||
|
||||
AddInternal(new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.5f,
|
||||
});
|
||||
|
||||
AddInternal(hitObjectContainer = new HitObjectContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
});
|
||||
}
|
||||
|
||||
class HitObjectContainer : Container
|
||||
{
|
||||
public override Vector2 ChildScale => new Vector2(0.625f);
|
||||
}
|
||||
}
|
||||
}
|
14
osu.Game/Modes/Osu/OsuRuleset.cs
Normal file
14
osu.Game/Modes/Osu/OsuRuleset.cs
Normal file
@ -0,0 +1,14 @@
|
||||
//Copyright (c) 2007-2016 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.Game.Modes.Objects;
|
||||
|
||||
namespace osu.Game.Modes.Osu
|
||||
{
|
||||
class OsuRuleset : Ruleset
|
||||
{
|
||||
public override ScoreOverlay CreateScoreOverlay() => new ScoreOverlayOsu();
|
||||
|
||||
public override HitRenderer CreateHitRendererWith(List<HitObject> objects) => new OsuHitRenderer { Objects = objects };
|
||||
}}
|
49
osu.Game/Modes/Osu/ScoreOverlayOsu.cs
Normal file
49
osu.Game/Modes/Osu/ScoreOverlayOsu.cs
Normal file
@ -0,0 +1,49 @@
|
||||
//Copyright (c) 2007-2016 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.Game.Graphics.UserInterface;
|
||||
using OpenTK;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace osu.Game.Modes.Osu
|
||||
{
|
||||
class ScoreOverlayOsu : ScoreOverlay
|
||||
{
|
||||
protected override PercentageCounter CreateAccuracyCounter() => new PercentageCounter()
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Position = new Vector2(0, 45)
|
||||
};
|
||||
|
||||
protected override ScoreCounter CreateScoreCounter() => new ScoreCounter()
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
TextSize = 60
|
||||
};
|
||||
|
||||
protected override ComboCounter CreateComboCounter() => new OsuComboCounter()
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
};
|
||||
|
||||
protected override KeyCounterCollection CreateKeyCounter() => new KeyCounterCollection
|
||||
{
|
||||
IsCounting = true,
|
||||
FadeTime = 50,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Position = new Vector2(10),
|
||||
Counters = new KeyCounter[]
|
||||
{
|
||||
new KeyCounterKeyboard(@"Z", Key.Z),
|
||||
new KeyCounterKeyboard(@"X", Key.X),
|
||||
new KeyCounterMouse(@"M1", MouseButton.Left),
|
||||
new KeyCounterMouse(@"M2", MouseButton.Right),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
20
osu.Game/Modes/PlayMode.cs
Normal file
20
osu.Game/Modes/PlayMode.cs
Normal file
@ -0,0 +1,20 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace osu.Game.Modes
|
||||
{
|
||||
public enum PlayMode
|
||||
{
|
||||
[Description(@"osu!")]
|
||||
Osu = 0,
|
||||
[Description(@"osu!taiko")]
|
||||
Taiko = 1,
|
||||
[Description(@"osu!catch")]
|
||||
Catch = 2,
|
||||
[Description(@"osu!mania")]
|
||||
Mania = 3
|
||||
}
|
||||
}
|
11
osu.Game/Modes/Playfield.cs
Normal file
11
osu.Game/Modes/Playfield.cs
Normal file
@ -0,0 +1,11 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Modes
|
||||
{
|
||||
public class Playfield : Container
|
||||
{
|
||||
}
|
||||
}
|
34
osu.Game/Modes/Ruleset.cs
Normal file
34
osu.Game/Modes/Ruleset.cs
Normal file
@ -0,0 +1,34 @@
|
||||
//Copyright (c) 2007-2016 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.Game.Modes.Catch;
|
||||
using osu.Game.Modes.Mania;
|
||||
using osu.Game.Modes.Objects;
|
||||
using osu.Game.Modes.Osu;
|
||||
using osu.Game.Modes.Taiko;
|
||||
|
||||
namespace osu.Game.Modes
|
||||
{
|
||||
public abstract class Ruleset
|
||||
{
|
||||
public abstract ScoreOverlay CreateScoreOverlay();
|
||||
|
||||
public abstract HitRenderer CreateHitRendererWith(List<HitObject> objects);
|
||||
|
||||
public static Ruleset GetRuleset(PlayMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
default:
|
||||
return new OsuRuleset();
|
||||
case PlayMode.Catch:
|
||||
return new CatchRuleset();
|
||||
case PlayMode.Mania:
|
||||
return new ManiaRuleset();
|
||||
case PlayMode.Taiko:
|
||||
return new TaikoRuleset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
osu.Game/Modes/ScoreOverlay.cs
Normal file
49
osu.Game/Modes/ScoreOverlay.cs
Normal file
@ -0,0 +1,49 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Modes.Objects;
|
||||
|
||||
namespace osu.Game.Modes
|
||||
{
|
||||
public abstract class ScoreOverlay : Container
|
||||
{
|
||||
public KeyCounterCollection KeyCounter;
|
||||
public ComboCounter ComboCounter;
|
||||
public ScoreCounter ScoreCounter;
|
||||
public PercentageCounter AccuracyCounter;
|
||||
|
||||
protected abstract KeyCounterCollection CreateKeyCounter();
|
||||
protected abstract ComboCounter CreateComboCounter();
|
||||
protected abstract PercentageCounter CreateAccuracyCounter();
|
||||
protected abstract ScoreCounter CreateScoreCounter();
|
||||
|
||||
public virtual void OnHit(HitObject h)
|
||||
{
|
||||
ComboCounter?.Increment();
|
||||
ScoreCounter?.Increment(300);
|
||||
AccuracyCounter?.Set(Math.Min(1, AccuracyCounter.Count + 0.01f));
|
||||
}
|
||||
|
||||
public virtual void OnMiss(HitObject h)
|
||||
{
|
||||
ComboCounter?.Roll();
|
||||
AccuracyCounter?.Set(AccuracyCounter.Count - 0.01f);
|
||||
}
|
||||
|
||||
public ScoreOverlay()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[] {
|
||||
KeyCounter = CreateKeyCounter(),
|
||||
ComboCounter = CreateComboCounter(),
|
||||
ScoreCounter = CreateScoreCounter(),
|
||||
AccuracyCounter = CreateAccuracyCounter(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
62
osu.Game/Modes/Taiko/TaikoComboCounter.cs
Normal file
62
osu.Game/Modes/Taiko/TaikoComboCounter.cs
Normal file
@ -0,0 +1,62 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics.Transformations;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Modes.Taiko
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows tint and scaling animations. Used in osu!taiko.
|
||||
/// </summary>
|
||||
public class TaikoComboCounter : ComboCounter
|
||||
{
|
||||
protected virtual int AnimationDuration => 300;
|
||||
protected virtual float ScaleFactor => 2;
|
||||
protected virtual EasingTypes AnimationEasing => EasingTypes.None;
|
||||
protected virtual bool CanAnimateWhenBackwards => false;
|
||||
|
||||
public TaikoComboCounter()
|
||||
{
|
||||
DisplayedCountSpriteText.Origin = Framework.Graphics.Anchor.BottomCentre;
|
||||
DisplayedCountSpriteText.Anchor = Framework.Graphics.Anchor.BottomCentre;
|
||||
}
|
||||
|
||||
protected virtual void TransformAnimate(ulong newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.Text = FormatCount(newValue);
|
||||
DisplayedCountSpriteText.ScaleTo(new Vector2(1, ScaleFactor));
|
||||
DisplayedCountSpriteText.ScaleTo(new Vector2(1, 1), AnimationDuration, AnimationEasing);
|
||||
}
|
||||
|
||||
protected virtual void TransformNotAnimate(ulong newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.Text = FormatCount(newValue);
|
||||
DisplayedCountSpriteText.ScaleTo(1);
|
||||
}
|
||||
|
||||
protected override void OnDisplayedCountRolling(ulong currentValue, ulong newValue)
|
||||
{
|
||||
if (newValue == 0)
|
||||
DisplayedCountSpriteText.FadeOut(FadeOutDuration);
|
||||
else
|
||||
DisplayedCountSpriteText.Show();
|
||||
|
||||
TransformNotAnimate(newValue);
|
||||
}
|
||||
|
||||
protected override void OnDisplayedCountChange(ulong newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.FadeTo(newValue == 0 ? 0 : 1);
|
||||
|
||||
TransformNotAnimate(newValue);
|
||||
}
|
||||
|
||||
protected override void OnDisplayedCountIncrement(ulong newValue)
|
||||
{
|
||||
DisplayedCountSpriteText.Show();
|
||||
|
||||
TransformAnimate(newValue);
|
||||
}
|
||||
}
|
||||
}
|
17
osu.Game/Modes/Taiko/TaikoHitRenderer.cs
Normal file
17
osu.Game/Modes/Taiko/TaikoHitRenderer.cs
Normal file
@ -0,0 +1,17 @@
|
||||
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Modes.Objects;
|
||||
using osu.Game.Modes.Objects.Taiko;
|
||||
|
||||
namespace osu.Game.Modes.Taiko
|
||||
{
|
||||
public class TaikoHitRenderer : HitRenderer<TaikoBaseHit>
|
||||
{
|
||||
protected override HitObjectConverter<TaikoBaseHit> Converter => new TaikoConverter();
|
||||
|
||||
protected override Playfield CreatePlayfield() => new TaikoPlayfield();
|
||||
|
||||
protected override DrawableHitObject GetVisualRepresentation(TaikoBaseHit h) => null;// new DrawableTaikoHit(h);
|
||||
}
|
||||
}
|
39
osu.Game/Modes/Taiko/TaikoPlayfield.cs
Normal file
39
osu.Game/Modes/Taiko/TaikoPlayfield.cs
Normal file
@ -0,0 +1,39 @@
|
||||
//Copyright (c) 2007-2016 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 OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Modes.Taiko
|
||||
{
|
||||
public class TaikoPlayfield : Playfield
|
||||
{
|
||||
public TaikoPlayfield()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Size = new Vector2(1, 100);
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Add(new Box { RelativeSizeAxes = Axes.Both, Alpha = 0.5f });
|
||||
|
||||
Add(new Sprite
|
||||
{
|
||||
Texture = textures.Get(@"Menu/logo"),
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(0.2f),
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Position = new Vector2(0.1f, 0.5f),
|
||||
Colour = Color4.Gray
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
16
osu.Game/Modes/Taiko/TaikoRuleset.cs
Normal file
16
osu.Game/Modes/Taiko/TaikoRuleset.cs
Normal file
@ -0,0 +1,16 @@
|
||||
//Copyright (c) 2007-2016 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.Game.Modes.Objects;
|
||||
using osu.Game.Modes.Osu;
|
||||
|
||||
namespace osu.Game.Modes.Taiko
|
||||
{
|
||||
class TaikoRuleset : Ruleset
|
||||
{
|
||||
public override ScoreOverlay CreateScoreOverlay() => new ScoreOverlayOsu();
|
||||
|
||||
public override HitRenderer CreateHitRendererWith(List<HitObject> objects) => new TaikoHitRenderer { Objects = objects };
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user