mirror of
https://github.com/ppy/osu.git
synced 2024-09-21 21:27:24 +08:00
Add initial game-wide beatmap flow.
This commit is contained in:
parent
0f5614ffa2
commit
74f1a9622f
@ -2,6 +2,7 @@
|
||||
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
@ -27,6 +28,8 @@ namespace osu.Game.Beatmaps.Drawable
|
||||
|
||||
private BeatmapGroupState state;
|
||||
|
||||
public IEnumerable<BeatmapPanel> BeatmapPanels;
|
||||
|
||||
public BeatmapGroupState State
|
||||
{
|
||||
get { return state; }
|
||||
@ -62,6 +65,16 @@ namespace osu.Game.Beatmaps.Drawable
|
||||
AutoSizeAxes = Axes.Y;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
BeatmapPanels = beatmapSet.Beatmaps.Select(b =>
|
||||
new BeatmapPanel(this.beatmapSet, b)
|
||||
{
|
||||
GainedSelection = panelGainedSelection,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
});
|
||||
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
new FlowContainer
|
||||
@ -87,15 +100,7 @@ namespace osu.Game.Beatmaps.Drawable
|
||||
Spacing = new Vector2(0, 5),
|
||||
Direction = FlowDirection.VerticalOnly,
|
||||
Alpha = 0,
|
||||
Children = this.beatmapSet.Beatmaps.Select(b =>
|
||||
new BeatmapPanel(this.beatmapSet, b)
|
||||
{
|
||||
GainedSelection = panelGainedSelection,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
}
|
||||
)
|
||||
Children = BeatmapPanels
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,16 +17,15 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
get
|
||||
{
|
||||
if (track == null)
|
||||
if (track != null) return track;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var trackData = Reader.ReadFile(Beatmap.Metadata.AudioFile);
|
||||
if (trackData != null)
|
||||
track = new AudioTrackBass(trackData);
|
||||
}
|
||||
catch { }
|
||||
var trackData = Reader.ReadFile(Beatmap.Metadata.AudioFile);
|
||||
if (trackData != null)
|
||||
track = new AudioTrackBass(trackData);
|
||||
}
|
||||
catch { }
|
||||
|
||||
return track;
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ namespace osu.Game.Database
|
||||
return Query<BeatmapSetInfo>().Where(s => s.BeatmapSetID == id).FirstOrDefault();
|
||||
}
|
||||
|
||||
public WorkingBeatmap GetBeatmapData(BeatmapInfo beatmapInfo)
|
||||
public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo)
|
||||
{
|
||||
var beatmapSet = Query<BeatmapSetInfo>().Where(s => s.BeatmapSetID == beatmapInfo.BeatmapSetID).FirstOrDefault();
|
||||
if (beatmapSet == null)
|
||||
@ -150,7 +150,7 @@ namespace osu.Game.Database
|
||||
|
||||
public Beatmap GetBeatmap(BeatmapInfo beatmapInfo)
|
||||
{
|
||||
using (WorkingBeatmap data = GetBeatmapData(beatmapInfo))
|
||||
using (WorkingBeatmap data = GetWorkingBeatmap(beatmapInfo))
|
||||
return data.Beatmap;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ using SQLiteNetExtensions.Attributes;
|
||||
|
||||
namespace osu.Game.Database
|
||||
{
|
||||
public class BeatmapInfo
|
||||
public class BeatmapInfo : IEquatable<BeatmapInfo>
|
||||
{
|
||||
[PrimaryKey]
|
||||
public int BeatmapID { get; set; }
|
||||
@ -64,5 +64,10 @@ namespace osu.Game.Database
|
||||
|
||||
// Metadata
|
||||
public string Version { get; set; }
|
||||
|
||||
public bool Equals(BeatmapInfo other)
|
||||
{
|
||||
return BeatmapID == other?.BeatmapID;
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@ using osu.Framework.Graphics.Transformations;
|
||||
using osu.Game.GameModes.Backgrounds;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Beatmaps;
|
||||
|
||||
namespace osu.Game.GameModes.Menu
|
||||
{
|
||||
|
@ -3,17 +3,20 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.GameModes;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Background;
|
||||
using osu.Game.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.GameModes
|
||||
{
|
||||
public class OsuGameMode : GameMode
|
||||
public abstract class OsuGameMode : GameMode
|
||||
{
|
||||
internal BackgroundMode Background { get; private set; }
|
||||
|
||||
@ -23,6 +26,64 @@ namespace osu.Game.GameModes
|
||||
/// </summary>
|
||||
protected virtual BackgroundMode CreateBackground() => null;
|
||||
|
||||
private bool boundToBeatmap;
|
||||
private Bindable<WorkingBeatmap> beatmap;
|
||||
|
||||
public WorkingBeatmap Beatmap
|
||||
{
|
||||
get
|
||||
{
|
||||
bindBeatmap();
|
||||
return beatmap.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
bindBeatmap();
|
||||
beatmap.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void bindBeatmap()
|
||||
{
|
||||
if (beatmap == null)
|
||||
beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
if (!boundToBeatmap)
|
||||
{
|
||||
beatmap.ValueChanged += beatmap_ValueChanged;
|
||||
boundToBeatmap = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
if (boundToBeatmap)
|
||||
beatmap.ValueChanged -= beatmap_ValueChanged;
|
||||
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
|
||||
private void beatmap_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
OnBeatmapChanged(beatmap.Value);
|
||||
}
|
||||
|
||||
public override bool Push(GameMode mode)
|
||||
{
|
||||
OsuGameMode nextOsu = mode as OsuGameMode;
|
||||
if (nextOsu != null)
|
||||
{
|
||||
nextOsu.beatmap = beatmap;
|
||||
}
|
||||
|
||||
return base.Push(mode);
|
||||
}
|
||||
|
||||
protected virtual void OnBeatmapChanged(WorkingBeatmap beatmap)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnEntering(GameMode last)
|
||||
{
|
||||
OsuGameMode lastOsu = last as OsuGameMode;
|
||||
|
@ -16,8 +16,11 @@ using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Game.Beatmaps.Drawable;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Framework.GameModes;
|
||||
|
||||
namespace osu.Game.GameModes.Play
|
||||
{
|
||||
@ -26,10 +29,12 @@ namespace osu.Game.GameModes.Play
|
||||
private Bindable<PlayMode> playMode;
|
||||
private BeatmapDatabase database;
|
||||
private BeatmapGroup selectedBeatmapGroup;
|
||||
private BeatmapInfo selectedBeatmapInfo;
|
||||
// TODO: use currently selected track as bg
|
||||
protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4");
|
||||
private ScrollContainer scrollContainer;
|
||||
private FlowContainer setList;
|
||||
private FlowContainer beatmapSetFlow;
|
||||
private TrackManager trackManager;
|
||||
|
||||
/// <param name="database">Optionally provide a database to use instead of the OsuGame one.</param>
|
||||
public PlaySongSelect(BeatmapDatabase database = null)
|
||||
@ -73,7 +78,7 @@ namespace osu.Game.GameModes.Play
|
||||
Origin = Anchor.CentreRight,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
setList = new FlowContainer
|
||||
beatmapSetFlow = new FlowContainer
|
||||
{
|
||||
Padding = new MarginPadding { Left = 25, Top = 25, Bottom = 25 + bottomToolHeight },
|
||||
RelativeSizeAxes = Axes.X,
|
||||
@ -123,7 +128,7 @@ namespace osu.Game.GameModes.Play
|
||||
if (osuGame != null)
|
||||
{
|
||||
playMode = osuGame.PlayMode;
|
||||
playMode.ValueChanged += PlayMode_ValueChanged;
|
||||
playMode.ValueChanged += playMode_ValueChanged;
|
||||
// Temporary:
|
||||
scrollContainer.Padding = new MarginPadding { Top = osuGame.Toolbar.Height };
|
||||
}
|
||||
@ -133,22 +138,68 @@ namespace osu.Game.GameModes.Play
|
||||
|
||||
database.BeatmapSetAdded += s => Schedule(() => addBeatmapSet(s));
|
||||
|
||||
trackManager = game.Audio.Track;
|
||||
|
||||
Task.Factory.StartNew(addBeatmapSets);
|
||||
}
|
||||
|
||||
protected override void OnEntering(GameMode last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
ensurePlayingSelected();
|
||||
}
|
||||
|
||||
protected override void OnResuming(GameMode last)
|
||||
{
|
||||
ensurePlayingSelected();
|
||||
|
||||
base.OnResuming(last);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
if (playMode != null)
|
||||
playMode.ValueChanged -= PlayMode_ValueChanged;
|
||||
playMode.ValueChanged -= playMode_ValueChanged;
|
||||
}
|
||||
|
||||
private void PlayMode_ValueChanged(object sender, EventArgs e)
|
||||
private void playMode_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void selectBeatmap(BeatmapGroup group, BeatmapInfo beatmap)
|
||||
protected override void OnBeatmapChanged(WorkingBeatmap beatmap)
|
||||
{
|
||||
base.OnBeatmapChanged(beatmap);
|
||||
selectBeatmap(beatmap.Beatmap.BeatmapInfo);
|
||||
}
|
||||
|
||||
private void selectBeatmap(BeatmapInfo beatmap)
|
||||
{
|
||||
if (beatmap.Equals(selectedBeatmapInfo))
|
||||
return;
|
||||
|
||||
beatmapSetFlow.Children.Cast<BeatmapGroup>().First(b =>
|
||||
{
|
||||
var panel = b.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(beatmap));
|
||||
panel?.TriggerClick();
|
||||
return panel != null;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// selection has been changed as the result of interaction with the carousel.
|
||||
/// </summary>
|
||||
private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap)
|
||||
{
|
||||
selectedBeatmapInfo = beatmap;
|
||||
|
||||
if (!beatmap.Equals(Beatmap?.Beatmap?.BeatmapInfo))
|
||||
{
|
||||
Beatmap = database.GetWorkingBeatmap(beatmap);
|
||||
}
|
||||
|
||||
ensurePlayingSelected();
|
||||
|
||||
if (selectedBeatmapGroup == group)
|
||||
return;
|
||||
|
||||
@ -158,6 +209,17 @@ namespace osu.Game.GameModes.Play
|
||||
selectedBeatmapGroup = group;
|
||||
}
|
||||
|
||||
private void ensurePlayingSelected()
|
||||
{
|
||||
var track = Beatmap?.Track;
|
||||
|
||||
if (track != null)
|
||||
{
|
||||
trackManager.SetExclusive(track);
|
||||
track.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void addBeatmapSet(BeatmapSetInfo beatmapSet)
|
||||
{
|
||||
beatmapSet = database.GetWithChildren<BeatmapSetInfo>(beatmapSet.BeatmapSetID);
|
||||
@ -165,9 +227,9 @@ namespace osu.Game.GameModes.Play
|
||||
beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList();
|
||||
Schedule(() =>
|
||||
{
|
||||
var group = new BeatmapGroup(beatmapSet) { SelectionChanged = selectBeatmap };
|
||||
setList.Add(group);
|
||||
if (setList.Children.Count() == 1)
|
||||
var group = new BeatmapGroup(beatmapSet) { SelectionChanged = selectionChanged };
|
||||
beatmapSetFlow.Add(group);
|
||||
if (beatmapSetFlow.Children.Count() == 1)
|
||||
group.State = BeatmapGroupState.Expanded;
|
||||
});
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ namespace osu.Game.GameModes.Play
|
||||
protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4");
|
||||
|
||||
public BeatmapInfo BeatmapInfo;
|
||||
public WorkingBeatmap Beatmap;
|
||||
|
||||
public PlayMode PreferredPlayMode;
|
||||
|
||||
@ -31,16 +30,13 @@ namespace osu.Game.GameModes.Play
|
||||
private InterpolatingFramedClock playerClock;
|
||||
private IAdjustableClock sourceClock;
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
Beatmap?.Dispose();
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
|
||||
protected override bool OnExiting(GameMode next)
|
||||
{
|
||||
//eagerly dispose as the finalizer runs too late right now.
|
||||
Beatmap?.Dispose();
|
||||
if (next == null)
|
||||
{
|
||||
//eagerly dispose as the finalizer runs too late right now.
|
||||
Beatmap?.Dispose();
|
||||
}
|
||||
|
||||
return base.OnExiting(next);
|
||||
}
|
||||
@ -52,7 +48,7 @@ namespace osu.Game.GameModes.Play
|
||||
try
|
||||
{
|
||||
if (Beatmap == null)
|
||||
Beatmap = ((OsuGame)game).Beatmaps.GetBeatmapData(BeatmapInfo);
|
||||
Beatmap = ((OsuGame)game).Beatmaps.GetWorkingBeatmap(BeatmapInfo);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -69,27 +65,28 @@ namespace osu.Game.GameModes.Play
|
||||
sourceClock = track;
|
||||
}
|
||||
|
||||
sourceClock = (IAdjustableClock)Beatmap.Track ?? new StopwatchClock();
|
||||
sourceClock = (IAdjustableClock)track ?? new StopwatchClock();
|
||||
playerClock = new InterpolatingFramedClock(sourceClock);
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
sourceClock.Reset();
|
||||
sourceClock.Start();
|
||||
});
|
||||
|
||||
HitRenderer hitRenderer;
|
||||
ScoreOverlay scoreOverlay;
|
||||
|
||||
if (Beatmap.Beatmap.BeatmapInfo?.Mode > PlayMode.Osu)
|
||||
var beatmap = Beatmap.Beatmap;
|
||||
|
||||
if (beatmap.BeatmapInfo?.Mode > PlayMode.Osu)
|
||||
{
|
||||
//we only support osu! mode for now because the hitobject parsing is crappy and needs a refactor.
|
||||
Exit();
|
||||
return;
|
||||
}
|
||||
|
||||
PlayMode usablePlayMode = Beatmap.Beatmap.BeatmapInfo?.Mode > PlayMode.Osu ? Beatmap.Beatmap.BeatmapInfo.Mode : PreferredPlayMode;
|
||||
|
||||
|
||||
PlayMode usablePlayMode = beatmap.BeatmapInfo?.Mode > PlayMode.Osu ? beatmap.BeatmapInfo.Mode : PreferredPlayMode;
|
||||
|
||||
switch (usablePlayMode)
|
||||
{
|
||||
@ -98,7 +95,7 @@ namespace osu.Game.GameModes.Play
|
||||
|
||||
hitRenderer = new OsuHitRenderer
|
||||
{
|
||||
Objects = Beatmap.Beatmap.HitObjects,
|
||||
Objects = beatmap.HitObjects,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
};
|
||||
@ -108,7 +105,7 @@ namespace osu.Game.GameModes.Play
|
||||
|
||||
hitRenderer = new TaikoHitRenderer
|
||||
{
|
||||
Objects = Beatmap.Beatmap.HitObjects,
|
||||
Objects = beatmap.HitObjects,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
};
|
||||
@ -118,7 +115,7 @@ namespace osu.Game.GameModes.Play
|
||||
|
||||
hitRenderer = new CatchHitRenderer
|
||||
{
|
||||
Objects = Beatmap.Beatmap.HitObjects,
|
||||
Objects = beatmap.HitObjects,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
};
|
||||
@ -128,7 +125,7 @@ namespace osu.Game.GameModes.Play
|
||||
|
||||
hitRenderer = new ManiaHitRenderer
|
||||
{
|
||||
Objects = Beatmap.Beatmap.HitObjects,
|
||||
Objects = beatmap.HitObjects,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
};
|
||||
|
@ -70,7 +70,10 @@ namespace osu.Game
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ActivateRequested = delegate { volume.Show(); }
|
||||
},
|
||||
intro = new Intro(),
|
||||
intro = new Intro
|
||||
{
|
||||
Beatmap = Beatmap
|
||||
},
|
||||
Toolbar = new Toolbar
|
||||
{
|
||||
OnHome = delegate { MainMenu?.MakeCurrent(); },
|
||||
|
@ -1,10 +1,13 @@
|
||||
using osu.Framework;
|
||||
using System;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.GameModes;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.IO;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Database;
|
||||
@ -32,6 +35,8 @@ namespace osu.Game
|
||||
|
||||
public CursorContainer Cursor;
|
||||
|
||||
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
public OsuGameBase()
|
||||
{
|
||||
AddInternal(ratioContainer = new RatioAdjust());
|
||||
@ -41,6 +46,13 @@ namespace osu.Game
|
||||
Options = new Options(),
|
||||
Cursor = new OsuCursorContainer()
|
||||
};
|
||||
|
||||
Beatmap.ValueChanged += Beatmap_ValueChanged;
|
||||
}
|
||||
|
||||
private void Beatmap_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Load(BaseGame game)
|
||||
|
Loading…
Reference in New Issue
Block a user