1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 08:52:55 +08:00

Make fruit catcher enter and leave what's behind the blinds

This commit is contained in:
WebFreak001 2018-09-16 12:48:36 +02:00
parent 5f3c0549c9
commit 91b25870ef
2 changed files with 164 additions and 17 deletions

View File

@ -6,7 +6,6 @@ using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using System.Linq;
namespace osu.Game.Rulesets.Osu.Mods
{
@ -17,8 +16,16 @@ namespace osu.Game.Rulesets.Osu.Mods
public override void ApplyToRulesetContainer(RulesetContainer<OsuHitObject> rulesetContainer)
{
bool hasEasy = rulesetContainer.ActiveMods.Count(mod => mod is ModEasy) > 0;
rulesetContainer.Overlays.Add(flashlight = new DrawableOsuBlinds(restrictTo: rulesetContainer.Playfield, hasEasy: hasEasy));
bool hasEasy = false;
bool hasHardrock = false;
foreach (var mod in rulesetContainer.ActiveMods)
{
if (mod is ModEasy)
hasEasy = true;
if (mod is ModHardRock)
hasHardrock = true;
}
rulesetContainer.Overlays.Add(flashlight = new DrawableOsuBlinds(restrictTo: rulesetContainer.Playfield, hasEasy: hasEasy, hasHardrock: hasHardrock));
}
public override void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
@ -26,6 +33,10 @@ namespace osu.Game.Rulesets.Osu.Mods
scoreProcessor.Health.ValueChanged += val => {
flashlight.Value = (float)val;
};
scoreProcessor.Combo.ValueChanged += val => {
if (val > 0 && val % 30 == 0)
flashlight.TriggerNPC();
};
}
}
}

View File

@ -10,6 +10,7 @@ using osu.Game.Skinning;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
using System;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
@ -24,13 +25,27 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
private Box box1, box2;
private Sprite panelLeft, panelRight;
private Sprite bgPanelLeft, bgPanelRight;
private Drawable bgRandomNpc;
private Drawable randomNpc;
private const float npc_movement_start = 1.5f;
private float npcPosition = npc_movement_start;
private bool animatingNPC;
private Random random;
private ISkinSource skin;
private float targetClamp = 1;
private float target = 1;
private readonly float easing = 1;
private const float black_depth = 10;
private const float bg_panel_depth = 8;
private const float fg_panel_depth = 4;
private const float npc_depth = 6;
private readonly Container restrictTo;
private readonly bool hasEasy;
private readonly bool modEasy, modHardrock;
/// <summary>
/// <para>
@ -50,10 +65,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
/// </summary>
private const float easy_position_multiplier = 0.95f;
public DrawableOsuBlinds(Container restrictTo, bool hasEasy)
public DrawableOsuBlinds(Container restrictTo, bool hasEasy, bool hasHardrock)
{
this.restrictTo = restrictTo;
this.hasEasy = hasEasy;
modEasy = hasEasy;
modHardrock = hasHardrock;
}
[BackgroundDependencyLoader]
@ -70,7 +87,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Colour = Color4.Black,
RelativeSizeAxes = Axes.Y,
Width = 0,
Height = 1
Height = 1,
Depth = black_depth
});
Add(box2 = new Box
{
@ -79,23 +97,56 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Colour = Color4.Black,
RelativeSizeAxes = Axes.Y,
Width = 0,
Height = 1
Height = 1,
Depth = black_depth
});
Add(bgPanelLeft = new ModBlindsPanelSprite {
Origin = Anchor.TopRight,
Colour = Color4.Gray
Colour = Color4.Gray,
Depth = bg_panel_depth + 1
});
Add(bgPanelRight = new ModBlindsPanelSprite {
Origin = Anchor.TopLeft,
Colour = Color4.Gray
Add(panelLeft = new ModBlindsPanelSprite {
Origin = Anchor.TopRight,
Depth = bg_panel_depth
});
Add(panelLeft = new ModBlindsPanelSprite {
Origin = Anchor.TopRight
Add(bgPanelRight = new ModBlindsPanelSprite {
Origin = Anchor.TopLeft,
Colour = Color4.Gray,
Depth = fg_panel_depth + 1
});
Add(panelRight = new ModBlindsPanelSprite {
Origin = Anchor.TopLeft
Origin = Anchor.TopLeft,
Depth = fg_panel_depth
});
random = new Random();
Add(bgRandomNpc = new Box
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = Color4.Black,
Width = 512 * 0.4f,
Height = 512 * 0.95f,
RelativePositionAxes = Axes.Y,
X = -512,
Y = 0,
Depth = black_depth
});
Add(new SkinnableDrawable("Play/Catch/fruit-catcher-idle", name => randomNpc = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Texture = textures.Get(name),
Width = 512,
Height = 512,
RelativePositionAxes = Axes.Y,
X = -512,
Y = 0
}) {
Depth = npc_depth
});
this.skin = skin;
@ -108,9 +159,36 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
PanelTexture = skin.GetTexture("Play/osu/blinds-panel");
}
private float applyGap(float value)
{
float ret;
if (modEasy)
{
float multiplier = 0.95f;
ret = value * multiplier;
}
else if (modHardrock)
{
float multiplier = 1.1f;
ret = value * multiplier;
}
else
{
ret = value;
}
if (ret > targetClamp)
return targetClamp;
else if (ret < 0)
return 0;
else
return ret;
}
private static float applyAdjustmentCurve(float value)
{
return value * value;
// lagrange polinominal for (0,0) (0.5,0.35) (1,1) should make a good curve
return 0.6f * value * value + 0.4f * value;
}
protected override void Update()
@ -121,7 +199,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
start -= rawWidth * leniency * 0.5f;
end += rawWidth * leniency * 0.5f;
float width = (end - start) * 0.5f * applyAdjustmentCurve((hasEasy ? easy_position_multiplier : 1) * easing);
float width = (end - start) * 0.5f * applyAdjustmentCurve(applyGap(easing));
// different values in case the playfield ever moves from center to somewhere else.
box1.Width = start + width;
box2.Width = DrawWidth - end + width;
@ -130,6 +208,64 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
panelRight.X = end - width;
bgPanelLeft.X = start;
bgPanelRight.X = end;
float adjustedNpcPosition = npcPosition * rawWidth;
if (randomNpc != null)
randomNpc.X = adjustedNpcPosition;
bgRandomNpc.X = adjustedNpcPosition;
}
public void TriggerNPC()
{
if (animatingNPC)
return;
bool left = (random.Next() & 1) != 0;
bool exit = (random.Next() & 1) != 0;
float start, end;
if (left)
{
start = -npc_movement_start;
end = npc_movement_start;
randomNpc.Scale = new OpenTK.Vector2(1, 1);
}
else
{
start = npc_movement_start;
end = -npc_movement_start;
randomNpc.Scale = new OpenTK.Vector2(-1, 1);
}
// depths for exit from the left and entry from the right
if (left == exit)
{
ChangeChildDepth(bgPanelLeft, fg_panel_depth + 1);
ChangeChildDepth(panelLeft, fg_panel_depth);
ChangeChildDepth(bgPanelRight, bg_panel_depth + 1);
ChangeChildDepth(panelRight, bg_panel_depth);
}
else // depths for entry from the left or exit from the right
{
ChangeChildDepth(bgPanelLeft, bg_panel_depth + 1);
ChangeChildDepth(panelLeft, bg_panel_depth);
ChangeChildDepth(bgPanelRight, fg_panel_depth + 1);
ChangeChildDepth(panelRight, fg_panel_depth);
}
animatingNPC = true;
npcPosition = start;
this.TransformTo(nameof(npcPosition), end, 3000, Easing.OutSine).Finally(_ => animatingNPC = false);
targetClamp = 1;
this.Delay(600).TransformTo(nameof(targetClamp), 0.6f, 300).Delay(500).TransformTo(nameof(targetClamp), 1f, 300);
randomNpc?.FadeIn(250).Delay(2000).FadeOut(500);
bgRandomNpc.FadeIn(250).Delay(2000).FadeOut(500);
}
/// <summary>