public static SKRect ResizingBehaviorApply(ResizingBehavior behavior, SKRect rect, SKRect target) { if (rect.Equals(target) || target == null) { return(rect); } if (behavior == ResizingBehavior.Stretch) { return(target); } float xRatio = Math.Abs(target.Width / rect.Width); float yRatio = Math.Abs(target.Height / rect.Height); float scale = 0f; switch (behavior) { case ResizingBehavior.AspectFit: { scale = Math.Min(xRatio, yRatio); break; } case ResizingBehavior.AspectFill: { scale = Math.Max(xRatio, yRatio); break; } case ResizingBehavior.Center: { scale = 1f; break; } } float newWidth = Math.Abs(rect.Width * scale); float newHeight = Math.Abs(rect.Height * scale); return(new SKRect(target.MidX - newWidth / 2, target.MidY - newHeight / 2, target.MidX + newWidth / 2, target.MidY + newHeight / 2)); }
public override void RenderStats(IStateOwner pOwner, SKCanvas pRenderTarget, GameplayGameState Source, GameStateSkiaDrawParameters Element) { var Bounds = Element.Bounds; var g = pRenderTarget; bool RedrawsNeeded = !LastDrawStat.Equals(Bounds); try { if (StatisticsBackground == null || RedrawsNeeded || Source.f_RedrawStatusBitmap || LastStatisticsTheme != Source.PlayField.Theme) { GenerateStatisticsBackground(Source); } g.DrawImage(StatisticsBackground, Bounds); //g.Clear(Color.Black); if (!Source.HasTetrominoSKBitmaps() || RedrawsNeeded) { RedrawStatusbarTetrominoBitmaps(pOwner, Source, Bounds); } lock (Source.LockTetImageRedraw) { var useStats = Source.GameStats; double Factor = Bounds.Height / 644d; var DesiredFontPixelHeight = 22d; // PixelsToPoints((int)(Bounds.Height * (30d / 644d))); float DesiredFontSize = (float)(DesiredFontPixelHeight * pOwner.ScaleFactor); SKTypeface standardFont = TetrisGame.RetroFontSK; //Font standardFont = new Font(TetrisGame.RetroFont, DesiredFontPixelHeight, FontStyle.Bold, GraphicsUnit.Pixel); var TopScore = Source.GetLocalScores() == null?0:Source.GetLocalScores().GetScores().First().Score; int MaxScoreLength = Math.Max(TopScore.ToString().Length, useStats.Score.ToString().Length); String CurrentScoreStr = useStats.Score.ToString().PadLeft(MaxScoreLength + 2); String TopScoreStr = TopScore.ToString().PadLeft(MaxScoreLength + 2); //TODO: redo this segment separately, so we can have the labels left-aligned and the values right-aligned. // String BuildStatString = "Time: " + FormatGameTime(pOwner).ToString().PadLeft(MaxScoreLength + 2) + "\n" + // "Score: " + CurrentScoreStr + "\n" + // "Top: " + TopScoreStr + " \n" + // "Lines: " + GameStats.LineCount.ToString().PadLeft(MaxScoreLength+2); //SKPaint skp = new SKPaint(){Style = SKPaintStyle.Fill,Color=; //g.DrawRect(); g.DrawRect(Bounds.Left, Bounds.Top + 5, Bounds.Width - 10, (int)(450 * Factor), LightenBrush); //String[] StatLabels = new string[] { "Time:", "Score:", "Top:", "Lines:" }; //int LineCount = Source.GameStats is TetrisStatistics ? (Source.GameStats as TetrisStatistics).LineCount : 0; //String[] StatValues = new string[] { FormatGameTime(pOwner), useStats.Score.ToString(), TopScore.ToString(), LineCount.ToString() }; WhiteBrush.TextSize = BlackBrush.TextSize = DesiredFontSize; WhiteBrush.Typeface = BlackBrush.Typeface = TetrisGame.RetroFontSK; SKRect MeasureLabel = new SKRect(), MeasureValue = new SKRect(); BlackBrush.MeasureText("#", ref MeasureLabel); BlackBrush.MeasureText("#", ref MeasureValue); SKPoint StatPosition = new SKPoint(Bounds.Left + (int)(7 * Factor), Bounds.Top + MeasureLabel.Height + (int)(14 * Factor)); float CurrentYPosition = StatPosition.Y + MeasureLabel.Height; var StatData = useStats.GetDisplayStatistics(pOwner, Source); int MaxLabelLength = 0; int MaxValueLength = 0; foreach (var statkvp in StatData) { if (MaxLabelLength < statkvp.Key.Length) { MaxLabelLength = statkvp.Key.Length; } if (MaxValueLength < statkvp.Value.Length) { MaxValueLength = statkvp.Value.Length; } } foreach (var statkvp in StatData) //for (int statindex = 0; statindex < StatLabels.Length; statindex++) { String Label = statkvp.Key; String Value = statkvp.Value.PadLeft(MaxValueLength, ' '); float LabelWidth = BlackBrush.MeasureText(Label.Replace(" ", "_") + "###", ref MeasureLabel); float ValueWidth = BlackBrush.MeasureText(Value.Replace(" ", "_") + "###", ref MeasureValue); //var MeasureLabel = g.MeasureString(StatLabels[statindex], standardFont); //var MeasureValue = g.MeasureString(StatValues[statindex], standardFont); float LargerHeight = Math.Max(MeasureLabel.Height, MeasureValue.Height); //we want to draw the current stat label at position StatPosition.X,CurrentYPosition... // TetrisGame.DrawTextSK(g, StatLabels[statindex], new SKPoint(StatPosition.X, CurrentYPosition), // TetrisGame.RetroFontSK, SKColors.Black, DesiredFontSize, (float)pOwner.ScaleFactor); //draw labels... g.DrawText(Label, new SKPoint(StatPosition.X + 5, CurrentYPosition + 5), WhiteBrush); g.DrawText(Label, new SKPoint(StatPosition.X, CurrentYPosition), BlackBrush); SKPoint ValuePosition = new SKPoint((float)(Bounds.Right - ((MeasureValue.Width) + (7 * Factor))), CurrentYPosition); g.DrawText(Value, new SKPoint(ValuePosition.X + 5, ValuePosition.Y + 5), WhiteBrush); g.DrawText(Value, new SKPoint(ValuePosition.X, ValuePosition.Y), BlackBrush); //TetrisGame.DrawTextSK(g, PaintInfo); //TetrisGame.DrawTextSK(g, PaintInfo); //we want to draw the current stat value at Bounds.Width-ValueWidth. //TetrisGame.DrawTextSK(g, StatValues[statindex], new SKPoint((float)(Bounds.Right - ((MeasureValue.Width) + (5 * Factor))), CurrentYPosition), TetrisGame.RetroFontSK, SKColors.Black, DesiredFontSize, (float)pOwner.ScaleFactor); //add the larger of the two heights to the current Y Position. CurrentYPosition += (int)LargerHeight; CurrentYPosition += 10; } var findRenderer = Source.GameHandler.GetStatAreaRenderer <SKCanvas, GameStateSkiaDrawParameters>(); if (findRenderer != null) { //bounds of stat area. var LeftBound = Bounds.Left + (int)(30 * Factor); var TopBound = Bounds.Top + (int)(140 * Factor); SKRect useBounds = new SKRect(LeftBound, TopBound, Bounds.Right, (float)(420 * Factor)); GameStateSkiaDrawParameters parameters = new GameStateSkiaDrawParameters(useBounds); findRenderer.Render(pOwner, pRenderTarget, Source, parameters); } else { } SKPoint NextDrawPosition = new SKPoint(Bounds.Left + (int)(40f * Factor), Bounds.Top + (int)(420 * Factor)); Size NextSize = new Size((int)(200f * Factor), (int)(200f * Factor)); SKPoint CenterPoint = new SKPoint(NextDrawPosition.X + NextSize.Width / 2, NextDrawPosition.Y + NextSize.Height / 2); if (Source.NextBlocks.Count > 0) { var QueueList = Source.NextBlocks.ToArray(); SKBitmap[] NextTetrominoes = (from t in QueueList select Source.GetTetrominoSKBitmap(pOwner, t)).ToArray(); SKBitmap DisplayBox = TetrisGame.Imageman.GetSKBitmap("display_box"); //draw it at 40,420. (Scaled). float ScaleDiff = 0; iActiveSoundObject PlayingMusic; if ((PlayingMusic = TetrisGame.Soundman.GetPlayingMusic_Active()) != null) { Source.StoredLevels.Enqueue(PlayingMusic.Level); } if (Source.StoredLevels.Count >= 4) { ScaleDiff = Math.Min(30, 10 * Source.StoredLevels.Dequeue()); } if (!TetrisGame.DJMode) { ScaleDiff = 0; } SKRect useRectangle = new SKRect(NextDrawPosition.X - ScaleDiff, NextDrawPosition.Y - ScaleDiff, NextDrawPosition.X - ScaleDiff + NextSize.Width + ScaleDiff * 2, NextDrawPosition.Y - ScaleDiff + NextSize.Height + ScaleDiff * 2); g.DrawBitmap(DisplayBox, useRectangle); g.DrawCircle(CenterPoint.X - 5, CenterPoint.Y - 5, 5, BlackBrush); //new "wiggling" mode. add Sin(timer*(5*index))*30 to the angle. for (int i = NextTetrominoes.Length - 1; i > -1; i--) { var baseval = ((double)(DateTime.Now.Ticks + (250000 * i)) / 5000000); //var AngleAdd = Math.Sin(baseval) * 10; //old approach. var AngleAdd = (Math.Sin(baseval) * Math.Cos(baseval * 2)) * 7; //new approach, tries to be a little bit different... //var AngleAdd = Math.Sin(((double)DateTime.Now.Millisecond / 166)) * 15; double StartAngle = Math.PI; double AngleIncrementSize = (Math.PI * 1.8) / (double)NextTetrominoes.Length; //we draw starting at StartAngle, in increments of AngleIncrementSize. //i is the index- we want to increase the angle by that amount (well, obviously, I suppose... double UseAngleCurrent = StartAngle + AngleIncrementSize * (float)i + Source.NextAngleOffset; double UseXPosition = CenterPoint.X + ((float)((NextSize.Width) / 2.2) * Math.Cos(UseAngleCurrent)); double UseYPosition = CenterPoint.Y + ((float)((NextSize.Height) / 2.2) * Math.Sin(UseAngleCurrent)); var NextTetromino = NextTetrominoes[i]; if (NextTetromino == null) { continue; } float Deviation = (i - NextTetrominoes.Length / 2); Point Deviate = new Point((int)(Deviation * 20 * Factor), (int)(Deviation * 20 * Factor)); var AngleRotateLocation = DateTime.Now.Ticks / 5000000; Point DrawTetLocation = new Point((int)UseXPosition - (NextTetromino.Width / 2), (int)UseYPosition - NextTetromino.Height / 2); //Point DrawTetLocation = new Point(Deviate.X + (int)(NextDrawPosition.X + ((float)NextSize.Width / 2) - ((float)NextTetromino.Width / 2)), // Deviate.Y + (int)(NextDrawPosition.Y + ((float)NextSize.Height / 2) - ((float)NextTetromino.Height / 2))); double AngleMovePercent = Source.NextAngleOffset / AngleIncrementSize; double NumAffect = Source.NextAngleOffset == 0 ? 0 : AngleIncrementSize / Source.NextAngleOffset; Size DrawTetSize = new Size ( (int)((float)(NextTetromino.Width * 1.5f) * (0.3 + (1 - ((float)(i) * 0.15f) - .15f * AngleMovePercent))), (int)((float)(NextTetromino.Height * 1.5f) * (0.3 + (1 - ((float)(i) * 0.15f) - .15f * AngleMovePercent)))); //g.TranslateTransform(CenterPoint.X,CenterPoint.Y); double DrawTetAngle = UseAngleCurrent; DrawTetAngle += (Math.PI * AngleMovePercent); float useDegrees = 180 + (float)(DrawTetAngle * (180 / Math.PI)); useDegrees = (float)(useDegrees + AngleAdd); g.RotateDegrees(useDegrees, DrawTetLocation.X + DrawTetSize.Width / 2, DrawTetLocation.Y + DrawTetSize.Width / 2); var DrawAdjustmentAngle = MathHelper.mod((int)(((double)DateTime.Now.Ticks / 400) * (5f * i)), 360); if (DrawTetSize.Width > 0 && DrawTetSize.Height > 0) { //ImageAttributes Shade = GetShadowAttributes(1.0f - ((float)i * 0.3f)); //ImageAttributes Shade = new ImageAttributes(); //Shade.SetColorMatrix(ColorMatrices.GetFader(1.0f - ((float)i * 0.1f))); SKRect DrawBound = new SKRect(DrawTetLocation.X, DrawTetLocation.Y, DrawTetLocation.X + DrawTetSize.Width, DrawTetLocation.Y + DrawTetSize.Height); //for the shade we would need to deal with SKPaint, I feel. Want to get it working somewhat first though. g.DrawBitmap(NextTetromino, DrawBound, null); } g.ResetMatrix(); } } if (Source.HoldBlock != null) { SKBitmap HoldTetromino = Source.GetTetrominoSKBitmap(Source.HoldBlock.GetType()); if (HoldTetromino != null) { g.DrawBitmap(HoldTetromino, CenterPoint.X - HoldTetromino.Width / 2, CenterPoint.Y - HoldTetromino.Height / 2); } } } } finally { LastDrawStat = Bounds; } }