/// <summary> /// nullを返すことがあります /// </summary> /// <param name="lane"></param> /// <param name="timing"></param> /// <param name="size"></param> /// <param name="noteType"></param> /// <returns></returns> public static ShortNote Factory(LanePotision lane, TimingPosition timing, NoteSize size, NoteType noteType) { switch (noteType) { case NoteType.Touch: return(new Touch(lane, timing, size)); case NoteType.Chain: return(new Chain(lane, timing, size)); case NoteType.SlideL: return(new SlideL(lane, timing, size)); case NoteType.SlideR: return(new SlideR(lane, timing, size)); case NoteType.SnapU: return(new SnapU(lane, timing, size)); case NoteType.SnapD: return(new SnapD(lane, timing, size)); default: Debug.Assert(false); return(null); } }
public void Exchange(JsonObject json) { BeatNum = uint.Parse(json["BeatNum"]); BeatDen = uint.Parse(json["BeatDen"]); TimingBegin = new TimingPosition(1, 0); TimingBegin.Exchange(json["TimingBegin"]); }
public Hold(LanePotision lane, TimingPosition timingBegin, TimingPosition timingEnd, NoteSize size) { System.Diagnostics.Debug.Assert(timingBegin < timingEnd); HoldBegin = new HoldBegin(lane, timingBegin, size); HoldBegin.PositionChanging += (begin, beginLane, beginTiming) => { if (stepNotes.Where(x => x.Timing <= beginTiming).Any()) { return(false); } if (!(beginTiming < HoldEnd.Timing)) { return(false); } return(true); }; HoldEnd = new HoldEnd(lane, timingEnd, size); HoldEnd.PositionChanging += (end, endLane, endTiming) => { if (stepNotes.Where(x => x.Timing >= endTiming).Any()) { return(false); } if (!(HoldBegin.Timing < endTiming)) { return(false); } return(true); }; stepNotes = new List <HoldStepNote>(); }
public EditorStatus(EditorMode edit, NoteMode note, int size, TimingPosition beat) { EditorMode = edit; NoteMode = note; NoteSize = size; BeatStride = beat; }
public override bool ReLocate(LanePotision lane, TimingPosition timing) { if (PositionChanging is null) { return(false); } if (!PositionChanging.Invoke(this, lane, timing)) { timing = Timing; } return(base.ReLocate(lane, timing)); }
public void EqualsTest1() { var lhs = new TimingPosition(2, 1); var rhs = new TimingPosition(3, 1); var sum = new TimingPosition(6, 5); Assert.IsTrue(lhs > rhs); Assert.IsTrue(lhs >= rhs); Assert.IsTrue(lhs != rhs); Assert.IsFalse(lhs < rhs); Assert.IsFalse(lhs <= rhs); Assert.IsFalse(lhs == rhs); Assert.IsTrue(lhs + rhs == sum); }
public void EqualsTest2() { var lhs = new TimingPosition(1, 1); var rhs = new TimingPosition(48, 7); var sub = new TimingPosition(48, 41); //Assert.IsTrue(lhs > rhs); //Assert.IsTrue(lhs >= rhs); //Assert.IsTrue(lhs != rhs); //Assert.IsFalse(lhs < rhs); //Assert.IsFalse(lhs <= rhs); //Assert.IsFalse(lhs == rhs); var calc = lhs - rhs; Assert.IsTrue(lhs - rhs == sub); }
private bool IsStepNoteTimingValid(TimingPosition timing) { if (timing is null) { return(false); } if (timing <= HoldBegin.Timing || timing >= HoldEnd.Timing) { return(false); } if (stepNotes.Where(x => x.Timing == timing).Any()) { return(false); } return(true); }
/// <summary> /// 絶対実座標から仮想座標を計算します /// LaneのRangeは(-inf, inf)(RawLaneを計算) /// </summary> /// <param name="env">エディタレーン環境</param> /// <param name="p">実座標(左上原点)</param> /// <param name="beat">拍数のストライド</param> /// <param name="scores"></param> /// <param name="position">計算された仮想座標</param> /// <returns>仮想座標の計算に成功したかどうか</returns> public static bool ConvertRealToVirtual(IReadOnlyEditorLaneEnvironment env, Point p, TimingPosition beat, IReadOnlyList <IReadOnlyScore> scores, out Position position) { p = new Point(p.X - env.PanelRegion.X, p.Y - env.PanelRegion.Y); position = null; if (env.AvailableLaneWidth == 0) { return(false); } var laneLeft = env.SideMargin; var laneRight = laneLeft + env.AvailableLaneWidth; if (!(laneLeft <= p.X && p.X < laneRight)) { return(false); } int lanePos = (int)(((p.X - laneLeft) + env.OffsetXRaw) / env.LaneUnitWidth); if ((p.X - laneLeft) + env.OffsetXRaw < 0) { lanePos--; } var newLanePos = new LanePotision(lanePos); var timing = new TimingPosition(env.TimingUnitHeight.ToUInt(), (env.PanelRegion.Height - p.Y) - (int)env.BottomMargin + env.OffsetY); var accum = new TimingPosition(1, 0); foreach (var score in scores) { var tmp = new TimingPosition(score.BeatDen, (int)score.BeatNum); if (timing < tmp + accum) { break; } accum += tmp; } var cnt = (int)Math.Floor(((timing - accum) / beat).BarRatio); var newTimingPos = new TimingPosition(beat.DivValue, cnt) + accum; position = new Position(newLanePos, newTimingPos); return(true); }
public HoldRelay(LanePotision lane, TimingPosition timing, NoteSize size) : base(lane, timing, size) { }
protected HoldStepNote(LanePotision lane, TimingPosition timing, NoteSize size) : base(lane, timing, size) { }
public PreviewNote(LanePotision lane, TimingPosition timing, NoteSize size) : base(lane, timing, size) { }
protected ShortNote(LanePotision lane, TimingPosition timing, NoteSize size) : base(lane, timing, size) { }
public SnapD(LanePotision lane, TimingPosition timing, NoteSize size) : base(lane, timing, size) { }
public static void Draw(System.Drawing.Graphics g, IReadOnlyEditorLaneEnvironment env, IReadOnlyList <Score.IReadOnlyScore> scores) { using (var backgroundBrush = new SolidBrush(backgroundColor)) using (var laneBackBrush = new SolidBrush(laneBackColor)) { g.FillRectangle(backgroundBrush, env.PanelRegion); g.FillRectangle(laneBackBrush, env.LaneRect); } using (var penBorder = new Pen(Color.White)) using (var penMain = new Pen(Color.FromArgb(200, Color.White))) using (var penSub = new Pen(Color.FromArgb(130, Color.White))) using (Font myFont = new Font("MS UI Gothic", 10, FontStyle.Bold)) using (var penTimingMain = new Pen(timingMainColor)) { // レーン補助線を描画 var diffX = (int)(env.LaneUnitWidth - env.OffsetX % env.LaneUnitWidth); if (diffX == env.LaneUnitWidth) { diffX = 0; } var curX = diffX + env.LaneRect.Left; var curLane = (diffX + env.OffsetX) / env.LaneUnitWidth; for (; curX <= env.LaneRect.Right; curX += (int)env.LaneUnitWidth, ++curLane) { curLane %= MadcaEnv.LaneCount; if (curLane % env.LaneGroupCount == 0) { g.DrawLine(penMain, new PointF(curX, env.PanelRegion.Y), new PointF(curX, env.PanelRegion.Y + env.AvailableLaneHeight)); var textWidth = System.Windows.Forms.TextRenderer.MeasureText(g, curLane.ToString(), myFont).Width; g.DrawString(curLane.ToString(), myFont, Brushes.White, new PointF(curX - textWidth / 2 + 1.5f, env.PanelRegion.Y + env.AvailableLaneHeight + 5)); continue; } g.DrawLine(penSub, new PointF(curX, env.PanelRegion.Y), new PointF(curX, env.PanelRegion.Y + env.AvailableLaneHeight)); } // 小節線などを描画 if (scores == null) { return; } var offsetTimingMin = new TimingPosition(env.TimingUnitHeight.ToUInt(), env.OffsetY); var offsetTimingMax = new TimingPosition(env.TimingUnitHeight.ToUInt(), env.OffsetY + env.LaneRect.Height); var drawScores = scores.Where(x => !(x.TimingEnd <= offsetTimingMin || offsetTimingMax < x.TimingBegin)); foreach (var score in drawScores) { var y = (int)(env.LaneRect.Bottom - (score.TimingBegin - offsetTimingMin).BarRatio * env.TimingUnitHeight); if (env.LaneRect.Top <= y && y <= env.LaneRect.Bottom) { g.DrawString(scores.IndexOf(score).ToString().PadLeft(3, '0'), myFont, Brushes.White, new Point(env.LaneRect.Left - 28, y - 12)); g.DrawLine(penTimingMain, new Point(env.LaneRect.Left, y), new Point(env.LaneRect.Right, y)); } for (var cnt = 1; cnt < score.BeatNum; ++cnt) { y -= (int)(env.TimingUnitHeight / score.BeatDen); if (env.LaneRect.Top <= y && y <= env.LaneRect.Bottom) { g.DrawLine(penSub, new Point(env.LaneRect.Left, y), new Point(env.LaneRect.Right, y)); } } } } }
public virtual bool ReLocate(LanePotision lane, TimingPosition timing) { Lane = new LanePotision(lane); Timing = new TimingPosition(timing); return(true); }
protected NoteBase(LanePotision lane, TimingPosition timing, NoteSize size) { Lane = new LanePotision(lane); Timing = new TimingPosition(timing); NoteSize = new NoteSize(size); }