// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; using osuTK; namespace osu.Game.Rulesets.Catch.UI { public class CatchPlayfield : ScrollingPlayfield { /// /// The width of the playfield. /// The horizontal movement of the catcher is confined in the area of this width. /// public const float WIDTH = 512; /// /// The center position of the playfield. /// public const float CENTER_X = WIDTH / 2; [Cached] private readonly DroppedObjectContainer droppedObjectContainer; internal readonly CatcherArea CatcherArea; public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => // only check the X position; handle all vertical space. base.ReceivePositionalInputAt(new Vector2(screenSpacePos.X, ScreenSpaceDrawQuad.Centre.Y)); public CatchPlayfield(BeatmapDifficulty difficulty) { CatcherArea = new CatcherArea(difficulty) { Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, }; InternalChildren = new[] { droppedObjectContainer = new DroppedObjectContainer(), CatcherArea.MovableCatcher.CreateProxiedContent(), HitObjectContainer.CreateProxy(), // This ordering (`CatcherArea` before `HitObjectContainer`) is important to // make sure the up-to-date catcher position is used for the catcher catching logic of hit objects. CatcherArea, HitObjectContainer, }; } [BackgroundDependencyLoader] private void load() { RegisterPool(50); RegisterPool(50); RegisterPool(100); RegisterPool(100); RegisterPool(10); RegisterPool(2); } protected override void LoadComplete() { base.LoadComplete(); // these subscriptions need to be done post constructor to ensure externally bound components have a chance to populate required fields (ScoreProcessor / ComboAtJudgement in this case). NewResult += onNewResult; RevertResult += onRevertResult; } protected override void OnNewDrawableHitObject(DrawableHitObject d) { ((DrawableCatchHitObject)d).CheckPosition = checkIfWeCanCatch; } private bool checkIfWeCanCatch(CatchHitObject obj) => CatcherArea.MovableCatcher.CanCatch(obj); private void onNewResult(DrawableHitObject judgedObject, JudgementResult result) => CatcherArea.OnNewResult((DrawableCatchHitObject)judgedObject, result); private void onRevertResult(DrawableHitObject judgedObject, JudgementResult result) => CatcherArea.OnRevertResult((DrawableCatchHitObject)judgedObject, result); } }