1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 07:22:54 +08:00

Make Playfield not a ScalableContainer

This commit is contained in:
smoogipoo 2018-09-21 14:02:32 +09:00
parent 7efaaceba5
commit 826dc6ceb7
10 changed files with 143 additions and 167 deletions

View File

@ -25,7 +25,6 @@ namespace osu.Game.Rulesets.Catch.UI
protected override bool UserScrollSpeedAdjustment => false;
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
: base(BASE_WIDTH)
{
Direction.Value = ScrollingDirection.Down;
@ -34,27 +33,36 @@ namespace osu.Game.Rulesets.Catch.UI
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
base.Content.Anchor = Anchor.BottomLeft;
base.Content.Origin = Anchor.BottomLeft;
base.Content.AddRange(new Drawable[]
InternalChild = new Container
{
explodingFruitContainer = new Container
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
FillAspectRatio = 4f / 3,
Child = new ScalingContainer(BASE_WIDTH)
{
RelativeSizeAxes = Axes.Both,
},
catcherArea = new CatcherArea(difficulty)
{
GetVisualRepresentation = getVisualRepresentation,
ExplodingFruitTarget = explodingFruitContainer,
Anchor = Anchor.BottomLeft,
Origin = Anchor.TopLeft,
},
content = new Container<Drawable>
{
RelativeSizeAxes = Axes.Both,
},
});
Children = new Drawable[]
{
explodingFruitContainer = new Container
{
RelativeSizeAxes = Axes.Both,
},
catcherArea = new CatcherArea(difficulty)
{
GetVisualRepresentation = getVisualRepresentation,
ExplodingFruitTarget = explodingFruitContainer,
Anchor = Anchor.BottomLeft,
Origin = Anchor.TopLeft,
},
content = new Container<Drawable>
{
RelativeSizeAxes = Axes.Both,
},
}
}
};
}
public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj);

View File

@ -0,0 +1,29 @@
// 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.Containers;
using OpenTK;
namespace osu.Game.Rulesets.Catch.UI
{
/// <summary>
/// A <see cref="Container"/> which scales its content relative to a target width.
/// </summary>
public class ScalingContainer : Container
{
private readonly float targetWidth;
public ScalingContainer(float targetWidth)
{
this.targetWidth = targetWidth;
}
protected override void Update()
{
base.Update();
Scale = new Vector2(Parent.ChildSize.X / targetWidth);
Size = Vector2.Divide(Vector2.One, Scale);
}
}
}

View File

@ -3,6 +3,7 @@
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
@ -31,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Edit
new HitObjectCompositionTool<Spinner>()
};
protected override ScalableContainer CreateLayerContainer() => new ScalableContainer(OsuPlayfield.BASE_SIZE.X) { RelativeSizeAxes = Axes.Both };
protected override Container CreateLayerContainer() => new LayerContainer();
public override HitObjectMask CreateMaskFor(DrawableHitObject hitObject)
{
@ -45,5 +46,20 @@ namespace osu.Game.Rulesets.Osu.Edit
return base.CreateMaskFor(hitObject);
}
private class LayerContainer : Container
{
protected override Container<Drawable> Content => content;
private readonly Container content;
public LayerContainer()
{
RelativeSizeAxes = Axes.Both;
FillMode = FillMode.Fit;
FillAspectRatio = 4f / 3;
Child = content = new ScalingContainer(OsuPlayfield.BASE_SIZE.X) { RelativeSizeAxes = Axes.Both };
}
}
}
}

View File

@ -20,32 +20,46 @@ namespace osu.Game.Rulesets.Osu.UI
private readonly JudgementContainer<DrawableOsuJudgement> judgementLayer;
private readonly ConnectionRenderer<OsuHitObject> connectionLayer;
private readonly Container content;
protected override Container<Drawable> Content => content;
public static readonly Vector2 BASE_SIZE = new Vector2(512, 384);
public OsuPlayfield()
: base(BASE_SIZE.X)
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
AddRange(new Drawable[]
InternalChild = new Container
{
connectionLayer = new FollowPointRenderer
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
FillAspectRatio = 4f / 3,
Child = content = new ScalingContainer(BASE_SIZE.X)
{
RelativeSizeAxes = Axes.Both,
Depth = 2,
},
judgementLayer = new JudgementContainer<DrawableOsuJudgement>
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
},
approachCircles = new Container
{
RelativeSizeAxes = Axes.Both,
Depth = -1,
},
});
Children = new Drawable[]
{
connectionLayer = new FollowPointRenderer
{
RelativeSizeAxes = Axes.Both,
Depth = 2,
},
judgementLayer = new JudgementContainer<DrawableOsuJudgement>
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
},
approachCircles = new Container
{
RelativeSizeAxes = Axes.Both,
Depth = -1,
},
}
}
};
}
public override void Add(DrawableHitObject h)

View File

@ -4,7 +4,6 @@
using System.Linq;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Input;
using OpenTK;
using osu.Game.Beatmaps;
using osu.Game.Input.Handlers;
using osu.Game.Rulesets.Objects.Drawables;
@ -58,12 +57,6 @@ namespace osu.Game.Rulesets.Osu.UI
}
}
protected override Vector2 GetAspectAdjustedSize()
{
var aspectSize = DrawSize.X * 0.75f < DrawSize.Y ? new Vector2(DrawSize.X, DrawSize.X * 0.75f) : new Vector2(DrawSize.Y * 4f / 3f, DrawSize.Y);
return new Vector2(aspectSize.X / DrawSize.X, aspectSize.Y / DrawSize.Y);
}
protected override CursorContainer CreateCursor() => new GameplayCursor();
}
}

View File

@ -0,0 +1,29 @@
// 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.Containers;
using OpenTK;
namespace osu.Game.Rulesets.Osu.UI
{
/// <summary>
/// A <see cref="Container"/> which scales its content relative to a target width.
/// </summary>
public class ScalingContainer : Container
{
private readonly float targetWidth;
public ScalingContainer(float targetWidth)
{
this.targetWidth = targetWidth;
}
protected override void Update()
{
base.Update();
Scale = new Vector2(Parent.ChildSize.X / targetWidth);
Size = Vector2.Divide(Vector2.One, Scale);
}
}
}

View File

@ -165,6 +165,6 @@ namespace osu.Game.Rulesets.Edit
/// <summary>
/// Creates a <see cref="ScalableContainer"/> which provides a layer above or below the <see cref="Playfield"/>.
/// </summary>
protected virtual ScalableContainer CreateLayerContainer() => new ScalableContainer { RelativeSizeAxes = Axes.Both };
protected virtual Container CreateLayerContainer() => new Container { RelativeSizeAxes = Axes.Both };
}
}

View File

@ -9,18 +9,25 @@ using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Configuration;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using OpenTK;
namespace osu.Game.Rulesets.UI
{
public abstract class Playfield : ScalableContainer
public abstract class Playfield : Container
{
/// <summary>
/// The <see cref="DrawableHitObject"/> contained in this Playfield.
/// </summary>
public HitObjectContainer HitObjectContainer { get; private set; }
/// <summary>
/// A function that converts gamefield coordinates to screen space.
/// </summary>
public Func<Vector2, Vector2> GamefieldToScreenSpace => HitObjectContainer.ToScreenSpace;
/// <summary>
/// All the <see cref="DrawableHitObject"/>s contained in this <see cref="Playfield"/> and all <see cref="NestedPlayfields"/>.
/// </summary>
@ -39,16 +46,9 @@ namespace osu.Game.Rulesets.UI
public readonly BindableBool DisplayJudgements = new BindableBool(true);
/// <summary>
/// A container for keeping track of DrawableHitObjects.
/// Creates a new <see cref="Playfield"/>.
/// </summary>
/// <param name="customWidth">The width to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customHeight"/> is desired. If <paramref name="customHeight"/> is also null, no scaling will occur.
/// </param>
/// <param name="customHeight">The height to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customWidth"/> is desired. If <paramref name="customWidth"/> is also null, no scaling will occur.
/// </param>
protected Playfield(float? customWidth = null, float? customHeight = null)
: base(customWidth, customHeight)
protected Playfield()
{
RelativeSizeAxes = Axes.Both;
}

View File

@ -1,99 +0,0 @@
// 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.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using OpenTK;
namespace osu.Game.Rulesets.UI
{
/// <summary>
/// A <see cref="Container"/> which can have its internal coordinate system scaled to a specific size.
/// </summary>
public class ScalableContainer : Container
{
/// <summary>
/// A function that converts coordinates from gamefield to screen space.
/// </summary>
public Func<Vector2, Vector2> GamefieldToScreenSpace => scaledContent.GamefieldToScreenSpace;
/// <summary>
/// The scaled content.
/// </summary>
private readonly ScaledContainer scaledContent;
protected override Container<Drawable> Content => scaledContent;
/// <summary>
/// A <see cref="Container"/> which can have its internal coordinate system scaled to a specific size.
/// </summary>
/// <param name="customWidth">The width to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customHeight"/> is desired. If <paramref name="customHeight"/> is also null, no scaling will occur.
/// </param>
/// <param name="customHeight">The height to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customWidth"/> is desired. If <paramref name="customWidth"/> is also null, no scaling will occur.
/// </param>
public ScalableContainer(float? customWidth = null, float? customHeight = null)
{
AddInternal(scaledContent = new ScaledContainer
{
CustomWidth = customWidth,
CustomHeight = customHeight,
RelativeSizeAxes = Axes.Both,
});
}
private class ScaledContainer : Container
{
/// <summary>
/// A function that converts coordinates from gamefield to screen space.
/// </summary>
public Func<Vector2, Vector2> GamefieldToScreenSpace => content.ToScreenSpace;
/// <summary>
/// The value to scale the width of the content to match.
/// If null, <see cref="CustomHeight"/> is used.
/// </summary>
public float? CustomWidth;
/// <summary>
/// The value to scale the height of the content to match.
/// if null, <see cref="CustomWidth"/> is used.
/// </summary>
public float? CustomHeight;
private readonly Container content;
protected override Container<Drawable> Content => content;
public ScaledContainer()
{
AddInternal(content = new Container { RelativeSizeAxes = Axes.Both });
}
protected override void Update()
{
base.Update();
content.Scale = sizeScale;
content.Size = Vector2.Divide(Vector2.One, sizeScale);
}
/// <summary>
/// The scale that is required for the size of the content to match <see cref="CustomWidth"/> and <see cref="CustomHeight"/>.
/// </summary>
private Vector2 sizeScale
{
get
{
if (CustomWidth.HasValue && CustomHeight.HasValue)
return Vector2.Divide(DrawSize, new Vector2(CustomWidth.Value, CustomHeight.Value));
if (CustomWidth.HasValue)
return new Vector2(DrawSize.X / CustomWidth.Value);
if (CustomHeight.HasValue)
return new Vector2(DrawSize.Y / CustomHeight.Value);
return Vector2.One;
}
}
}
}
}

View File

@ -62,20 +62,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
/// </summary>
protected readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
/// <summary>
/// Creates a new <see cref="ScrollingPlayfield"/>.
/// </summary>
/// <param name="customWidth">The width to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customHeight"/> is desired. If <paramref name="customHeight"/> is also null, no scaling will occur.
/// </param>
/// <param name="customHeight">The height to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customWidth"/> is desired. If <paramref name="customWidth"/> is also null, no scaling will occur.
/// </param>
protected ScrollingPlayfield(float? customWidth = null, float? customHeight = null)
: base(customWidth, customHeight)
{
}
[BackgroundDependencyLoader]
private void load()
{