1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 03:03:21 +08:00

Implement note placement

This commit is contained in:
smoogipoo 2018-11-12 18:24:18 +09:00
parent a0c75a0597
commit 3a1fee59fb
10 changed files with 160 additions and 22 deletions

View File

@ -49,8 +49,8 @@ namespace osu.Game.Rulesets.Mania.Tests
Spacing = new Vector2(20, 0),
Children = new[]
{
createColumn(ScrollingDirection.Up, ManiaAction.Key1),
createColumn(ScrollingDirection.Down, ManiaAction.Key2)
createColumn(ScrollingDirection.Up, ManiaAction.Key1, 0),
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,
Origin = Anchor.Centre,

View File

@ -0,0 +1,74 @@
// 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.Edit.Blueprints.Components;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.UI.Scrolling;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
public class NotePlacementBlueprint : PlacementBlueprint
{
protected new Note HitObject => (Note)base.HitObject;
[Resolved]
private ManiaHitObjectComposer composer { get; set; }
[Resolved]
private IScrollingInfo scrollingInfo { get; set; }
public NotePlacementBlueprint()
: base(new Note())
{
RelativeSizeAxes = Axes.None;
Origin = Anchor.Centre;
AutoSizeAxes = Axes.Y;
Width = 45;
InternalChild = new EditNotePiece { RelativeSizeAxes = Axes.X };
}
protected override bool OnMouseMove(MouseMoveEvent e)
{
Position = e.MousePosition;
return true;
}
protected override bool OnClick(ClickEvent e)
{
var offsetPosition = e.ScreenSpaceMousePosition;
switch (scrollingInfo.Direction.Value)
{
case ScrollingDirection.Up:
offsetPosition.Y -= DrawHeight / 2;
break;
case ScrollingDirection.Down:
offsetPosition.Y += DrawHeight / 2;
break;
}
var column = composer.ColumnAt(offsetPosition);
if (column == null)
return base.OnClick(e);
var hitObjectContainer = column.HitObjectContainer;
HitObject.StartTime = scrollingInfo.Algorithm.TimeAt(hitObjectContainer.ToLocalSpace(offsetPosition).Y,
EditorClock.CurrentTime,
scrollingInfo.TimeRange.Value,
hitObjectContainer.DrawHeight);
HitObject.Column = column.Index;
EndPlacement();
return true;
}
}
}

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 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;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
@ -11,10 +10,13 @@ using osu.Game.Rulesets.Objects.Drawables;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Game.Rulesets.Mania.Edit.Blueprints;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.UI;
using OpenTK;
namespace osu.Game.Rulesets.Mania.Edit
{
[Cached]
public class ManiaHitObjectComposer : HitObjectComposer<ManiaHitObject>
{
public ManiaHitObjectComposer(Ruleset ruleset)
@ -27,6 +29,8 @@ namespace osu.Game.Rulesets.Mania.Edit
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
public Column ColumnAt(Vector2 screenSpacePosition) => ((ManiaPlayfield)RulesetContainer.Playfield).GetColumnByPosition(screenSpacePosition);
protected override RulesetContainer<ManiaHitObject> CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
{
var rulesetContainer = new ManiaEditRulesetContainer(ruleset, beatmap);
@ -37,7 +41,10 @@ namespace osu.Game.Rulesets.Mania.Edit
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)
{

View 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();
}
}

View File

@ -21,6 +21,11 @@ namespace osu.Game.Rulesets.Mania.UI
private const float column_width = 45;
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>();
private readonly ColumnBackground background;
@ -30,8 +35,10 @@ namespace osu.Game.Rulesets.Mania.UI
internal readonly Container TopLevelContainer;
private readonly Container explosionContainer;
public Column()
public Column(int index)
{
Index = index;
RelativeSizeAxes = Axes.Y;
Width = column_width;

View File

@ -54,6 +54,33 @@ namespace osu.Game.Rulesets.Mania.UI
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)
{
int sum = 0;

View File

@ -123,7 +123,7 @@ namespace osu.Game.Rulesets.Mania.UI
for (int i = 0; i < definition.Columns; i++)
{
var isSpecial = definition.IsSpecialColumn(i);
var column = new Column
var column = new Column(firstColumnIndex + i)
{
IsSpecial = isSpecial,
Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ }

View File

@ -68,9 +68,9 @@ namespace osu.Game.Rulesets.Edit
// Process object
var processor = ruleset.CreateBeatmapProcessor(beatmap);
processor.PreProcess();
processor?.PreProcess();
tObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
processor.PostProcess();
processor?.PostProcess();
// Add visual representation
var drawableObject = rulesetContainer.GetVisualRepresentation(tObject);

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Edit
{
public abstract class HitObjectComposer : CompositeDrawable
{
public IEnumerable<DrawableHitObject> HitObjects => rulesetContainer.Playfield.AllHitObjects;
public IEnumerable<DrawableHitObject> HitObjects => RulesetContainer.Playfield.AllHitObjects;
protected readonly Ruleset Ruleset;
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Edit
private readonly List<Container> layerContainers = new List<Container>();
private EditRulesetContainer rulesetContainer;
protected EditRulesetContainer RulesetContainer { get; private set; }
private BlueprintContainer blueprintContainer;
@ -51,8 +51,8 @@ namespace osu.Game.Rulesets.Edit
try
{
rulesetContainer = CreateRulesetContainer();
rulesetContainer.Clock = framedClock;
RulesetContainer = CreateRulesetContainer();
RulesetContainer.Clock = framedClock;
}
catch (Exception e)
{
@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Edit
layerBelowRuleset.Child = new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both };
var layerAboveRuleset = CreateLayerContainer();
layerAboveRuleset.Child = new BlueprintContainer();
layerAboveRuleset.Child = blueprintContainer = new BlueprintContainer();
layerContainers.Add(layerBelowRuleset);
layerContainers.Add(layerAboveRuleset);
@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.Edit
Children = new Drawable[]
{
layerBelowRuleset,
rulesetContainer,
RulesetContainer,
layerAboveRuleset
}
}
@ -130,10 +130,10 @@ namespace osu.Game.Rulesets.Edit
layerContainers.ForEach(l =>
{
l.Anchor = rulesetContainer.Playfield.Anchor;
l.Origin = rulesetContainer.Playfield.Origin;
l.Position = rulesetContainer.Playfield.Position;
l.Size = rulesetContainer.Playfield.Size;
l.Anchor = RulesetContainer.Playfield.Anchor;
l.Origin = RulesetContainer.Playfield.Origin;
l.Position = RulesetContainer.Playfield.Position;
l.Size = RulesetContainer.Playfield.Size;
});
}
@ -141,9 +141,9 @@ namespace osu.Game.Rulesets.Edit
/// Adds a <see cref="HitObject"/> to the <see cref="Beatmaps.Beatmap"/> and visualises it.
/// </summary>
/// <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();

View File

@ -85,6 +85,9 @@ namespace osu.Game.Tests.Visual
public float PositionAt(double time, double currentTime, double timeRange, float scrollLength)
=> implementation.PositionAt(time, currentTime, timeRange, scrollLength);
public double TimeAt(float position, double currentTime, double timeRange, float scrollLength)
=> implementation.TimeAt(position, currentTime, timeRange, scrollLength);
public void Reset()
=> implementation.Reset();
}