1
0
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:
Dean Herbert 2016-10-28 19:55:48 +09:00
parent 0f5614ffa2
commit 74f1a9622f
10 changed files with 197 additions and 51 deletions

View File

@ -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
}
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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
{

View File

@ -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;

View File

@ -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;
});
}

View File

@ -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
};

View File

@ -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(); },

View File

@ -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)