public static void DrawHoldRegionToPreview(System.Drawing.Graphics g, IReadOnlyPreviewDisplayEnvironment env, Hold hold) { if (hold.HoldEnd.Timing <= env.TimingOffset) { return; } if (hold.HoldBegin.Timing >= env.TimingOffset + env.TimingLength) { return; } var notes = hold.AllNotes.OrderBy(x => x.Timing).ToList(); for (var i = 0; i < notes.Count - 1; ++i) { var begin = notes[i]; var end = notes[i + 1]; if (begin.Timing >= env.TimingOffset + env.TimingLength) { continue; } if (end.Timing <= env.TimingOffset) { continue; } DrawHoldStep(g, env, begin, end); } }
public static void DrawToPreview(System.Drawing.Graphics g, IReadOnlyPreviewDisplayEnvironment env, NoteBook noteBook) { foreach (var hold in noteBook.Holds) { DrawHoldRegionToPreview(g, env, hold); DrawToPreview(g, env, hold.HoldBegin); DrawToPreview(g, env, hold.HoldEnd); } foreach (var note in noteBook.Notes) { DrawToPreview(g, env, note); } }
public static void DrawToPreview(System.Drawing.Graphics g, IReadOnlyPreviewDisplayEnvironment env, NoteBase note) { var diff = note.Timing - env.TimingOffset; float r = 1 - (float)(diff / env.TimingLength).BarRatio; if (r <= 0 || r > 1) { return; } var lane1 = note.Lane.NormalizedLane; float startDeg = CalcCsDeg(6 * lane1); float degSize = CalcCsDegSize(6 * note.NoteSize.Size); using (var p = new Pen(NoteGraphicsGenerator.GetColor(note.NoteType), 5)) { r *= env.Radius; g.DrawArc(p, env.CenterPoint.X - r, env.CenterPoint.Y - r, 2 * r, 2 * r, startDeg, degSize); } }
public static void Draw(System.Drawing.Graphics g, IReadOnlyPreviewDisplayEnvironment env, IReadOnlyList <Score.IReadOnlyScore> scores) { using (var backBrush = new SolidBrush(Color.Black)) using (var gameDisplayBrush = new SolidBrush(Color.FromArgb(50, 50, 50))) using (var penMain = new Pen(Color.White)) using (var penSub = new Pen(Color.FromArgb(130, Color.White))) using (Font myFont = new Font("MS UI Gothic", 10, FontStyle.Regular)) { g.FillRectangle(backBrush, env.DisplayRegion); g.FillEllipse(gameDisplayBrush, env.Circle); g.DrawEllipse(penMain, env.Circle); var circleCenter = new Point(env.Circle.X + env.Radius, env.Circle.Y + env.Radius); var vanishingTiming = env.TimingOffset + env.TimingLength; foreach (var score in scores.Where(x => env.TimingOffset < x.TimingEnd && x.TimingBegin < vanishingTiming)) { // 主線小節番号の描画 var r = (int)(((vanishingTiming - score.TimingBegin) / env.TimingLength).BarRatio * env.Radius); var c = new Rectangle(circleCenter.X - r, circleCenter.Y - r, 2 * r, 2 * r); if (0 < r && r < env.Radius) { g.DrawEllipse(penMain, c); // TODO: 表示/非表示を切り替えられるようにしたら良いかもね g.DrawString(scores.IndexOf(score).ToString().PadLeft(3, '0'), myFont, Brushes.White, new Point(c.Left + c.Width / 2 - 14, c.Bottom - 6)); } // 副線の描画 // TODO: 表示/非表示を切り替えられるようにしたら良いかもね for (var cnt = 1; cnt < score.BeatNum; ++cnt) { r = (int)(((vanishingTiming - score.TimingBegin - new TimingPosition(score.BeatDen, cnt)) / env.TimingLength).BarRatio * env.Radius); if (!(0 < r && r < env.Radius)) { continue; } c = new Rectangle(circleCenter.X - r, circleCenter.Y - r, 2 * r, 2 * r); g.DrawEllipse(penSub, c); } } } }
private static void DrawHoldStep(System.Drawing.Graphics g, IReadOnlyPreviewDisplayEnvironment env, NoteBase begin, NoteBase end) { using (var clipPath = new GraphicsPath()) { clipPath.AddEllipse(env.Circle); g.Clip = new Region(clipPath); } var step = 5; // 円の中央が0 var rbegin = (1 - ((begin.Timing - env.TimingOffset) / env.TimingLength).BarRatio) * env.Radius; var rend = (1 - ((end.Timing - env.TimingOffset) / env.TimingLength).BarRatio) * env.Radius; var dr = rbegin - rend; var dlleft = end.Lane.RawLane - begin.Lane.RawLane; var dlright = (end.Lane.RawLane + end.NoteSize.Size) - (begin.Lane.RawLane + begin.NoteSize.Size); var psLeft = new List <Point>(); var psRight = new List <Point>(); var curR = rbegin - step; while (true) { if (curR <= 0 || curR <= rend) { break; } if (dlleft != 0 || curR <= step) { var radLeft = MyMath.DegToRad(CalcCsDeg((float)(begin.Lane.RawLane * 6 + (rbegin - curR) / dr * dlleft * 6))); psLeft.Add(new Point((int)(env.CenterPoint.X + curR * Math.Cos(radLeft)), (int)(env.CenterPoint.Y + curR * Math.Sin(radLeft)))); } if (dlright != 0 || curR <= step) { var radRight = MyMath.DegToRad(CalcCsDeg((float)((begin.Lane.RawLane + begin.NoteSize.Size) * 6 + (rbegin - curR) / dr * dlright * 6))); psRight.Add(new Point((int)(env.CenterPoint.X + curR * Math.Cos(radRight)), (int)(env.CenterPoint.Y + curR * Math.Sin(radRight)))); } curR -= step; } var path = new GraphicsPath(); if (psLeft.Any()) { path.AddLines(psLeft.ToArray()); } if (rend > 0) { path.AddArc( (float)(env.CenterPoint.X - rend), (float)(env.CenterPoint.Y - rend), (float)(2 * rend), (float)(2 * rend), CalcCsDeg(end.Lane.NormalizedLane * 6), CalcCsDegSize(end.NoteSize.Size * 6)); } if (psRight.Any()) { path.AddLines(psRight.Reverse <Point>().ToArray()); } if (rbegin > 0) { path.AddArc( (float)(env.CenterPoint.X - rbegin), (float)(env.CenterPoint.Y - rbegin), (float)(2 * rbegin), (float)(2 * rbegin), CalcCsDeg((begin.Lane.NormalizedLane + begin.NoteSize.Size) * 6), CalcCsDegSize(-begin.NoteSize.Size * 6)); } // 色は決め打ちではなく,名前つけて一か所にまとめた方がいいかもね using (var sb = new SolidBrush(Color.FromArgb(200, 200, 175, 90))) { try { g.FillPath(sb, path); } catch (Exception) { } } path.Dispose(); g.ResetClip(); }