private void explode(int beat, float strength = 1) { pDrawable explosion = explosions[beat]; if (explosion.Alpha == 0 && !menuBackgroundNew.IsAwesome && osuLogo.ScaleScalar >= 0.6f) { explosion.ScaleScalar *= 1.3f; explosion.FadeIn(100); } if (!menuBackgroundNew.IsAwesome) { float adjust = beat == 0 ? (1 - 0.1f * strength) : (beat == 1 ? (1 + 0.05f * strength) : 1); if (osuLogo.Transformations.Count != 0 && osuLogo.Transformations[0] is TransformationBounce) { ((TransformationBounce)osuLogo.Transformations[0]).EndFloat *= adjust; } else { osuLogo.ScaleScalar *= adjust; osuLogo.ScaleTo(0.625f, 500, EasingTypes.In); } } explosion.FlashColour(ColourHelper.Lighten2(explosion.Colour, 0.4f * strength), 350); explosion.ScaleScalar *= 1 + (0.2f * strength); explosion.ScaleTo(sizeForExplosion(beat), 400, EasingTypes.In); }
internal void UpdateStarDifficultyDisplay(bool instant) { if (!IsLoaded || Beatmap == null || state < TreeItemState.ExtrasVisible) { return; } double stars = Math.Min(Beatmap.StarDisplay, 10.0); // We don't want to deal with more than 10 stars in this display if (currentlyVisibleStars == stars) { return; } double previouslyVisibleStars = currentlyVisibleStars; currentlyVisibleStars = stars; UpdateDifficultyText(); // We want the -1 placeholder for "inexistant difficulty" to be treated like 0 stars here if (stars < 0) { stars = 0; int BackgroundStarSpritesEndIndex = starSpritesBeginIndex + AMOUNT_STARS; for (int i = starSpritesBeginIndex; i < BackgroundStarSpritesEndIndex; ++i) { pDrawable starSprite = SpriteCollection[i]; starSprite.FadeOut(instant ? 0 : (OldLayout ? 1000 : 600)); } } // ... with the exception of the background stars appearing. We want these to only appear once difficulty has been computed. (for looking good!) else { int BackgroundStarSpritesEndIndex = starSpritesBeginIndex + AMOUNT_STARS; for (int i = starSpritesBeginIndex; i < BackgroundStarSpritesEndIndex; ++i) { pDrawable starSprite = SpriteCollection[i]; starSprite.FadeIn(instant ? 0 : (OldLayout ? 1000 : 600)); } } int StarSpritesEndIndex = starSpritesBeginIndex + AMOUNT_STARS * 2; for (int i = starSpritesBeginIndex + AMOUNT_STARS; i < StarSpritesEndIndex; ++i) { int starIndex = i - (starSpritesBeginIndex + AMOUNT_STARS); double starsLeft = stars - starIndex; pSprite starSprite = SpriteCollection[i] as pSprite; starSprite.Transformations.Clear(); if (OldLayout) { int targetWidth = (int)(starSprite.Width * starsLeft); // It is important to also clip the width to negative values so the animation is delayed when the stars potentially appear again after the difficulty has been computed. // Don't optimize this and set to 0! starSprite.ClipWidthTo(targetWidth, instant ? 0 : 500, EasingTypes.OutCubic); } else { float newScale = starsLeft <= 0 ? 0 : star_scale * (float)Math.Max(0.5f, Math.Min(1, starsLeft) + starIndex * 0.04f); int amountStarsScaled = (int)Math.Floor(starIndex - Math.Min(stars, previouslyVisibleStars)); if (instant) { starSprite.ScaleTo(newScale, 0); } else { int timeAddition = previouslyVisibleStars <= stars ? amountStarsScaled : (int)Math.Floor(previouslyVisibleStars - stars) - amountStarsScaled - 1; int startTime = GameBase.Time + timeAddition * 80 + 50; starSprite.Transformations.Add(new Transformation(TransformationType.Scale, starSprite.Scale, newScale, startTime, startTime + 500, EasingTypes.OutBack)); } } } }
private void checkObject(HitObject nextObject) { pDrawable preferred = null; float leftPart = GameBase.GamefieldBaseSize.X / 11f * 4; float rightPart = GameBase.GamefieldBaseSize.X / 11f * 7; float distFromLeft = pMathHelper.Distance(nextObject.Position, ((HitObject)leftFinger.Tag)?.EndPosition ?? leftFinger.Position); float distFromRight = pMathHelper.Distance(nextObject.Position, ((HitObject)rightFinger.Tag)?.EndPosition ?? rightFinger.Position); if (nextObject.connectedObject != null) { //if there is a connected object, always use the correct L-R arrangement. if (nextObject.Position.X == nextObject.connectedObject.Position.X) { // if same x we'll assign the closest finger to each note float connectedDistFromLeft = pMathHelper.Distance(nextObject.connectedObject.Position, ((HitObject)leftFinger.Tag)?.EndPosition ?? leftFinger.Position); float connectedDistFromRight = pMathHelper.Distance(nextObject.connectedObject.Position, ((HitObject)rightFinger.Tag)?.EndPosition ?? rightFinger.Position); float smallest = Math.Min(Math.Min(connectedDistFromLeft, connectedDistFromRight), Math.Min(distFromLeft, distFromLeft)); preferred = smallest == distFromLeft || smallest == connectedDistFromRight ? leftFinger : rightFinger; } else if (nextObject.Position.X < nextObject.connectedObject.Position.X) { preferred = leftFinger; } else { preferred = rightFinger; } } else { if (distFromLeft < 20) { //stacked objects (left finger) preferred = leftFinger; } else if (distFromRight < 20) { //stacked objects (right finger) preferred = rightFinger; } else if (lastObject != null && lastObject != nextObject && !(lastObject is Slider) && !(nextObject is Slider) && nextObject.StartTime - lastObject.EndTime < 150) { //fast hits; always alternate fingers preferred = lastFinger == leftFinger ? rightFinger : leftFinger; } /* * else if (nextObject.Position.X > nextObject.Position2.X && nextObject.Position.X < rightPart && Math.Abs(nextObject.Position.Y - nextObject.Position2.Y) < 20) * //sliders that start right and end left, centered towards the left * preferred = leftFinger; * else if (nextObject.Position.X < nextObject.Position2.X && nextObject.Position.X > leftPart && Math.Abs(nextObject.Position.Y - nextObject.Position2.Y) < 20) * //sliders that start left and end right, centered towards the right * preferred = rightFinger; */ else if (nextObject.Position.X < leftPart) { //starts in left 1/3 of screen. preferred = leftFinger; } else if (nextObject.Position.X > rightPart) { //starts in right 1/3 of screen. preferred = rightFinger; } else if (nextObject.Position2.X < leftPart) { //ends in left 1/3 of screen. preferred = leftFinger; } else if (nextObject.Position2.X > rightPart) { //ends in right 1/3 of screen. preferred = rightFinger; } else if (lastObject is HoldCircle) { //hold note; always alternate fingers preferred = lastFinger == leftFinger ? rightFinger : leftFinger; } else { //fall back to the closest finger. preferred = distFromLeft < distFromRight ? leftFinger : rightFinger; } if (preferred == leftFinger && nextObject.Position.X > rightFinger.Position.X && rightFinger.Tag == null) { //if we're about to use left finger but the object is wedged between the right finger and right side of screen, use right instead. preferred = rightFinger; } else if (preferred == rightFinger && nextObject.Position.X < leftFinger.Position.X && leftFinger.Tag == null) { //if we're about to use right finger but the object is wedged between the left finger and left side of screen, use left instead. preferred = leftFinger; } } pDrawable alternative = preferred == leftFinger ? rightFinger : leftFinger; if (preferred.Tag == null) { preferred.Tag = nextObject; preferred.Transformations.Clear(); preferred.FadeIn(300); } else { //finger is busy... HitObject busyObject = preferred.Tag as HitObject; if (busyObject.EndTime > nextObject.StartTime - 80) { alternative.Tag = nextObject; alternative.Transformations.Clear(); alternative.FadeIn(300); } } lastObject = nextObject; }