Merge branch 'master' into beatmap-track-rework

This commit is contained in:
Dean Herbert
2020-08-16 22:35:32 +09:00
13 changed files with 93 additions and 59 deletions

View File

@ -9,7 +9,9 @@
[![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu) [![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu)
[![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy) [![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy)
Rhythm is just a *click* away. The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! Commonly known by the codename *osu!lazer*. Pew pew. A free-to-win rhythm game. Rhythm is just a *click* away!
The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! Commonly known by the codename *osu!lazer*. Pew pew.
## Status ## Status

View File

@ -52,6 +52,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.812.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2020.812.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.812.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2020.814.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -3,7 +3,7 @@
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Description>click the circles. to the beat.</Description> <Description>A free-to-win rhythm game. Rhythm is just a *click* away!</Description>
<AssemblyName>osu!</AssemblyName> <AssemblyName>osu!</AssemblyName>
<Title>osu!lazer</Title> <Title>osu!lazer</Title>
<Product>osu!lazer</Product> <Product>osu!lazer</Product>

View File

@ -9,8 +9,7 @@
<projectUrl>https://osu.ppy.sh/</projectUrl> <projectUrl>https://osu.ppy.sh/</projectUrl>
<iconUrl>https://puu.sh/tYyXZ/9a01a5d1b0.ico</iconUrl> <iconUrl>https://puu.sh/tYyXZ/9a01a5d1b0.ico</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>click the circles. to the beat.</description> <description>A free-to-win rhythm game. Rhythm is just a *click* away!</description>
<summary>click the circles.</summary>
<releaseNotes>testing</releaseNotes> <releaseNotes>testing</releaseNotes>
<copyright>Copyright (c) 2020 ppy Pty Ltd</copyright> <copyright>Copyright (c) 2020 ppy Pty Ltd</copyright>
<language>en-AU</language> <language>en-AU</language>

View File

@ -83,8 +83,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
private SkinnableSound spinningSample; private SkinnableSound spinningSample;
private const float minimum_volume = 0.0001f;
protected override void LoadSamples() protected override void LoadSamples()
{ {
base.LoadSamples(); base.LoadSamples();
@ -101,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
AddInternal(spinningSample = new SkinnableSound(clone) AddInternal(spinningSample = new SkinnableSound(clone)
{ {
Volume = { Value = minimum_volume }, Volume = { Value = 0 },
Looping = true, Looping = true,
}); });
} }
@ -119,7 +117,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
} }
else else
{ {
spinningSample?.VolumeTo(minimum_volume, 200).Finally(_ => spinningSample.Stop()); spinningSample?.VolumeTo(0, 200).Finally(_ => spinningSample.Stop());
} }
} }

View File

@ -272,7 +272,21 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("Overlay is closed", () => pauseOverlay.State.Value == Visibility.Hidden); AddAssert("Overlay is closed", () => pauseOverlay.State.Value == Visibility.Hidden);
} }
[Test]
public void TestSelectionResetOnVisibilityChange()
{
showOverlay();
AddStep("Select last button", () => InputManager.Key(Key.Up));
hideOverlay();
showOverlay();
AddAssert("No button selected",
() => pauseOverlay.Buttons.All(button => !button.Selected.Value));
}
private void showOverlay() => AddStep("Show overlay", () => pauseOverlay.Show()); private void showOverlay() => AddStep("Show overlay", () => pauseOverlay.Show());
private void hideOverlay() => AddStep("Hide overlay", () => pauseOverlay.Hide());
private DialogButton getButton(int index) => pauseOverlay.Buttons.Skip(index).First(); private DialogButton getButton(int index) => pauseOverlay.Buttons.Skip(index).First();

View File

@ -67,19 +67,18 @@ namespace osu.Game.Beatmaps.Drawables
if (beatmapSet != null) if (beatmapSet != null)
{ {
BeatmapSetCover cover; Add(displayedCover = new DelayedLoadUnloadWrapper(() =>
{
Add(displayedCover = new DelayedLoadWrapper( var cover = new BeatmapSetCover(beatmapSet, coverType)
cover = new BeatmapSetCover(beatmapSet, coverType)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fill, FillMode = FillMode.Fill,
}) };
);
cover.OnLoadComplete += d => d.FadeInFromZero(400, Easing.Out); cover.OnLoadComplete += d => d.FadeInFromZero(400, Easing.Out);
return cover;
}));
} }
} }
} }

View File

@ -20,7 +20,7 @@ namespace osu.Game.Graphics.Backgrounds
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(TextureStore textures) private void load(LargeTextureStore textures)
{ {
Sprite.Texture = Beatmap?.Background ?? textures.Get(fallbackTextureName); Sprite.Texture = Beatmap?.Background ?? textures.Get(fallbackTextureName);
} }

View File

@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play
public abstract string Description { get; } public abstract string Description { get; }
protected internal FillFlowContainer<DialogButton> InternalButtons; protected ButtonContainer InternalButtons;
public IReadOnlyList<DialogButton> Buttons => InternalButtons; public IReadOnlyList<DialogButton> Buttons => InternalButtons;
private FillFlowContainer retryCounterContainer; private FillFlowContainer retryCounterContainer;
@ -59,7 +59,7 @@ namespace osu.Game.Screens.Play
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
State.ValueChanged += s => selectionIndex = -1; State.ValueChanged += s => InternalButtons.Deselect();
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -114,7 +114,7 @@ namespace osu.Game.Screens.Play
} }
} }
}, },
InternalButtons = new FillFlowContainer<DialogButton> InternalButtons = new ButtonContainer
{ {
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
@ -186,40 +186,16 @@ namespace osu.Game.Screens.Play
InternalButtons.Add(button); InternalButtons.Add(button);
} }
private int selectionIndex = -1;
private void setSelected(int value)
{
if (selectionIndex == value)
return;
// Deselect the previously-selected button
if (selectionIndex != -1)
InternalButtons[selectionIndex].Selected.Value = false;
selectionIndex = value;
// Select the newly-selected button
if (selectionIndex != -1)
InternalButtons[selectionIndex].Selected.Value = true;
}
public bool OnPressed(GlobalAction action) public bool OnPressed(GlobalAction action)
{ {
switch (action) switch (action)
{ {
case GlobalAction.SelectPrevious: case GlobalAction.SelectPrevious:
if (selectionIndex == -1 || selectionIndex == 0) InternalButtons.SelectPrevious();
setSelected(InternalButtons.Count - 1);
else
setSelected(selectionIndex - 1);
return true; return true;
case GlobalAction.SelectNext: case GlobalAction.SelectNext:
if (selectionIndex == -1 || selectionIndex == InternalButtons.Count - 1) InternalButtons.SelectNext();
setSelected(0);
else
setSelected(selectionIndex + 1);
return true; return true;
case GlobalAction.Back: case GlobalAction.Back:
@ -241,9 +217,9 @@ namespace osu.Game.Screens.Play
private void buttonSelectionChanged(DialogButton button, bool isSelected) private void buttonSelectionChanged(DialogButton button, bool isSelected)
{ {
if (!isSelected) if (!isSelected)
setSelected(-1); InternalButtons.Deselect();
else else
setSelected(InternalButtons.IndexOf(button)); InternalButtons.Select(button);
} }
private void updateRetryCount() private void updateRetryCount()
@ -277,6 +253,46 @@ namespace osu.Game.Screens.Play
}; };
} }
protected class ButtonContainer : FillFlowContainer<DialogButton>
{
private int selectedIndex = -1;
private void setSelected(int value)
{
if (selectedIndex == value)
return;
// Deselect the previously-selected button
if (selectedIndex != -1)
this[selectedIndex].Selected.Value = false;
selectedIndex = value;
// Select the newly-selected button
if (selectedIndex != -1)
this[selectedIndex].Selected.Value = true;
}
public void SelectNext()
{
if (selectedIndex == -1 || selectedIndex == Count - 1)
setSelected(0);
else
setSelected(selectedIndex + 1);
}
public void SelectPrevious()
{
if (selectedIndex == -1 || selectedIndex == 0)
setSelected(Count - 1);
else
setSelected(selectedIndex - 1);
}
public void Deselect() => setSelected(-1);
public void Select(DialogButton button) => setSelected(IndexOf(button));
}
private class Button : DialogButton private class Button : DialogButton
{ {
// required to ensure keyboard navigation always starts from an extremity (unless the cursor is moved) // required to ensure keyboard navigation always starts from an extremity (unless the cursor is moved)

View File

@ -26,8 +26,6 @@ namespace osu.Game.Screens.Play
protected override Action BackAction => () => InternalButtons.Children.First().Click(); protected override Action BackAction => () => InternalButtons.Children.First().Click();
private const float minimum_volume = 0.0001f;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
@ -38,10 +36,8 @@ namespace osu.Game.Screens.Play
AddInternal(pauseLoop = new SkinnableSound(new SampleInfo("pause-loop")) AddInternal(pauseLoop = new SkinnableSound(new SampleInfo("pause-loop"))
{ {
Looping = true, Looping = true,
Volume = { Value = 0 }
}); });
// SkinnableSound only plays a sound if its aggregate volume is > 0, so the volume must be turned up before playing it
pauseLoop.VolumeTo(minimum_volume);
} }
protected override void PopIn() protected override void PopIn()
@ -56,7 +52,7 @@ namespace osu.Game.Screens.Play
{ {
base.PopOut(); base.PopOut();
pauseLoop.VolumeTo(minimum_volume, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop()); pauseLoop.VolumeTo(0, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop());
} }
} }
} }

View File

@ -27,6 +27,16 @@ namespace osu.Game.Skinning
public override bool RemoveWhenNotAlive => false; public override bool RemoveWhenNotAlive => false;
public override bool RemoveCompletedTransforms => false; public override bool RemoveCompletedTransforms => false;
/// <summary>
/// Whether to play the underlying sample when aggregate volume is zero.
/// Note that this is checked at the point of calling <see cref="Play"/>; changing the volume post-play will not begin playback.
/// Defaults to false unless <see cref="Looping"/>.
/// </summary>
/// <remarks>
/// Can serve as an optimisation if it is known ahead-of-time that this behaviour is allowed in a given use case.
/// </remarks>
protected bool PlayWhenZeroVolume => Looping;
private readonly AudioContainer<DrawableSample> samplesContainer; private readonly AudioContainer<DrawableSample> samplesContainer;
public SkinnableSound(ISampleInfo hitSamples) public SkinnableSound(ISampleInfo hitSamples)
@ -86,7 +96,7 @@ namespace osu.Game.Skinning
{ {
samplesContainer.ForEach(c => samplesContainer.ForEach(c =>
{ {
if (c.AggregateVolume.Value > 0) if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0)
c.Play(); c.Play();
}); });
} }

View File

@ -24,7 +24,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Framework" Version="2020.812.0" /> <PackageReference Include="ppy.osu.Framework" Version="2020.814.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.812.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2020.812.0" />
<PackageReference Include="Sentry" Version="2.1.5" /> <PackageReference Include="Sentry" Version="2.1.5" />
<PackageReference Include="SharpCompress" Version="0.26.0" /> <PackageReference Include="SharpCompress" Version="0.26.0" />

View File

@ -70,7 +70,7 @@
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.812.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2020.814.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.812.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2020.812.0" />
</ItemGroup> </ItemGroup>
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. --> <!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
@ -80,7 +80,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="ppy.osu.Framework" Version="2020.812.0" /> <PackageReference Include="ppy.osu.Framework" Version="2020.814.0" />
<PackageReference Include="SharpCompress" Version="0.26.0" /> <PackageReference Include="SharpCompress" Version="0.26.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />