private static Rectangle GetSourceRect([NotNull] SpriteSheet1D spriteSheet, int index) { if (index < 0 || index >= spriteSheet.Count) { throw new ArgumentOutOfRangeException(nameof(index)); } float x, y, w, h; switch (spriteSheet.Orientation) { case SpriteSheetOrientation.Horizontal: w = spriteSheet.UnitWidth; h = spriteSheet.UnitHeight; x = index * w; y = 0; break; case SpriteSheetOrientation.Vertical: w = spriteSheet.UnitWidth; h = spriteSheet.UnitHeight; x = 0; y = index * h; break; default: throw new ArgumentOutOfRangeException(); } return(RectHelper.RoundToRectangle(x, y, w, h)); }
private static Rectangle GetSourceRect([NotNull] SpriteSheet2D spriteSheet, int index) { if (index < 0 || index >= spriteSheet.ArrayCount) { throw new ArgumentOutOfRangeException(nameof(index)); } int xIndex, yIndex; float w, h; switch (spriteSheet.Orientation) { case SpriteSheetOrientation.Horizontal: w = spriteSheet.UnitWidth; h = spriteSheet.UnitHeight; xIndex = index % spriteSheet.Stride; yIndex = index / spriteSheet.Stride; break; case SpriteSheetOrientation.Vertical: w = spriteSheet.UnitWidth; h = spriteSheet.UnitHeight; xIndex = index / spriteSheet.Stride; yIndex = index % spriteSheet.Stride; break; default: throw new ArgumentOutOfRangeException(); } var x = xIndex * w; var y = yIndex * h; return(RectHelper.RoundToRectangle(x, y, w, h)); }
protected override void OnDraw(GameTime gameTime) { base.OnDraw(gameTime); var config = ConfigurationStore.Get <ComboNumbersConfig>(); var game = Game.ToBaseGame(); var scalingResponder = game.FindSingleElement <MltdStageScalingResponder>(); if (scalingResponder == null) { throw new InvalidOperationException(); } var location = Location; var images = _numberImages; var sourceBlankEdge = config.Data.Images.UnitBlankEdge; var singleImageSize = scalingResponder.ScaleResults.ComboNumber; var scaleX = singleImageSize.X / images.UnitWidth; var scaleY = singleImageSize.Y / images.UnitHeight; var actualImageSize = new Vector2(singleImageSize.X - (sourceBlankEdge.Left + sourceBlankEdge.Right) * scaleX, singleImageSize.Y - (sourceBlankEdge.Top + sourceBlankEdge.Bottom) * scaleY); var spriteBatch = game.SpriteBatch; spriteBatch.BeginOnBufferedVisual(); var i = 1; var value = Value; do { var digit = (int)(value % 10); var x = location.X - i * actualImageSize.X; var y = location.Y - actualImageSize.Y; var destRect = RectHelper.RoundToRectangle(x, y, actualImageSize.X, actualImageSize.Y); spriteBatch.Draw(_numberImages, digit, destRect, sourceBlankEdge.ToRectangle()); value /= 10; ++i; } while (value > 0); spriteBatch.End(); }
protected override void OnDraw(GameTime gameTime) { base.OnDraw(gameTime); var theaterDays = Game.ToBaseGame(); var scalingResponder = theaterDays.FindSingleElement <MltdStageScalingResponder>(); if (scalingResponder == null) { throw new InvalidOperationException(); } var scaledSize = scalingResponder.ScaleResults.ComboText; var location = Location; var spriteBatch = theaterDays.SpriteBatch; var destRect = RectHelper.RoundToRectangle(location.X, location.Y, scaledSize.X, scaledSize.Y); spriteBatch.BeginOnBufferedVisual(); spriteBatch.Draw(_textImage, destRect, Color.White); spriteBatch.End(); }
protected override void OnDraw(GameTime gameTime) { base.OnDraw(gameTime); var config = ConfigurationStore.Get <SlideMotionConfig>(); var motionIcon = config.Data.Icon; if (motionIcon == SlideMotionConfig.SlideMotionIcon.None) { return; } var theaterDays = Game.ToBaseGame(); var score = theaterDays.FindSingleElement <ScoreLoader>()?.RuntimeScore; if (score == null) { return; } var notes = score.Notes; var syncTimer = theaterDays.FindSingleElement <SyncTimer>(); if (syncTimer == null) { return; } var tapPoints = theaterDays.FindSingleElement <TapPoints>(); if (tapPoints == null) { throw new InvalidOperationException(); } var notesLayer = theaterDays.FindSingleElement <NotesLayer>(); if (notesLayer == null) { throw new InvalidOperationException(); } var scalingResponder = theaterDays.FindSingleElement <MltdStageScalingResponder>(); if (scalingResponder == null) { throw new InvalidOperationException(); } var now = (float)syncTimer.CurrentTime.TotalSeconds; var tapPointsConfig = ConfigurationStore.Get <TapPointsConfig>(); var notesLayerConfig = ConfigurationStore.Get <NotesLayerConfig>(); var tapPointsLayout = tapPointsConfig.Data.Layout; var notesLayerLayout = notesLayerConfig.Data.Layout; var clientSize = theaterDays.GraphicsDevice.Viewport; var animationCalculator = notesLayer.AnimationCalculator; var commonNoteMetrics = new NoteMetrics { StartRadius = scalingResponder.ScaleResults.Note.Start, EndRadius = scalingResponder.ScaleResults.Note.End }; var animationMetrics = new NoteAnimationMetrics { GlobalSpeedScale = notesLayer.GlobalSpeedScale, Width = clientSize.Width, Height = clientSize.Height, Top = notesLayerLayout.Y.IsPercentage ? notesLayerLayout.Y.Value * clientSize.Height : notesLayerLayout.Y.Value, Bottom = tapPointsLayout.Y.IsPercentage ? tapPointsLayout.Y.Value * clientSize.Height : tapPointsLayout.Y.Value, NoteStartXRatios = tapPoints.StartXRatios, NoteEndXRatios = tapPoints.EndXRatios, TrackCount = tapPoints.EndXRatios.Length }; var spriteBatch = theaterDays.SpriteBatch; spriteBatch.Begin(); foreach (var note in notes) { if (!note.IsSlide() || !note.HasNextSlide()) { continue; } var thisStatus = NoteAnimationHelper.GetOnStageStatusOf(note, now, animationMetrics); if (thisStatus < OnStageStatus.Passed) { continue; } var nextStatus = NoteAnimationHelper.GetOnStageStatusOf(note.NextSlide, now, animationMetrics); if (nextStatus >= OnStageStatus.Passed) { continue; } var x = animationCalculator.GetNoteX(note, now, commonNoteMetrics, animationMetrics); var y = animationCalculator.GetNoteY(note, now, commonNoteMetrics, animationMetrics); Vector2 imageSize; switch (motionIcon) { case SlideMotionConfig.SlideMotionIcon.None: // Not possible. throw new InvalidOperationException(); case SlideMotionConfig.SlideMotionIcon.TapPoint: if (_tapPointImage != null) { imageSize = scalingResponder.ScaleResults.TapPoint.Start; spriteBatch.Draw(_tapPointImage, RectHelper.RoundToRectangle(x - imageSize.X / 2, y - imageSize.Y / 2, imageSize.X, imageSize.Y)); } break; case SlideMotionConfig.SlideMotionIcon.SlideStart: case SlideMotionConfig.SlideMotionIcon.SlideMiddle: case SlideMotionConfig.SlideMotionIcon.SlideEnd: var isStart = motionIcon == SlideMotionConfig.SlideMotionIcon.SlideStart; var isEnd = motionIcon == SlideMotionConfig.SlideMotionIcon.SlideEnd; if (_noteImages?[0] != null) { var(imageIndex, _) = NotesLayer.GetImageIndex(NoteType.Slide, NoteSize.Small, FlickDirection.None, false, false, isStart, isEnd); imageSize = scalingResponder.ScaleResults.Note.End; spriteBatch.Draw(_noteImages[0], imageIndex, RectHelper.RoundToRectangle(x - imageSize.X / 2, y - imageSize.Y / 2, imageSize.X, imageSize.Y)); } break; default: throw new ArgumentOutOfRangeException(); } } spriteBatch.End(); }
protected override void OnDraw(GameTime gameTime) { base.OnDraw(gameTime); if (!_isAnimationStarted) { return; } var theaterDays = Game.ToBaseGame(); var syncTimer = theaterDays.FindSingleElement <SyncTimer>(); if (syncTimer == null) { throw new InvalidOperationException(); } var scalingResponder = theaterDays.FindSingleElement <MltdStageScalingResponder>(); if (scalingResponder == null) { throw new InvalidOperationException(); } var tapPoints = theaterDays.FindSingleElement <TapPoints>(); if (tapPoints == null) { throw new InvalidOperationException(); } var currentTime = syncTimer.CurrentTime; if (currentTime < _animationStartedTime) { // Automatically cancels the animation if the user steps back in UI. _isAnimationStarted = false; return; } var animationTime = (currentTime - _animationStartedTime).TotalSeconds; if (animationTime > _phase1Duration + _phase2Duration) { _isAnimationStarted = false; return; } var clientSize = theaterDays.GraphicsDevice.Viewport; var scalingResults = scalingResponder.ScaleResults; var tapPointsConfig = ConfigurationStore.Get <TapPointsConfig>(); var tapPointsLayout = tapPointsConfig.Data.Layout; var spriteBatch = theaterDays.SpriteBatch; spriteBatch.Begin(); float perc; var y = tapPointsLayout.Y.IsPercentage ? tapPointsLayout.Y.Value * clientSize.Height : tapPointsLayout.Y.Value; if (animationTime <= _phase1Duration) { perc = (float)animationTime / (float)_phase1Duration; var tapPointSizes = scalingResults.TapPoint; var auraSizes = scalingResults.SpecialNoteAura; var tapPointWidth = MathHelper.Lerp(tapPointSizes.Start.X, tapPointSizes.End.X, perc); var tapPointHeight = MathHelper.Lerp(tapPointSizes.Start.Y, tapPointSizes.End.Y, perc); var auraWidth = MathHelper.Lerp(auraSizes.Start.X, auraSizes.End.X, perc); var auraHeight = MathHelper.Lerp(auraSizes.Start.Y, auraSizes.End.Y, perc); var xRatioArray = tapPoints.EndXRatios; for (var i = 0; i < xRatioArray.Length; ++i) { var x = MathHelper.Lerp(xRatioArray[i], 0.5f, perc) * clientSize.Width; spriteBatch.Draw(_tapPointImage, RectHelper.RoundToRectangle(x - tapPointWidth / 2, y - tapPointHeight / 2, tapPointWidth, tapPointHeight), 1 - perc); spriteBatch.Draw(_auraImage, RectHelper.RoundToRectangle(x - auraWidth / 2, y - auraHeight / 2, auraWidth, auraHeight), perc); } } else { perc = (float)(animationTime - _phase1Duration) / (float)_phase2Duration; var auraSize = scalingResults.SpecialNoteAura.End; var socketSize = scalingResults.SpecialNoteSocket; var x = clientSize.Width * 0.5f; spriteBatch.Draw(_socketImage, RectHelper.RoundToRectangle(x - socketSize.X / 2, y - socketSize.Y / 2, socketSize.X, socketSize.Y), perc); spriteBatch.Draw(_auraImage, RectHelper.RoundToRectangle(x - auraSize.X / 2, y - auraSize.Y / 2, auraSize.X, auraSize.Y)); } spriteBatch.End(); }
protected override void OnLoadContents() { base.OnLoadContents(); var theaterDays = Game.ToBaseGame(); var config = ConfigurationStore.Get <AvatarDisplayConfig>(); var avatarCount = config.Data.Images.Length; var avatarImages = new Texture2D[avatarCount]; for (var i = 0; i < avatarCount; ++i) { try { var image = ContentHelper.LoadTexture(theaterDays.GraphicsDevice, config.Data.Images[i].FileName); avatarImages[i] = image; } catch (Exception ex) { Debug.Print(ex.Message); } } var clientSize = theaterDays.GraphicsDevice.Viewport; var layout = config.Data.Layout; var x = layout.X.IsPercentage ? layout.X.Value * clientSize.Width : layout.X.Value; var y = layout.Y.IsPercentage ? layout.Y.Value * clientSize.Height : layout.Y.Value; var w = layout.Width.IsPercentage ? layout.Width.Value * clientSize.Width : layout.Width.Value; var h = layout.Height.IsPercentage ? layout.Height.Value * clientSize.Height : layout.Height.Value; var rects = new Rectangle[avatarCount]; float radius; if (w >= h) { radius = h / 2; for (var i = 0; i < avatarCount; ++i) { var cx = (w - radius * 2) / (avatarCount - 1) * i; var rect = RectHelper.RoundToRectangle(x + cx, y, radius * 2, radius * 2); rects[i] = rect; } } else { radius = w / 2; for (var i = 0; i < avatarCount; ++i) { var cy = (h - radius * 2) / (avatarCount - 1) * i; var rect = RectHelper.RoundToRectangle(x, y + cy, radius * 2, radius * 2); rects[i] = rect; } } _avatarImages = avatarImages; _avatarRectangles = rects; var avatarImagesData = new byte[avatarImages.Length][]; for (var i = 0; i < avatarImages.Length; ++i) { if (avatarImages[i] == null) { continue; } var data = new byte[avatarImages[i].Width * avatarImages[i].Height * sizeof(int)]; avatarImages[i].GetData(data); avatarImagesData[i] = data; } _avatarImagesData = avatarImagesData; var scalingResponder = theaterDays.FindSingleElement <MltdStageScalingResponder>(); if (scalingResponder == null) { throw new InvalidOperationException(); } var scalingResults = scalingResponder.ScaleResults; _borderColor = Color.White; _borderWidth = scalingResults.AvatarBorder.X; DrawContents(); }
protected override void OnDraw(GameTime gameTime) { base.OnDraw(gameTime); var texture = _texture; if (texture != null) { var game = Game.ToBaseGame(); var config = ConfigurationStore.Get <BackgroundImageConfig>(); var samplerState = config.Data.Fit == BackgroundImageFit.Tile ? SamplerState.LinearWrap : SamplerState.LinearClamp; var viewport = game.GraphicsDevice.Viewport; game.SpriteBatch.Begin(blendState: BlendState.AlphaBlend, samplerState: samplerState); Rectangle?destRect = null; switch (config.Data.Fit) { case BackgroundImageFit.None: break; case BackgroundImageFit.Fit: { var viewportAspectRatio = viewport.AspectRatio; var textureAspectRatio = (float)texture.Width / texture.Height; if (viewportAspectRatio > textureAspectRatio) { // Width is the limitation destRect = RectHelper.RoundToRectangle(0, (float)(viewport.Height - texture.Height) / 2, viewport.Width, viewport.Width / textureAspectRatio); } else { // Height is the limitation destRect = RectHelper.RoundToRectangle((float)(viewport.Width - texture.Width) / 2, 0, viewport.Height * textureAspectRatio, viewport.Height); } } break; case BackgroundImageFit.Stretch: destRect = viewport.Bounds; break; case BackgroundImageFit.Tile: break; case BackgroundImageFit.Center: destRect = RectHelper.RoundToRectangle((float)(viewport.Width - texture.Width) / 2, (float)(viewport.Height - texture.Height) / 2, texture.Width, texture.Height); break; case BackgroundImageFit.LetterBox: { var viewportAspectRatio = viewport.AspectRatio; var textureAspectRatio = (float)texture.Width / texture.Height; if (viewportAspectRatio > textureAspectRatio) { // Width is the limitation var newWidth = viewport.Height * textureAspectRatio; destRect = RectHelper.RoundToRectangle((viewport.Width - newWidth) / 2, 0, newWidth, viewport.Height); } else { // Height is the limitation var newHeight = viewport.Width / textureAspectRatio; destRect = RectHelper.RoundToRectangle(0, (viewport.Height - newHeight) / 2, viewport.Width, newHeight); } } break; default: throw new ArgumentOutOfRangeException(); } if (destRect != null) { game.SpriteBatch.Draw(texture, destRect.Value, Color.White); } else { game.SpriteBatch.Draw(texture, Vector2.Zero, Color.White); } game.SpriteBatch.End(); } }
protected override void OnDrawBuffer(GameTime gameTime) { base.OnDrawBuffer(gameTime); if (!_isAnimationStarted) { return; } var theaterDays = Game.ToBaseGame(); var syncTimer = theaterDays.FindSingleElement <SyncTimer>(); if (syncTimer == null) { throw new InvalidOperationException(); } var scalingResponder = theaterDays.FindSingleElement <MltdStageScalingResponder>(); if (scalingResponder == null) { throw new InvalidOperationException(); } var tapPoints = theaterDays.FindSingleElement <TapPoints>(); if (tapPoints == null) { throw new InvalidOperationException(); } var currentTime = syncTimer.CurrentTime; if (currentTime < _animationStartedTime) { // Automatically cancels the animation if the user steps back in UI. _isAnimationStarted = false; return; } var animationTime = (currentTime - _animationStartedTime).TotalSeconds; if (animationTime > _stage1Duration + _stage2Duration) { Opacity = 0; _isAnimationStarted = false; return; } if (_selectedImageIndex < 0 || _selectedImageIndex >= _hitRankImages.Count) { return; } var clientSize = theaterDays.GraphicsDevice.Viewport; var scalingResults = scalingResponder.ScaleResults; var config = ConfigurationStore.Get <HitRankAnimationConfig>(); var hitRankLayout = config.Data.Layout; var perc = (float)animationTime / (float)(_stage1Duration + _stage2Duration); var scale = MathHelper.Lerp(_initialScale, 1, perc); var centerX = hitRankLayout.X.IsPercentage ? hitRankLayout.X.Value * clientSize.Width : hitRankLayout.X.Value; var centerY = hitRankLayout.Y.IsPercentage ? hitRankLayout.Y.Value * clientSize.Height : hitRankLayout.Y.Value; var scaledWidth = scalingResults.HitRank.X * scale; var scaledHeight = scalingResults.HitRank.Y * scale; var spriteBatch = theaterDays.SpriteBatch; var destRect = RectHelper.RoundToRectangle(centerX - scaledWidth / 2, centerY - scaledHeight / 2, scaledWidth, scaledHeight); spriteBatch.BeginOnBufferedVisual(); spriteBatch.Draw(_hitRankImages, _selectedImageIndex, destRect); spriteBatch.End(); }