mirror of
https://github.com/ppy/osu.git
synced 2025-01-07 20:42:54 +08:00
Merge branch 'master' into master
This commit is contained in:
commit
6a8e99db17
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) 2007-2018 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.Timing;
|
||||||
|
using osu.Game.Rulesets.Mania.Edit;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
|
{
|
||||||
|
[Cached(Type = typeof(IManiaHitObjectComposer))]
|
||||||
|
public abstract class ManiaPlacementBlueprintTestCase : PlacementBlueprintTestCase, IManiaHitObjectComposer
|
||||||
|
{
|
||||||
|
private readonly Column column;
|
||||||
|
|
||||||
|
protected ManiaPlacementBlueprintTestCase()
|
||||||
|
{
|
||||||
|
Add(column = new Column(0)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AccentColour = Color4.OrangeRed,
|
||||||
|
Clock = new FramedClock(new StopwatchClock()), // No scroll
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
|
{
|
||||||
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
|
dependencies.CacheAs(((ScrollingTestContainer)HitObjectContainer).ScrollingInfo);
|
||||||
|
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Container CreateHitObjectContainer() => new ScrollingTestContainer(ScrollingDirection.Down) { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
|
protected override void AddHitObject(DrawableHitObject hitObject) => column.Add((DrawableManiaHitObject)hitObject);
|
||||||
|
|
||||||
|
public Column ColumnAt(Vector2 screenSpacePosition) => column;
|
||||||
|
}
|
||||||
|
}
|
@ -49,8 +49,8 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
Spacing = new Vector2(20, 0),
|
Spacing = new Vector2(20, 0),
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
createColumn(ScrollingDirection.Up, ManiaAction.Key1),
|
createColumn(ScrollingDirection.Up, ManiaAction.Key1, 0),
|
||||||
createColumn(ScrollingDirection.Down, ManiaAction.Key2)
|
createColumn(ScrollingDirection.Down, ManiaAction.Key2, 1)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -85,9 +85,9 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Drawable createColumn(ScrollingDirection direction, ManiaAction action)
|
private Drawable createColumn(ScrollingDirection direction, ManiaAction action, int index)
|
||||||
{
|
{
|
||||||
var column = new Column
|
var column = new Column(index)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
|
{
|
||||||
|
public class TestCaseNotePlacementBlueprint : ManiaPlacementBlueprintTestCase
|
||||||
|
{
|
||||||
|
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableNote((Note)hitObject);
|
||||||
|
protected override PlacementBlueprint CreateBlueprint() => new NotePlacementBlueprint();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright (c) 2007-2018 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.Input.Events;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public abstract class ManiaPlacementBlueprint<T> : PlacementBlueprint
|
||||||
|
where T : ManiaHitObject
|
||||||
|
{
|
||||||
|
protected new T HitObject => (T)base.HitObject;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current mouse position, snapped to the closest column.
|
||||||
|
/// </summary>
|
||||||
|
protected Vector2 SnappedMousePosition { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The width of the closest column to the current mouse position.
|
||||||
|
/// </summary>
|
||||||
|
protected float SnappedWidth { get; private set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IManiaHitObjectComposer composer { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IScrollingInfo scrollingInfo { get; set; }
|
||||||
|
|
||||||
|
protected ManiaPlacementBlueprint(T hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||||
|
{
|
||||||
|
Column column = ColumnAt(e.ScreenSpaceMousePosition);
|
||||||
|
|
||||||
|
if (column == null) return false;
|
||||||
|
|
||||||
|
SnappedWidth = column.DrawWidth;
|
||||||
|
|
||||||
|
// Snap to the column
|
||||||
|
var parentPos = Parent.ToLocalSpace(column.ToScreenSpace(new Vector2(column.DrawWidth / 2, 0)));
|
||||||
|
SnappedMousePosition = new Vector2(parentPos.X, e.MousePosition.Y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double TimeAt(Vector2 screenSpacePosition)
|
||||||
|
{
|
||||||
|
var column = ColumnAt(screenSpacePosition);
|
||||||
|
if (column == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var hitObjectContainer = column.HitObjectContainer;
|
||||||
|
|
||||||
|
// If we're scrolling downwards, a position of 0 is actually further away from the hit target
|
||||||
|
// so we need to flip the vertical coordinate in the hitobject container's space
|
||||||
|
var hitObjectPos = column.HitObjectContainer.ToLocalSpace(applyPositionOffset(screenSpacePosition)).Y;
|
||||||
|
if (scrollingInfo.Direction.Value == ScrollingDirection.Down)
|
||||||
|
hitObjectPos = hitObjectContainer.DrawHeight - hitObjectPos;
|
||||||
|
|
||||||
|
return scrollingInfo.Algorithm.TimeAt(hitObjectPos,
|
||||||
|
EditorClock.CurrentTime,
|
||||||
|
scrollingInfo.TimeRange.Value,
|
||||||
|
hitObjectContainer.DrawHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Column ColumnAt(Vector2 screenSpacePosition)
|
||||||
|
=> composer.ColumnAt(applyPositionOffset(screenSpacePosition));
|
||||||
|
|
||||||
|
private Vector2 applyPositionOffset(Vector2 position)
|
||||||
|
{
|
||||||
|
switch (scrollingInfo.Direction.Value)
|
||||||
|
{
|
||||||
|
case ScrollingDirection.Up:
|
||||||
|
position.Y -= NotePiece.NOTE_HEIGHT / 2;
|
||||||
|
break;
|
||||||
|
case ScrollingDirection.Down:
|
||||||
|
position.Y += NotePiece.NOTE_HEIGHT / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (c) 2007-2018 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.Input.Events;
|
||||||
|
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class NotePlacementBlueprint : ManiaPlacementBlueprint<Note>
|
||||||
|
{
|
||||||
|
public NotePlacementBlueprint()
|
||||||
|
: base(new Note())
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
InternalChild = new EditNotePiece { RelativeSizeAxes = Axes.X };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
Width = SnappedWidth;
|
||||||
|
Position = SnappedMousePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnClick(ClickEvent e)
|
||||||
|
{
|
||||||
|
Column column;
|
||||||
|
if ((column = ColumnAt(e.ScreenSpaceMousePosition)) == null)
|
||||||
|
return base.OnClick(e);
|
||||||
|
|
||||||
|
HitObject.StartTime = TimeAt(e.ScreenSpaceMousePosition);
|
||||||
|
HitObject.Column = column.Index;
|
||||||
|
|
||||||
|
EndPlacement();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
osu.Game.Rulesets.Mania/Edit/IManiaHitObjectComposer.cs
Normal file
13
osu.Game.Rulesets.Mania/Edit/IManiaHitObjectComposer.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
|
{
|
||||||
|
public interface IManiaHitObjectComposer
|
||||||
|
{
|
||||||
|
Column ColumnAt(Vector2 screenSpacePosition);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Tools;
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
@ -11,17 +10,29 @@ using osu.Game.Rulesets.Objects.Drawables;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
{
|
{
|
||||||
public class ManiaHitObjectComposer : HitObjectComposer<ManiaHitObject>
|
[Cached(Type = typeof(IManiaHitObjectComposer))]
|
||||||
|
public class ManiaHitObjectComposer : HitObjectComposer<ManiaHitObject>, IManiaHitObjectComposer
|
||||||
{
|
{
|
||||||
|
protected new ManiaEditRulesetContainer RulesetContainer { get; private set; }
|
||||||
|
|
||||||
public ManiaHitObjectComposer(Ruleset ruleset)
|
public ManiaHitObjectComposer(Ruleset ruleset)
|
||||||
: base(ruleset)
|
: base(ruleset)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the column that intersects a screen-space position.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="screenSpacePosition">The screen-space position.</param>
|
||||||
|
/// <returns>The column which intersects with <paramref name="screenSpacePosition"/>.</returns>
|
||||||
|
public Column ColumnAt(Vector2 screenSpacePosition) => RulesetContainer.GetColumnByPosition(screenSpacePosition);
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
@ -29,15 +40,18 @@ namespace osu.Game.Rulesets.Mania.Edit
|
|||||||
|
|
||||||
protected override RulesetContainer<ManiaHitObject> CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
protected override RulesetContainer<ManiaHitObject> CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||||
{
|
{
|
||||||
var rulesetContainer = new ManiaEditRulesetContainer(ruleset, beatmap);
|
RulesetContainer = new ManiaEditRulesetContainer(ruleset, beatmap);
|
||||||
|
|
||||||
// This is the earliest we can cache the scrolling info to ourselves, before masks are added to the hierarchy and inject it
|
// This is the earliest we can cache the scrolling info to ourselves, before masks are added to the hierarchy and inject it
|
||||||
dependencies.CacheAs(rulesetContainer.ScrollingInfo);
|
dependencies.CacheAs(RulesetContainer.ScrollingInfo);
|
||||||
|
|
||||||
return rulesetContainer;
|
return RulesetContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => Array.Empty<HitObjectCompositionTool>();
|
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
||||||
|
{
|
||||||
|
new NoteCompositionTool()
|
||||||
|
};
|
||||||
|
|
||||||
public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
|
public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
|
20
osu.Game.Rulesets.Mania/Edit/NoteCompositionTool.cs
Normal file
20
osu.Game.Rulesets.Mania/Edit/NoteCompositionTool.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
|
{
|
||||||
|
public class NoteCompositionTool : HitObjectCompositionTool
|
||||||
|
{
|
||||||
|
public NoteCompositionTool()
|
||||||
|
: base(nameof(Note))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override PlacementBlueprint CreatePlacementBlueprint() => new NotePlacementBlueprint();
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,7 @@ using osu.Framework.Input.Bindings;
|
|||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Mania.UI.Components;
|
using osu.Game.Rulesets.Mania.UI.Components;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
@ -21,6 +22,11 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
private const float column_width = 45;
|
private const float column_width = 45;
|
||||||
private const float special_column_width = 70;
|
private const float special_column_width = 70;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The index of this column as part of the whole playfield.
|
||||||
|
/// </summary>
|
||||||
|
public readonly int Index;
|
||||||
|
|
||||||
public readonly Bindable<ManiaAction> Action = new Bindable<ManiaAction>();
|
public readonly Bindable<ManiaAction> Action = new Bindable<ManiaAction>();
|
||||||
|
|
||||||
private readonly ColumnBackground background;
|
private readonly ColumnBackground background;
|
||||||
@ -30,8 +36,10 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
internal readonly Container TopLevelContainer;
|
internal readonly Container TopLevelContainer;
|
||||||
private readonly Container explosionContainer;
|
private readonly Container explosionContainer;
|
||||||
|
|
||||||
public Column()
|
public Column(int index)
|
||||||
{
|
{
|
||||||
|
Index = index;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
Width = column_width;
|
Width = column_width;
|
||||||
|
|
||||||
@ -172,5 +180,9 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool OnReleased(ManiaAction action) => false;
|
public bool OnReleased(ManiaAction action) => false;
|
||||||
|
|
||||||
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos)
|
||||||
|
// This probably shouldn't exist as is, but the columns in the stage are separated by a 1px border
|
||||||
|
=> DrawRectangle.Inflate(new Vector2(ManiaStage.COLUMN_SPACING / 2, 0)).Contains(ToLocalSpace(screenSpacePos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@ -17,6 +18,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
{
|
{
|
||||||
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
||||||
|
|
||||||
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => stages.Any(s => s.ReceivePositionalInputAt(screenSpacePos));
|
||||||
|
|
||||||
public ManiaPlayfield(List<StageDefinition> stageDefinitions)
|
public ManiaPlayfield(List<StageDefinition> stageDefinitions)
|
||||||
{
|
{
|
||||||
if (stageDefinitions == null)
|
if (stageDefinitions == null)
|
||||||
@ -56,6 +59,33 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
public void Add(BarLine barline) => stages.ForEach(s => s.Add(barline));
|
public void Add(BarLine barline) => stages.ForEach(s => s.Add(barline));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a column from a screen-space position.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="screenSpacePosition">The screen-space position.</param>
|
||||||
|
/// <returns>The column which the <paramref name="screenSpacePosition"/> lies in.</returns>
|
||||||
|
public Column GetColumnByPosition(Vector2 screenSpacePosition)
|
||||||
|
{
|
||||||
|
Column found = null;
|
||||||
|
|
||||||
|
foreach (var stage in stages)
|
||||||
|
{
|
||||||
|
foreach (var column in stage.Columns)
|
||||||
|
{
|
||||||
|
if (column.ReceivePositionalInputAt(screenSpacePosition))
|
||||||
|
{
|
||||||
|
found = column;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
private ManiaStage getStageByColumn(int column)
|
private ManiaStage getStageByColumn(int column)
|
||||||
{
|
{
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
@ -25,6 +25,7 @@ using osu.Game.Rulesets.Replays;
|
|||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
@ -80,6 +81,13 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
Config.BindWith(ManiaSetting.ScrollTime, TimeRange);
|
Config.BindWith(ManiaSetting.ScrollTime, TimeRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the column that intersects a screen-space position.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="screenSpacePosition">The screen-space position.</param>
|
||||||
|
/// <returns>The column which intersects with <paramref name="screenSpacePosition"/>.</returns>
|
||||||
|
public Column GetColumnByPosition(Vector2 screenSpacePosition) => Playfield.GetColumnByPosition(screenSpacePosition);
|
||||||
|
|
||||||
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
|
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
|
@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ManiaStage : ScrollingPlayfield
|
public class ManiaStage : ScrollingPlayfield
|
||||||
{
|
{
|
||||||
|
public const float COLUMN_SPACING = 1;
|
||||||
|
|
||||||
public const float HIT_TARGET_POSITION = 50;
|
public const float HIT_TARGET_POSITION = 50;
|
||||||
|
|
||||||
public IReadOnlyList<Column> Columns => columnFlow.Children;
|
public IReadOnlyList<Column> Columns => columnFlow.Children;
|
||||||
@ -40,6 +42,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
private List<Color4> normalColumnColours = new List<Color4>();
|
private List<Color4> normalColumnColours = new List<Color4>();
|
||||||
private Color4 specialColumnColour;
|
private Color4 specialColumnColour;
|
||||||
|
|
||||||
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Columns.Any(c => c.ReceivePositionalInputAt(screenSpacePos));
|
||||||
|
|
||||||
private readonly int firstColumnIndex;
|
private readonly int firstColumnIndex;
|
||||||
|
|
||||||
public ManiaStage(int firstColumnIndex, StageDefinition definition, ref ManiaAction normalColumnStartAction, ref ManiaAction specialColumnStartAction)
|
public ManiaStage(int firstColumnIndex, StageDefinition definition, ref ManiaAction normalColumnStartAction, ref ManiaAction specialColumnStartAction)
|
||||||
@ -84,8 +88,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
AutoSizeAxes = Axes.X,
|
AutoSizeAxes = Axes.X,
|
||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
Padding = new MarginPadding { Left = 1, Right = 1 },
|
Padding = new MarginPadding { Left = COLUMN_SPACING, Right = COLUMN_SPACING },
|
||||||
Spacing = new Vector2(1, 0)
|
Spacing = new Vector2(COLUMN_SPACING, 0)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -123,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
for (int i = 0; i < definition.Columns; i++)
|
for (int i = 0; i < definition.Columns; i++)
|
||||||
{
|
{
|
||||||
var isSpecial = definition.IsSpecialColumn(i);
|
var isSpecial = definition.IsSpecialColumn(i);
|
||||||
var column = new Column
|
var column = new Column(firstColumnIndex + i)
|
||||||
{
|
{
|
||||||
IsSpecial = isSpecial,
|
IsSpecial = isSpecial,
|
||||||
Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ }
|
Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ }
|
||||||
|
@ -68,9 +68,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
// Process object
|
// Process object
|
||||||
var processor = ruleset.CreateBeatmapProcessor(beatmap);
|
var processor = ruleset.CreateBeatmapProcessor(beatmap);
|
||||||
|
|
||||||
processor.PreProcess();
|
processor?.PreProcess();
|
||||||
tObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
|
tObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
|
||||||
processor.PostProcess();
|
processor?.PostProcess();
|
||||||
|
|
||||||
// Add visual representation
|
// Add visual representation
|
||||||
var drawableObject = rulesetContainer.GetVisualRepresentation(tObject);
|
var drawableObject = rulesetContainer.GetVisualRepresentation(tObject);
|
||||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
{
|
{
|
||||||
public abstract class HitObjectComposer : CompositeDrawable
|
public abstract class HitObjectComposer : CompositeDrawable
|
||||||
{
|
{
|
||||||
public IEnumerable<DrawableHitObject> HitObjects => rulesetContainer.Playfield.AllHitObjects;
|
public IEnumerable<DrawableHitObject> HitObjects => RulesetContainer.Playfield.AllHitObjects;
|
||||||
|
|
||||||
protected readonly Ruleset Ruleset;
|
protected readonly Ruleset Ruleset;
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
private readonly List<Container> layerContainers = new List<Container>();
|
private readonly List<Container> layerContainers = new List<Container>();
|
||||||
|
|
||||||
private EditRulesetContainer rulesetContainer;
|
protected EditRulesetContainer RulesetContainer { get; private set; }
|
||||||
|
|
||||||
private BlueprintContainer blueprintContainer;
|
private BlueprintContainer blueprintContainer;
|
||||||
|
|
||||||
@ -54,8 +54,8 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
rulesetContainer = CreateRulesetContainer();
|
RulesetContainer = CreateRulesetContainer();
|
||||||
rulesetContainer.Clock = framedClock;
|
RulesetContainer.Clock = framedClock;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
layerBelowRuleset,
|
layerBelowRuleset,
|
||||||
rulesetContainer,
|
RulesetContainer,
|
||||||
layerAboveRuleset
|
layerAboveRuleset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,25 +140,25 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
layerContainers.ForEach(l =>
|
layerContainers.ForEach(l =>
|
||||||
{
|
{
|
||||||
l.Anchor = rulesetContainer.Playfield.Anchor;
|
l.Anchor = RulesetContainer.Playfield.Anchor;
|
||||||
l.Origin = rulesetContainer.Playfield.Origin;
|
l.Origin = RulesetContainer.Playfield.Origin;
|
||||||
l.Position = rulesetContainer.Playfield.Position;
|
l.Position = RulesetContainer.Playfield.Position;
|
||||||
l.Size = rulesetContainer.Playfield.Size;
|
l.Size = RulesetContainer.Playfield.Size;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the user's cursor is currently in an area of the <see cref="HitObjectComposer"/> that is valid for placement.
|
/// Whether the user's cursor is currently in an area of the <see cref="HitObjectComposer"/> that is valid for placement.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual bool CursorInPlacementArea => rulesetContainer.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
|
public virtual bool CursorInPlacementArea => RulesetContainer.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="HitObject"/> to the <see cref="Beatmaps.Beatmap"/> and visualises it.
|
/// Adds a <see cref="HitObject"/> to the <see cref="Beatmaps.Beatmap"/> and visualises it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hitObject">The <see cref="HitObject"/> to add.</param>
|
/// <param name="hitObject">The <see cref="HitObject"/> to add.</param>
|
||||||
public void Add(HitObject hitObject) => blueprintContainer.AddBlueprintFor(rulesetContainer.Add(hitObject));
|
public void Add(HitObject hitObject) => blueprintContainer.AddBlueprintFor(RulesetContainer.Add(hitObject));
|
||||||
|
|
||||||
public void Remove(HitObject hitObject) => blueprintContainer.RemoveBlueprintFor(rulesetContainer.Remove(hitObject));
|
public void Remove(HitObject hitObject) => blueprintContainer.RemoveBlueprintFor(RulesetContainer.Remove(hitObject));
|
||||||
|
|
||||||
internal abstract EditRulesetContainer CreateRulesetContainer();
|
internal abstract EditRulesetContainer CreateRulesetContainer();
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input;
|
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -20,7 +19,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A blueprint which governs the creation of a new <see cref="HitObject"/> to actualisation.
|
/// A blueprint which governs the creation of a new <see cref="HitObject"/> to actualisation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class PlacementBlueprint : CompositeDrawable, IStateful<PlacementState>, IRequireHighFrequencyMousePosition
|
public abstract class PlacementBlueprint : CompositeDrawable, IStateful<PlacementState>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when <see cref="State"/> has changed.
|
/// Invoked when <see cref="State"/> has changed.
|
||||||
@ -50,6 +49,10 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
// This is required to allow the blueprint's position to be updated via OnMouseMove/Handle
|
||||||
|
// on the same frame it is made visible via a PlacementState change.
|
||||||
|
AlwaysPresent = true;
|
||||||
|
|
||||||
Alpha = 0;
|
Alpha = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,18 +15,14 @@ namespace osu.Game.Tests.Visual
|
|||||||
[Cached(Type = typeof(IPlacementHandler))]
|
[Cached(Type = typeof(IPlacementHandler))]
|
||||||
public abstract class PlacementBlueprintTestCase : OsuTestCase, IPlacementHandler
|
public abstract class PlacementBlueprintTestCase : OsuTestCase, IPlacementHandler
|
||||||
{
|
{
|
||||||
private readonly Container hitObjectContainer;
|
protected readonly Container HitObjectContainer;
|
||||||
private PlacementBlueprint currentBlueprint;
|
private PlacementBlueprint currentBlueprint;
|
||||||
|
|
||||||
protected PlacementBlueprintTestCase()
|
protected PlacementBlueprintTestCase()
|
||||||
{
|
{
|
||||||
Beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize = 2;
|
Beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize = 2;
|
||||||
|
|
||||||
Add(hitObjectContainer = new Container
|
Add(HitObjectContainer = CreateHitObjectContainer());
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Clock = new FramedClock(new StopwatchClock())
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -49,7 +45,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
public void EndPlacement(HitObject hitObject)
|
public void EndPlacement(HitObject hitObject)
|
||||||
{
|
{
|
||||||
hitObjectContainer.Add(CreateHitObject(hitObject));
|
AddHitObject(CreateHitObject(hitObject));
|
||||||
|
|
||||||
Remove(currentBlueprint);
|
Remove(currentBlueprint);
|
||||||
Add(currentBlueprint = CreateBlueprint());
|
Add(currentBlueprint = CreateBlueprint());
|
||||||
@ -59,6 +55,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual Container CreateHitObjectContainer() => new Container { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
|
protected virtual void AddHitObject(DrawableHitObject hitObject) => HitObjectContainer.Add(hitObject);
|
||||||
|
|
||||||
protected abstract DrawableHitObject CreateHitObject(HitObject hitObject);
|
protected abstract DrawableHitObject CreateHitObject(HitObject hitObject);
|
||||||
protected abstract PlacementBlueprint CreateBlueprint();
|
protected abstract PlacementBlueprint CreateBlueprint();
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
public double TimeRange { set => scrollingInfo.TimeRange.Value = value; }
|
public double TimeRange { set => scrollingInfo.TimeRange.Value = value; }
|
||||||
|
|
||||||
|
public IScrollingInfo ScrollingInfo => scrollingInfo;
|
||||||
|
|
||||||
[Cached(Type = typeof(IScrollingInfo))]
|
[Cached(Type = typeof(IScrollingInfo))]
|
||||||
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
|
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user