1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 10:42:54 +08:00
osu-lazer/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
Bartłomiej Dach 9323df26a1 Decouple bar line hitobjects from generator
Introduce an IBarLine interface, which together with generic constraints
helps decouple BarLineGenerator from the actual hitobject types it
creates. Thanks to this, all rulesets that want bar lines can provide
an implementation of IBarLine that also derives from the base hitobject
class.

This allows DrawableBarLines in taiko and mania to be migrated back to
DrawableTaikoHitObject and DrawableManiaHitObject base classes
respectively. This in turn resolves #6215 without code duplication,
since the missing anchoring application is now done in mania's
DrawableBarLine through deriving from DrawableManiaHitObject.
2019-09-25 00:36:27 +02:00

108 lines
3.6 KiB
C#

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
using osuTK;
namespace osu.Game.Rulesets.Mania.UI
{
public class ManiaPlayfield : ScrollingPlayfield
{
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)
{
if (stageDefinitions == null)
throw new ArgumentNullException(nameof(stageDefinitions));
if (stageDefinitions.Count <= 0)
throw new ArgumentException("Can't have zero or fewer stages.");
GridContainer playfieldGrid;
AddInternal(playfieldGrid = new GridContainer
{
RelativeSizeAxes = Axes.Both,
Content = new[] { new Drawable[stageDefinitions.Count] }
});
var normalColumnAction = ManiaAction.Key1;
var specialColumnAction = ManiaAction.Special1;
int firstColumnIndex = 0;
for (int i = 0; i < stageDefinitions.Count; i++)
{
var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction);
playfieldGrid.Content[0][i] = newStage;
stages.Add(newStage);
AddNested(newStage);
firstColumnIndex += newStage.Columns.Count;
}
}
public override void Add(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Add(h);
public override bool Remove(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Remove(h);
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;
}
/// <summary>
/// Retrieves the total amount of columns across all stages in this playfield.
/// </summary>
public int TotalColumns => stages.Sum(s => s.Columns.Count);
private ManiaStage getStageByColumn(int column)
{
int sum = 0;
foreach (var stage in stages)
{
sum = sum + stage.Columns.Count;
if (sum > column)
return stage;
}
return null;
}
}
}