public void Explode(DrawableHitObject fruit) { var originalX = fruit.X * Scale.X; if (ExplodingFruitTarget != null) { fruit.Anchor = Anchor.TopLeft; fruit.Position = caughtFruit.ToSpaceOfOtherDrawable(fruit.DrawPosition, ExplodingFruitTarget); if (!caughtFruit.Remove(fruit)) { // we may have already been removed by a previous operation (due to the weird OnLoadComplete scheduling). // this avoids a crash on potentially attempting to Add a fruit to ExplodingFruitTarget twice. return; } ExplodingFruitTarget.Add(fruit); } fruit.MoveToY(fruit.Y - 50, 250, Easing.OutSine).Then().MoveToY(fruit.Y + 50, 500, Easing.InSine); fruit.MoveToX(fruit.X + originalX * 6, 1000); fruit.FadeOut(750); fruit.Expire(); }
private void updateState(DrawableHitObject hitObject, ArmedState state) { if (state == ArmedState.Idle || hitAnimations.Value) { return; } if (hitObject is DrawableHitCircle circle) { circle.ApproachCircle .FadeOutFromOne(EDITOR_HIT_OBJECT_FADE_OUT_EXTENSION * 4) .Expire(); circle.ApproachCircle.ScaleTo(1.1f, 300, Easing.OutQuint); } if (hitObject is IHasMainCirclePiece mainPieceContainer) { // clear any explode animation logic. // this is scheduled after children to ensure that the clear happens after invocations of ApplyCustomUpdateState on the circle piece's nested skinnables. ScheduleAfterChildren(() => { if (hitObject.HitObject == null) { return; } mainPieceContainer.CirclePiece.ApplyTransformsAt(hitObject.StateUpdateTime, true); mainPieceContainer.CirclePiece.ClearTransformsAfter(hitObject.StateUpdateTime, true); }); } if (hitObject is DrawableSliderRepeat repeat) { repeat.Arrow.ApplyTransformsAt(hitObject.StateUpdateTime, true); repeat.Arrow.ClearTransformsAfter(hitObject.StateUpdateTime, true); } // adjust the visuals of top-level object types to make them stay on screen for longer than usual. switch (hitObject) { case DrawableSlider _: case DrawableHitCircle _: // Get the existing fade out transform var existing = hitObject.Transforms.LastOrDefault(t => t.TargetMember == nameof(Alpha)); if (existing == null) { return; } hitObject.RemoveTransform(existing); using (hitObject.BeginAbsoluteSequence(hitObject.HitStateUpdateTime)) hitObject.FadeOut(EDITOR_HIT_OBJECT_FADE_OUT_EXTENSION).Expire(); break; } }
protected override void ApplyHiddenState(DrawableHitObject o, ArmedState state) { const float hiddenTime = 2000f; var ho = o.HitObject; double start = ho.StartTime - hiddenTime; using (o.BeginAbsoluteSequence(start, true)) o.FadeOut(hiddenTime); }
private void updateState(DrawableHitObject hitObject, ArmedState state) { if (state == ArmedState.Idle || hitAnimations.Value) { return; } if (hitObject is DrawableHitCircle circle) { circle.ApproachCircle .FadeOutFromOne(editor_hit_object_fade_out_extension * 4) .Expire(); circle.ApproachCircle.ScaleTo(1.1f, 300, Easing.OutQuint); } if (hitObject is IHasMainCirclePiece mainPieceContainer) { // clear any explode animation logic. mainPieceContainer.CirclePiece.ApplyTransformsAt(hitObject.HitStateUpdateTime, true); mainPieceContainer.CirclePiece.ClearTransformsAfter(hitObject.HitStateUpdateTime, true); } if (hitObject is DrawableSliderRepeat repeat) { repeat.Arrow.ApplyTransformsAt(hitObject.HitStateUpdateTime, true); repeat.Arrow.ClearTransformsAfter(hitObject.HitStateUpdateTime, true); } // adjust the visuals of top-level object types to make them stay on screen for longer than usual. switch (hitObject) { case DrawableSlider _: case DrawableHitCircle _: // Get the existing fade out transform var existing = hitObject.Transforms.LastOrDefault(t => t.TargetMember == nameof(Alpha)); if (existing == null) { return; } hitObject.RemoveTransform(existing); using (hitObject.BeginAbsoluteSequence(hitObject.HitStateUpdateTime)) hitObject.FadeOut(editor_hit_object_fade_out_extension).Expire(); break; } }
private void updateState(DrawableHitObject hitObject, ArmedState state) { if (state == ArmedState.Idle || hitAnimations.Value) { return; } // adjust the visuals of certain object types to make them stay on screen for longer than usual. switch (hitObject) { default: // there are quite a few drawable hit types we don't want to extend (spinners, ticks etc.) return; case DrawableSlider _: // no specifics to sliders but let them fade slower below. break; case DrawableHitCircle circle: // also handles slider heads circle.ApproachCircle .FadeOutFromOne(editor_hit_object_fade_out_extension * 4) .Expire(); circle.ApproachCircle.ScaleTo(1.1f, 300, Easing.OutQuint); var circlePieceDrawable = circle.CirclePiece.Drawable; // clear any explode animation logic. circlePieceDrawable.ApplyTransformsAt(circle.HitStateUpdateTime, true); circlePieceDrawable.ClearTransformsAfter(circle.HitStateUpdateTime, true); break; } // Get the existing fade out transform var existing = hitObject.Transforms.LastOrDefault(t => t.TargetMember == nameof(Alpha)); if (existing == null) { return; } hitObject.RemoveTransform(existing); using (hitObject.BeginAbsoluteSequence(hitObject.HitStateUpdateTime)) hitObject.FadeOut(editor_hit_object_fade_out_extension).Expire(); }
private void updateState(DrawableHitObject hitObject, ArmedState state) { switch (state) { case ArmedState.Miss: // Get the existing fade out transform var existing = hitObject.Transforms.LastOrDefault(t => t.TargetMember == nameof(Alpha)); if (existing == null) { return; } using (hitObject.BeginAbsoluteSequence(existing.StartTime)) hitObject.FadeOut(editor_hit_object_fade_out_extension).Expire(); break; } }
private void updateState(DrawableHitObject hitObject, ArmedState state) { if (state == ArmedState.Idle) { return; } // adjust the visuals of certain object types to make them stay on screen for longer than usual. switch (hitObject) { default: // there are quite a few drawable hit types we don't want to extent (spinners, ticks etc.) return; case DrawableSlider _: // no specifics to sliders but let them fade slower below. break; case DrawableHitCircle circle: // also handles slider heads circle.ApproachCircle .FadeOutFromOne(editor_hit_object_fade_out_extension) .Expire(); break; } // Get the existing fade out transform var existing = hitObject.Transforms.LastOrDefault(t => t.TargetMember == nameof(Alpha)); if (existing == null) { return; } hitObject.RemoveTransform(existing); using (hitObject.BeginAbsoluteSequence(existing.StartTime)) hitObject.FadeOut(editor_hit_object_fade_out_extension).Expire(); }
public void Explode(DrawableHitObject fruit) { var originalX = fruit.X * Scale.X; if (ExplodingFruitTarget != null) { fruit.Anchor = Anchor.TopLeft; fruit.Position = caughtFruit.ToSpaceOfOtherDrawable(fruit.DrawPosition, ExplodingFruitTarget); caughtFruit.Remove(fruit); ExplodingFruitTarget.Add(fruit); } fruit.MoveToY(fruit.Y - 50, 250, Easing.OutSine) .Then() .MoveToY(fruit.Y + 50, 500, Easing.InSine); fruit.MoveToX(fruit.X + originalX * 6, 1000); fruit.FadeOut(750); fruit.Expire(); }
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) { switch (hitObject) { case DrawableDrumRollTick _: case DrawableHit _: double preempt = drawableRuleset.TimeRange.Value / drawableRuleset.ControlPointAt(hitObject.HitObject.StartTime).Multiplier; double start = hitObject.HitObject.StartTime - preempt * fade_out_start_time; double duration = preempt * fade_out_duration; using (hitObject.BeginAbsoluteSequence(start)) { hitObject.FadeOut(duration); // DrawableHitObject sets LifetimeEnd to LatestTransformEndTime if it isn't manually changed. // in order for the object to not be killed before its actual end time (as the latest transform ends earlier), set lifetime end explicitly. hitObject.LifetimeEnd = state == ArmedState.Idle || !hitObject.AllJudged ? hitObject.HitObject.GetEndTime() + hitObject.HitObject.HitWindows.WindowFor(HitResult.Miss) : hitObject.HitStateUpdateTime; } break; } }