mirror of
https://github.com/osukey/osukey.git
synced 2025-08-08 00:53:56 +09:00
handle spinners and follow points
This commit is contained in:
@ -2,11 +2,9 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
@ -26,23 +24,19 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(OsuModAutopilot), typeof(OsuModWiggle), typeof(OsuModTransform), typeof(ModAutoplay) };
|
public override Type[] IncompatibleMods => new[] { typeof(OsuModAutopilot), typeof(OsuModWiggle), typeof(OsuModTransform), typeof(ModAutoplay) };
|
||||||
|
|
||||||
public const float SPIN_RADIUS = 50; // same as OsuAutoGeneratorBase.SPIN_RADIUS
|
private const float spin_radius = 30;
|
||||||
|
private Vector2? prevCursorPos;
|
||||||
private DrawableSpinner activeSpinner;
|
|
||||||
private float spinnerAngle; // in radians
|
|
||||||
|
|
||||||
public void Update(Playfield playfield)
|
public void Update(Playfield playfield)
|
||||||
{
|
{
|
||||||
var cursorPos = playfield.Cursor.ActiveCursor.DrawPosition;
|
var cursorPos = playfield.Cursor.ActiveCursor.DrawPosition;
|
||||||
double currentTime = playfield.Clock.CurrentTime;
|
double currentTime = playfield.Clock.CurrentTime;
|
||||||
|
|
||||||
// Judgment displays would all be cramped onto the cursor
|
// Hide judgment displays and follow points
|
||||||
playfield.DisplayJudgements.Value = false;
|
playfield.DisplayJudgements.Value = false;
|
||||||
|
(playfield as OsuPlayfield)?.FollowPoints.Clear();
|
||||||
|
|
||||||
// FIXME: Hide follow points
|
// Move all currently alive object to new destination
|
||||||
//(playfield as OsuPlayfield)?.ConnectionLayer.Hide();
|
|
||||||
|
|
||||||
// If object too old, remove from movingObjects list, otherwise move to new destination
|
|
||||||
foreach (var drawable in playfield.HitObjectContainer.AliveObjects.OfType<DrawableOsuHitObject>())
|
foreach (var drawable in playfield.HitObjectContainer.AliveObjects.OfType<DrawableOsuHitObject>())
|
||||||
{
|
{
|
||||||
var h = drawable.HitObject;
|
var h = drawable.HitObject;
|
||||||
@ -79,64 +73,32 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
// Move spinner to cursor
|
// Move spinner to cursor
|
||||||
if (currentTime < h.StartTime)
|
if (currentTime < h.StartTime)
|
||||||
{
|
{
|
||||||
spinner.MoveTo(cursorPos, Math.Max(0, h.StartTime - currentTime - 10));
|
spinner.MoveTo(cursorPos + new Vector2(0, -spin_radius), Math.Max(0, h.StartTime - currentTime - 10));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO:
|
// Move spinner visually
|
||||||
// - get current angle to cursor
|
Vector2 delta = spin_radius * (spinner.Position - prevCursorPos ?? cursorPos).Normalized();
|
||||||
// - move clockwise(?)
|
const float angle = 3 * MathF.PI / 180; // radians per update, arbitrary value
|
||||||
// - call spinner.RotationTracker.AddRotation
|
|
||||||
|
|
||||||
// TODO: Remove
|
// Rotation matrix
|
||||||
//spinnerAngle = 0;
|
var targetPos = new Vector2(
|
||||||
//activeSpinner = spinner;
|
delta.X * MathF.Cos(angle) - delta.Y * MathF.Sin(angle) + cursorPos.X,
|
||||||
|
delta.X * MathF.Sin(angle) + delta.Y * MathF.Cos(angle) + cursorPos.Y
|
||||||
|
);
|
||||||
|
|
||||||
|
spinner.MoveTo(targetPos);
|
||||||
|
|
||||||
|
// Logically finish spinner immediatly, no need for the user to click.
|
||||||
|
// Temporary workaround until spinner rotations are easier to handle, similar as Autopilot mod.
|
||||||
|
spinner.Result.RateAdjustedRotation = spinner.HitObject.SpinsRequired * 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move active spinner around the cursor
|
prevCursorPos = cursorPos;
|
||||||
if (activeSpinner != null)
|
|
||||||
{
|
|
||||||
double spinnerEndTime = activeSpinner.HitObject.GetEndTime();
|
|
||||||
|
|
||||||
if (currentTime > spinnerEndTime)
|
|
||||||
{
|
|
||||||
activeSpinner = null;
|
|
||||||
spinnerAngle = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const float additional_degrees = 4;
|
|
||||||
float added_degrees = additional_degrees * (float)Math.PI / 180;
|
|
||||||
spinnerAngle += added_degrees;
|
|
||||||
|
|
||||||
//int spinsRequired = activeSpinner.HitObject.SpinsRequired;
|
|
||||||
//float spunDegrees = activeSpinner.Result.RateAdjustedRotation;
|
|
||||||
//double timeLeft = spinnerEndTime - currentTime;
|
|
||||||
|
|
||||||
// Visual progress
|
|
||||||
activeSpinner.MoveTo(new Vector2((float)(SPIN_RADIUS * Math.Cos(spinnerAngle) + cursorPos.X), (float)(SPIN_RADIUS * Math.Sin(spinnerAngle) + cursorPos.Y)));
|
|
||||||
|
|
||||||
// Logical progress
|
|
||||||
activeSpinner.RotationTracker.AddRotation(added_degrees);
|
|
||||||
Console.WriteLine($"added_degrees={added_degrees}");
|
|
||||||
//activeSpinner.Disc.RotationAbsolute += additional_degrees;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TODOs
|
|
||||||
* - fix sliders reappearing at original position after their EndTime (see https://puu.sh/E7zT4/111cf9cdc8.gif)
|
|
||||||
* - find nicer way to handle slider headcircle explosion, flash, ...
|
|
||||||
* - add Aim Assist as incompatible mod for Autoplay (?)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
@ -31,7 +31,8 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
private readonly ProxyContainer approachCircles;
|
private readonly ProxyContainer approachCircles;
|
||||||
private readonly ProxyContainer spinnerProxies;
|
private readonly ProxyContainer spinnerProxies;
|
||||||
private readonly JudgementContainer<DrawableOsuJudgement> judgementLayer;
|
private readonly JudgementContainer<DrawableOsuJudgement> judgementLayer;
|
||||||
private readonly FollowPointRenderer followPoints;
|
|
||||||
|
public FollowPointRenderer FollowPoints { get; }
|
||||||
|
|
||||||
public static readonly Vector2 BASE_SIZE = new Vector2(512, 384);
|
public static readonly Vector2 BASE_SIZE = new Vector2(512, 384);
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
{
|
{
|
||||||
playfieldBorder = new PlayfieldBorder { RelativeSizeAxes = Axes.Both },
|
playfieldBorder = new PlayfieldBorder { RelativeSizeAxes = Axes.Both },
|
||||||
spinnerProxies = new ProxyContainer { RelativeSizeAxes = Axes.Both },
|
spinnerProxies = new ProxyContainer { RelativeSizeAxes = Axes.Both },
|
||||||
followPoints = new FollowPointRenderer { RelativeSizeAxes = Axes.Both },
|
FollowPoints = new FollowPointRenderer { RelativeSizeAxes = Axes.Both },
|
||||||
judgementLayer = new JudgementContainer<DrawableOsuJudgement> { RelativeSizeAxes = Axes.Both },
|
judgementLayer = new JudgementContainer<DrawableOsuJudgement> { RelativeSizeAxes = Axes.Both },
|
||||||
HitObjectContainer,
|
HitObjectContainer,
|
||||||
judgementAboveHitObjectLayer = new Container { RelativeSizeAxes = Axes.Both },
|
judgementAboveHitObjectLayer = new Container { RelativeSizeAxes = Axes.Both },
|
||||||
@ -131,13 +132,13 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
protected override void OnHitObjectAdded(HitObject hitObject)
|
protected override void OnHitObjectAdded(HitObject hitObject)
|
||||||
{
|
{
|
||||||
base.OnHitObjectAdded(hitObject);
|
base.OnHitObjectAdded(hitObject);
|
||||||
followPoints.AddFollowPoints((OsuHitObject)hitObject);
|
FollowPoints.AddFollowPoints((OsuHitObject)hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnHitObjectRemoved(HitObject hitObject)
|
protected override void OnHitObjectRemoved(HitObject hitObject)
|
||||||
{
|
{
|
||||||
base.OnHitObjectRemoved(hitObject);
|
base.OnHitObjectRemoved(hitObject);
|
||||||
followPoints.RemoveFollowPoints((OsuHitObject)hitObject);
|
FollowPoints.RemoveFollowPoints((OsuHitObject)hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onNewResult(DrawableHitObject judgedObject, JudgementResult result)
|
private void onNewResult(DrawableHitObject judgedObject, JudgementResult result)
|
||||||
|
Reference in New Issue
Block a user