2017-02-07 12:59:30 +08:00
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
2016-09-02 18:25:13 +08:00
2016-11-14 16:23:33 +08:00
using System ;
2016-09-02 18:25:13 +08:00
using System.Collections.Generic ;
2016-11-14 16:23:33 +08:00
using System.Linq ;
using osu.Framework.Allocation ;
2016-09-02 19:30:27 +08:00
using osu.Framework.Graphics ;
2016-09-02 18:25:13 +08:00
using osu.Framework.Graphics.Containers ;
2016-11-14 17:03:20 +08:00
using osu.Game.Modes.Objects ;
2016-11-14 18:49:29 +08:00
using osu.Game.Modes.Objects.Drawables ;
2017-02-09 13:56:39 +08:00
using osu.Game.Beatmaps ;
2017-03-06 14:24:00 +08:00
using osu.Game.Screens.Play ;
2017-03-07 18:30:39 +08:00
using OpenTK ;
2016-09-02 18:25:13 +08:00
2016-11-14 17:54:24 +08:00
namespace osu.Game.Modes.UI
2016-09-02 18:25:13 +08:00
{
2016-10-19 18:44:03 +08:00
public abstract class HitRenderer : Container
{
2016-11-29 20:28:43 +08:00
public event Action < JudgementInfo > OnJudgement ;
2016-11-29 22:59:56 +08:00
public event Action OnAllJudged ;
2017-03-07 18:30:39 +08:00
internal readonly PlayerInputManager InputManager = new PlayerInputManager ( ) ;
/// <summary>
/// A function to convert coordinates from gamefield to screen space.
/// </summary>
public abstract Func < Vector2 , Vector2 > MapPlayfieldToScreenSpace { get ; }
2017-03-06 12:59:11 +08:00
public abstract bool AllObjectsJudged { get ; }
2017-02-28 19:14:48 +08:00
2016-11-29 22:59:56 +08:00
protected void TriggerOnJudgement ( JudgementInfo j )
{
OnJudgement ? . Invoke ( j ) ;
if ( AllObjectsJudged )
OnAllJudged ? . Invoke ( ) ;
}
2017-03-06 12:59:11 +08:00
}
2016-11-02 13:07:20 +08:00
2017-03-06 12:59:11 +08:00
public abstract class HitRenderer < TObject > : HitRenderer
where TObject : HitObject
{
private List < TObject > objects ;
2016-11-02 13:07:20 +08:00
2017-03-06 12:59:11 +08:00
protected Playfield < TObject > Playfield ;
2016-10-19 18:44:03 +08:00
2017-03-07 18:30:39 +08:00
public override Func < Vector2 , Vector2 > MapPlayfieldToScreenSpace = > Playfield . ScaledContent . ToScreenSpace ;
2017-03-06 12:59:11 +08:00
public override bool AllObjectsJudged = > Playfield . HitObjects . Children . First ( ) ? . Judgement . Result ! = null ; //reverse depth sort means First() instead of Last().
public IEnumerable < DrawableHitObject > DrawableObjects = > Playfield . HitObjects . Children ;
2016-09-02 19:30:27 +08:00
2017-02-09 13:56:39 +08:00
public Beatmap Beatmap
2016-10-01 17:40:14 +08:00
{
2016-10-13 09:10:15 +08:00
set
{
objects = Convert ( value ) ;
if ( IsLoaded )
loadObjects ( ) ;
}
2016-10-01 17:40:14 +08:00
}
2017-03-06 12:59:11 +08:00
protected abstract Playfield < TObject > CreatePlayfield ( ) ;
2016-10-13 09:10:15 +08:00
2017-03-06 12:59:11 +08:00
protected abstract HitObjectConverter < TObject > Converter { get ; }
2016-10-13 21:14:18 +08:00
2017-03-06 12:59:11 +08:00
protected virtual List < TObject > Convert ( Beatmap beatmap ) = > Converter . Convert ( beatmap ) ;
2016-10-13 09:10:15 +08:00
2017-03-07 09:59:19 +08:00
protected HitRenderer ( )
2016-09-02 19:30:27 +08:00
{
2016-10-13 09:10:15 +08:00
RelativeSizeAxes = Axes . Both ;
2017-03-07 18:30:39 +08:00
InputManager . Add ( content = new Container
{
RelativeSizeAxes = Axes . Both ,
Children = new [ ]
{
Playfield = CreatePlayfield ( ) ,
}
} ) ;
AddInternal ( InputManager ) ;
2016-11-13 01:34:36 +08:00
}
2016-10-13 09:10:15 +08:00
2017-03-07 18:30:39 +08:00
protected override Container < Drawable > Content = > content ;
private Container content ;
2016-11-13 01:34:36 +08:00
[BackgroundDependencyLoader]
private void load ( )
{
2016-10-13 09:10:15 +08:00
loadObjects ( ) ;
}
private void loadObjects ( )
{
if ( objects = = null ) return ;
2017-03-06 12:59:11 +08:00
foreach ( TObject h in objects )
2016-10-19 18:44:03 +08:00
{
2017-03-06 12:59:11 +08:00
DrawableHitObject < TObject > drawableObject = GetVisualRepresentation ( h ) ;
2016-10-19 18:44:03 +08:00
if ( drawableObject = = null ) continue ;
2016-11-29 20:28:43 +08:00
drawableObject . OnJudgement + = onJudgement ;
2016-10-19 18:44:03 +08:00
2016-11-02 13:07:20 +08:00
Playfield . Add ( drawableObject ) ;
2016-10-19 18:44:03 +08:00
}
2017-02-10 13:16:23 +08:00
Playfield . PostProcess ( ) ;
2016-10-19 18:44:03 +08:00
}
2017-03-06 12:59:11 +08:00
private void onJudgement ( DrawableHitObject < TObject > o , JudgementInfo j ) = > TriggerOnJudgement ( j ) ;
2016-10-13 09:10:15 +08:00
2017-03-06 12:59:11 +08:00
protected abstract DrawableHitObject < TObject > GetVisualRepresentation ( TObject h ) ;
2016-09-02 18:25:13 +08:00
}
}