示例#1
0
 public void FillLane()
 {
     if (LaneBook.Any())
     {
         FillLane(LaneBook.First());
     }
 }
示例#2
0
 public override void RelocateOnlyAndUpdate(Position position, LaneBook laneBook)
 {
     base.RelocateOnlyAndUpdate(position, laneBook);
     Air?.RelocateOnlyAndUpdate(position, laneBook);
     airHoldBegin?.Relocate(position);
     airHoldBegin?.UpdateLocation(laneBook);
 }
示例#3
0
 // REVIEW: この辺の生ノーツデータを手づかみで触る処理はここじゃなくてNoteBookでやったほうが安全じゃない…?
 private void ReverseShortNotes(List <Note> noteList, LaneBook laneBook, NoteBook noteBook)
 {
     noteList.ForEach(x =>
     {
         int reverseLane      = BottomRightPosition.Lane - (x.Position.Lane - TopLeftPosition.Lane + x.Size) + 1;
         Position newPosition = new Position(reverseLane, x.Position.Tick);
         x.RelocateOnlyAndUpdate(newPosition, laneBook);
         if (x is AirableNote airable && airable.IsAirAttached)
         {
             Air newAir = null;
             if (airable.Air is AirUpL)
             {
                 newAir = new AirUpR(x);
             }
             else if (airable.Air is AirUpR)
             {
                 newAir = new AirUpL(x);
             }
             else if (airable.Air is AirDownL)
             {
                 newAir = new AirDownR(x);
             }
             else if (airable.Air is AirDownR)
             {
                 newAir = new AirDownL(x);
             }
             if (newAir != null)
             {
                 noteBook.DetachAirFromAirableNote(airable, out _);
                 noteBook.AttachAirToAirableNote(airable, newAir);
             }
         }
     });
 }
示例#4
0
        public override void Draw(Graphics g, Point drawLocation, LaneBook laneBook)
        {
            base.Draw(g, drawLocation, laneBook);
            var list = this.OrderBy(x => x.Position.Tick).ToList();

            foreach (Note note in list)
            {
                // 画面外の場合は描画しないようにしてなるべく処理を軽くしたい
                if (note.Position.Tick > Status.DrawTickLast)
                {
                    continue;
                }
                if (list.IndexOf(note) < list.Count - 1)
                {
                    Note next = list.Next(note);
                    // 画面外の場合は描画しないようにしてなるべく処理を軽くしたい
                    if (next.Position.Tick < Status.DrawTickFirst)
                    {
                        continue;
                    }
                    DrawAirHoldLine(g, note, next, drawLocation, laneBook);
                }
                //クリッピングの解除を忘れないこと
                g.ResetClip();
                note.Draw(g, drawLocation);
            }
        }
示例#5
0
 // REVIEW: この辺の生ノーツデータを手づかみで触る処理はここじゃなくてNoteBookでやったほうが安全じゃない…?
 public void ReverseNotes(NoteBook noteBook, LaneBook laneBook)
 {
     ReverseShortNotes(SelectedNoteList, laneBook, noteBook);
     SelectedLongNoteList.ForEach(x =>
     {
         ReverseShortNotes(x, laneBook, noteBook);
     });
 }
示例#6
0
 public Model()
 {
     NoteBook  = new NoteBook();
     ScoreBook = new ScoreBook();
     LaneBook  = new LaneBook();
     LaneBook.UpdateNoteLocation += NoteBook.UpdateNoteLocation;
     MusicInfo = new MusicInfo();
 }
示例#7
0
        public void Draw(Graphics g, LaneBook laneBook, Point originLocation)
        {
            if (StartPosition == null || EndPosition == null)
            {
                return;
            }
            ScoreLane futureLane = laneBook.Find(
                x => x.StartTick <= TopLeftPosition.Tick && TopLeftPosition.Tick <= x.EndTick);
            ScoreLane pastLane = laneBook.Find(
                x => x.StartTick <= BottomRightPosition.Tick && BottomRightPosition.Tick <= x.EndTick);
            int    passingLanes = futureLane != null ? futureLane.Index - pastLane.Index : laneBook.Count - pastLane.Index - 1;
            PointF topLeft      = new PointF(
                pastLane.LaneRect.Left + TopLeftPosition.Lane * ScoreInfo.UnitLaneWidth - originLocation.X,
                pastLane.LaneRect.Bottom - (TopLeftPosition.Tick - pastLane.StartTick) * ScoreInfo.UnitBeatHeight - originLocation.Y - minHeight / 2);
            PointF topRight = new PointF(
                pastLane.LaneRect.Left + (BottomRightPosition.Lane + 1) * ScoreInfo.UnitLaneWidth - originLocation.X,
                pastLane.LaneRect.Bottom - (TopLeftPosition.Tick - pastLane.StartTick) * ScoreInfo.UnitBeatHeight - originLocation.Y - minHeight / 2);
            PointF bottomLeft = new PointF(
                pastLane.LaneRect.Left + TopLeftPosition.Lane * ScoreInfo.UnitLaneWidth - originLocation.X,
                pastLane.LaneRect.Bottom - (BottomRightPosition.Tick - pastLane.StartTick) * ScoreInfo.UnitBeatHeight - originLocation.Y + minHeight / 2);
            PointF bottomRight = new PointF(
                pastLane.LaneRect.Left + (BottomRightPosition.Lane + 1) * ScoreInfo.UnitLaneWidth - originLocation.X,
                pastLane.LaneRect.Bottom - (BottomRightPosition.Tick - pastLane.StartTick) * ScoreInfo.UnitBeatHeight - originLocation.Y + minHeight / 2);

            using (GraphicsPath graphicsPath = new GraphicsPath())
            {
                var smoothingMode = g.SmoothingMode;
                g.SmoothingMode = SmoothingMode.Default;
                var itrLane = pastLane;
                for (int i = 0; i <= passingLanes; ++i, itrLane = laneBook.Next(itrLane))
                {
                    graphicsPath.AddLines(new PointF[] { topLeft, bottomLeft, bottomRight, topRight });
                    graphicsPath.CloseFigure();
                    if (itrLane.StartTick <= Status.DrawTickLast && itrLane.EndTick >= Status.DrawTickFirst)
                    {
                        using (Pen pen = new Pen(Color.White, 1))
                        {
                            pen.DashPattern = new float[] { 4f, 4f };
                            RectangleF clipRect = new RectangleF(
                                itrLane.LaneRect.X - originLocation.X,
                                itrLane.LaneRect.Y - originLocation.Y,
                                //HACK: 選択領域矩形が少し大きいので見切れないようにする
                                itrLane.LaneRect.Width + 1,
                                itrLane.LaneRect.Height + 5);
                            g.Clip = new Region(clipRect);
                            g.DrawPath(pen, graphicsPath);
                        }
                    }
                    topLeft     = topLeft.Add(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, itrLane.LaneRect.Height);
                    topRight    = topRight.Add(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, itrLane.LaneRect.Height);
                    bottomLeft  = bottomLeft.Add(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, itrLane.LaneRect.Height);
                    bottomRight = bottomRight.Add(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, itrLane.LaneRect.Height);
                    graphicsPath.ClearMarkers();
                }
                g.SmoothingMode = smoothingMode;
            }
            g.ResetClip();
        }
示例#8
0
        public void UpdateLocation(LaneBook laneBook)
        {
            ScoreLane lane = laneBook.Find(x => x.StartTick <= Position.Tick && Position.Tick <= x.EndTick);

            if (lane == null)
            {
                return;
            }
            PointF location = new PointF(
                lane.LaneRect.Left + Position.Lane * ScoreInfo.UnitLaneWidth,
                //HACK: Y座標が微妙にずれるので-1して調節する
                lane.HitRect.Bottom - (Position.Tick - lane.StartTick) * ScoreInfo.UnitBeatHeight - 1);

            RelocateOnly(location, lane.Index);
        }
示例#9
0
        public override void Draw(Graphics g, Point drawLocation, LaneBook laneBook)
        {
            base.Draw(g, drawLocation, laneBook);
            var list = this.OrderBy(x => x.Position.Tick).ToList();

            foreach (Note note in list)
            {
                if (list.IndexOf(note) < list.Count - 1)
                {
                    Note next = list.Next(note);
                    DrawHoldLine(g, note, next, drawLocation, laneBook);
                }
                //クリッピングの解除を忘れないこと
                g.ResetClip();
                note.Draw(g, drawLocation);
            }
        }
示例#10
0
 public RelocateNoteOperation(
     List <Note> noteList, List <LongNote> longNoteList, Position diff, LaneBook laneBook)
 {
     Invoke += () =>
     {
         noteList.ForEach(x =>
         {
             Position positionAfter = new Position(
                 x.Position.Lane + diff.Lane,
                 x.Position.Tick + diff.Tick);
             x.RelocateOnlyAndUpdate(positionAfter, laneBook);
         });
         longNoteList.ForEach(x =>
         {
             x.ForEach(y =>
             {
                 Position positionAfter = new Position(
                     y.Position.Lane + diff.Lane,
                     y.Position.Tick + diff.Tick);
                 y.RelocateOnlyAndUpdate(positionAfter, laneBook);
             });
         });
     };
     Undo += () =>
     {
         noteList.ForEach(x =>
         {
             Position positionAfter = new Position(
                 x.Position.Lane - diff.Lane,
                 x.Position.Tick - diff.Tick);
             x.RelocateOnlyAndUpdate(positionAfter, laneBook);
         });
         longNoteList.ForEach(x =>
         {
             x.ForEach(y =>
             {
                 Position positionAfter = new Position(
                     y.Position.Lane - diff.Lane,
                     y.Position.Tick - diff.Tick);
                 y.RelocateOnlyAndUpdate(positionAfter, laneBook);
             });
         });
     };
 }
示例#11
0
        /// <summary>
        /// 選択矩形の左上の位置が引数のpositionとなるように移動します
        /// </summary>
        /// <param name="position"></param>
        /// <param name="laneBook"></param>
        // REVIEW: この辺の生ノーツデータを手づかみで触る処理はここじゃなくてNoteBookでやったほうが安全じゃない…?
        public void Relocate(Position position, LaneBook laneBook)
        {
            if (StartPosition == null || EndPosition == null || position == null)
            {
                return;
            }
            Position prevStartPosition = new Position(TopLeftPosition);
            Position areaSize          = new Position(BottomRightPosition.Lane - TopLeftPosition.Lane, TopLeftPosition.Tick - BottomRightPosition.Tick);
            int      newStartLane      = position.Lane;

            if (newStartLane < 0)
            {
                newStartLane = 0;
            }
            else if (newStartLane + areaSize.Lane > 15)
            {
                newStartLane = 15 - areaSize.Lane;
            }
            int newStartTick = position.Tick;

            if (newStartTick - areaSize.Tick < 0)
            {
                newStartTick = areaSize.Tick;
            }
            StartPosition = new Position(
                newStartLane,
                newStartTick);
            EndPosition = new Position(
                StartPosition.Lane + areaSize.Lane,
                StartPosition.Tick - areaSize.Tick);
            SelectedNoteList.ForEach(x =>
            {
                Position positionDelta = x.Position - prevStartPosition;
                x.RelocateOnlyAndUpdate(new Position(newStartLane + positionDelta.Lane, newStartTick + positionDelta.Tick), laneBook);
            });
            SelectedLongNoteList.ForEach(x =>
            {
                x.ForEach(y =>
                {
                    Position positionDelta = y.Position - prevStartPosition;
                    y.RelocateOnlyAndUpdate(new Position(newStartLane + positionDelta.Lane, newStartTick + positionDelta.Tick), laneBook);
                });
            });
        }
示例#12
0
 public RelocateNoteOperation(Note note, Position before, Position after, LaneBook laneBook)
 {
     Invoke += () =>
     {
         note.Relocate(after);
         note.UpdateLocation(laneBook);
         if (note is AirableNote airable)
         {
             airable.Air?.UpdateLocation(laneBook);
             airable.AirHold?.UpdateLocation(laneBook);
         }
     };
     Undo += () =>
     {
         note.Relocate(before);
         note.UpdateLocation(laneBook);
         if (note is AirableNote airable)
         {
             airable.Air?.UpdateLocation(laneBook);
             airable.AirHold?.UpdateLocation(laneBook);
         }
     };
 }
示例#13
0
        /// <summary>
        /// SlideCurveの当たり判定
        /// </summary>
        private bool ContainsInCurve(Note past, Note curve, Note future, LaneBook laneBook, PointF locationVirtual)
        {
            int passingLanes = future.LaneIndex - past.LaneIndex;

            using (GraphicsPath graphicsPath = MyUtil.CreateSlideCurvePath(past, curve, future, drawOffset))
            {
                ScoreLane lane = laneBook.Find(x => x.Contains(past));
                for (int i = 0; i <= passingLanes && lane != null; ++i)
                {
                    if (graphicsPath.IsVisible(locationVirtual))
                    {
                        return(true);
                    }
                    else
                    {
                        graphicsPath.Translate(
                            ScoreLane.scoreWidth + ScoreLane.Margin.Left + ScorePanel.Margin.Right + ScorePanel.Margin.Left + ScoreLane.Margin.Right,
                            lane.HitRect.Height);
                        lane = laneBook.Next(lane);
                    }
                }
            }
            return(false);
        }
示例#14
0
        private static void DrawAirHoldLine(Graphics g, Note past, Note future, Point drawLocation, LaneBook laneBook)
        {
            float  distance   = (future.Position.Tick - past.Position.Tick) * ScoreInfo.UnitBeatHeight;
            PointF drawOffset = new PointF(past.Width / 2f - lineWidth / 2f, LongNote.drawOffset.Y);
            //相対位置
            PointF pastRerativeLocation   = new PointF(past.Location.X - drawLocation.X, past.Location.Y - drawLocation.Y);
            PointF futureRerativeLocation = new PointF(future.Location.X - drawLocation.X, future.Location.Y - drawLocation.Y);

            int passingLanes = future.LaneIndex - past.LaneIndex;

            //スライドのノーツとノーツがレーンをまたがないとき
            if (passingLanes == 0)
            {
                PointF topLeft     = futureRerativeLocation.Add(drawOffset);
                PointF topRight    = futureRerativeLocation.Add(-drawOffset.X, drawOffset.Y).AddX(future.Width);
                PointF bottomLeft  = pastRerativeLocation.Add(drawOffset);
                PointF bottomRight = pastRerativeLocation.Add(-drawOffset.X, drawOffset.Y).AddX(past.Width);
                using (GraphicsPath graphicsPath = new GraphicsPath())
                {
                    graphicsPath.AddLines(new PointF[] { topLeft, bottomLeft, bottomRight, topRight });
                    using (SolidBrush myBrush = new SolidBrush(lineColor))
                    {
                        g.FillPath(myBrush, graphicsPath);
                    }
                }
            }
            //スライドのノーツとノーツがレーンをまたぐとき
            else if (passingLanes >= 1)
            {
                float positionDistance = (future.Position.Tick - past.Position.Tick) * ScoreInfo.UnitBeatHeight;
                float diffX            = (future.Position.Lane - past.Position.Lane) * ScoreInfo.UnitLaneWidth;
                #region 最初のレーンでの描画
                //ノーツfutureの位置はノーツpastの位置に2ノーツの距離を引いて表す。またTopRightの水平位置はfutureのWidthを使うことに注意
                PointF topLeft  = pastRerativeLocation.Add(diffX, -positionDistance).Add(drawOffset);
                PointF topRight = pastRerativeLocation.Add(diffX, -positionDistance).Add(-drawOffset.X, drawOffset.Y).AddX(future.Width);
                //以下の2つはレーンをまたがないときと同じ
                PointF bottomLeft  = pastRerativeLocation.Add(drawOffset);
                PointF bottomRight = pastRerativeLocation.Add(-drawOffset.X, drawOffset.Y).AddX(past.Width);
                using (GraphicsPath graphicsPath = new GraphicsPath())
                {
                    graphicsPath.AddLines(new PointF[] { topLeft, bottomLeft, bottomRight, topRight });
                    ScoreLane scoreLane = laneBook.Find(x => x.Contains(past));
                    if (scoreLane != null)
                    {
                        RectangleF clipRect = new RectangleF(
                            scoreLane.LaneRect.X - drawLocation.X,
                            scoreLane.LaneRect.Y - drawLocation.Y,
                            scoreLane.LaneRect.Width,
                            scoreLane.LaneRect.Height);
                        g.Clip = new Region(clipRect);
                    }
                    using (SolidBrush myBrush = new SolidBrush(lineColor))
                    {
                        g.FillPath(myBrush, graphicsPath);
                    }
                }
                #endregion
                #region 以降最後までのレーンでの描画
                {
                    ScoreLane prevLane, curLane;
                    for (prevLane = laneBook.Find(x => x.Contains(past)), curLane = laneBook.Next(prevLane);
                         curLane != null && laneBook.IndexOf(curLane) <= future.LaneIndex;
                         prevLane = curLane, curLane = laneBook.Next(curLane))
                    {
                        topLeft.X      = curLane.LaneRect.X + future.Position.Lane * ScoreInfo.UnitLaneWidth - drawLocation.X + drawOffset.X;
                        topLeft.Y     += prevLane.LaneRect.Height;
                        topRight.X     = topLeft.X + future.Width - 2 * drawOffset.X;
                        topRight.Y    += prevLane.LaneRect.Height;
                        bottomLeft.X   = curLane.LaneRect.X + past.Position.Lane * ScoreInfo.UnitLaneWidth - drawLocation.X + drawOffset.X;
                        bottomLeft.Y  += prevLane.LaneRect.Height;
                        bottomRight.X  = bottomLeft.X + past.Width - 2 * drawOffset.X;
                        bottomRight.Y += prevLane.LaneRect.Height;
                        using (GraphicsPath graphicsPath = new GraphicsPath())
                        {
                            graphicsPath.AddLines(new PointF[] { topLeft, bottomLeft, bottomRight, topRight });
                            RectangleF clipRect = new RectangleF(curLane.LaneRect.Location.Sub(drawLocation), curLane.LaneRect.Size);
                            g.Clip = new Region(clipRect);
                            using (SolidBrush myBrush = new SolidBrush(lineColor))
                            {
                                g.FillPath(myBrush, graphicsPath);
                            }
                        }
                    }
                }

                #endregion
            }
        }
示例#15
0
 public void SetScore(int beatNumer, int beatDenom, int barCount)
 {
     LaneBook.SetScore(ScoreBook, beatNumer, beatDenom, barCount);
 }
示例#16
0
        /// <summary>
        /// ノーツ間を繋ぐ帯の描画(ベジェ)
        /// </summary>
        private static void DrawSlideCurve(Graphics g, Note past, Note curve, Note future, Point drawLocation, LaneBook laneBook, ref RectangleF gradientRect)
        {
            if (gradientRect.Width <= 0)
            {
                gradientRect.Width = 1;
            }
            if (gradientRect.Height <= 0)
            {
                gradientRect.Height = 1;
            }
            //相対位置
            PointF pastRerativeLocation = new PointF(past.Location.X - drawLocation.X, past.Location.Y - drawLocation.Y);

            int passingLanes = future.LaneIndex - past.LaneIndex;

            float positionDistanceFuture = (future.Position.Tick - past.Position.Tick) * ScoreInfo.UnitBeatHeight;
            float positionDistanceCurve  = (curve.Position.Tick - past.Position.Tick) * ScoreInfo.UnitBeatHeight;
            float diffXFuture            = (future.Position.Lane - past.Position.Lane) * ScoreInfo.UnitLaneWidth;
            float diffXCurve             = (curve.Position.Lane - past.Position.Lane) * ScoreInfo.UnitLaneWidth;

            //ノーツfutureの位置はノーツpastの位置に2ノーツの距離を引いて表す。またTopRightの水平位置はfutureのWidthを使うことに注意
            PointF topLeft  = pastRerativeLocation.Add(diffXFuture, -positionDistanceFuture).Add(drawOffset);
            PointF topRight = pastRerativeLocation.Add(diffXFuture, -positionDistanceFuture).Add(-drawOffset.X, drawOffset.Y).AddX(future.Width);
            //以下の2つはレーンをまたがないときと同じ
            PointF bottomLeft  = pastRerativeLocation.Add(drawOffset).AddY(deltaHeight);
            PointF bottomRight = pastRerativeLocation.Add(-drawOffset.X, drawOffset.Y).AddX(past.Width).AddY(deltaHeight);
            //3つのそれぞれのノーツの中心の座標
            PointF topCenter    = topLeft.AddX(future.Width / 2f - drawOffset.X);
            PointF bottomCenter = bottomLeft.AddX(past.Width / 2f - drawOffset.X);
            PointF curveCenter  = pastRerativeLocation.Add(diffXCurve, -positionDistanceCurve).AddX(curve.Width / 2f);
            //
            //下からアンカーまでの比率
            float ratio = (curveCenter.Y - bottomCenter.Y) / (topCenter.Y - bottomCenter.Y);
            //カーブノーツのY座標で水平にスライドを切ったときのスライド幅
            float widthAnchor = (topRight.X - topLeft.X) * ratio + (bottomRight.X - bottomLeft.X) * (1 - ratio);

            using (GraphicsPath graphicsPath = new GraphicsPath())
            {
                graphicsPath.AddBezier(bottomLeft, curveCenter.AddX(-widthAnchor / 2f), topLeft);
                graphicsPath.AddLine(topLeft, topRight);
                graphicsPath.AddBezier(topRight, curveCenter.AddX(widthAnchor / 2f), bottomRight);
                graphicsPath.AddLine(bottomLeft, bottomRight);
                ScoreLane  scoreLane = laneBook.Find(x => x.Contains(past));
                RectangleF clipRect;
                for (int i = 0; i <= passingLanes && scoreLane != null; ++i)
                {
                    if (Status.DrawTickFirst < scoreLane.EndTick && scoreLane.StartTick < Status.DrawTickLast)
                    {
                        clipRect = new RectangleF(
                            scoreLane.LaneRect.X - drawLocation.X,
                            scoreLane.LaneRect.Y - drawLocation.Y,
                            scoreLane.LaneRect.Width,
                            scoreLane.LaneRect.Height);
                        g.Clip = new Region(clipRect);
                        using (LinearGradientBrush myBrush = new LinearGradientBrush(gradientRect, baseColor, baseColor, LinearGradientMode.Vertical))
                        {
                            myBrush.InterpolationColors = colorBlend;
                            g.FillPath(myBrush, graphicsPath);
                        }
                        using (Pen myPen = new Pen(lineColor, 2))
                        {
                            g.DrawBezier(myPen, bottomCenter, curveCenter, topCenter);
                        }
                    }
                    // インクリメント
                    bottomCenter = bottomCenter.Add(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, scoreLane.HitRect.Height);
                    curveCenter  = curveCenter.Add(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, scoreLane.HitRect.Height);
                    topCenter    = topCenter.Add(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, scoreLane.HitRect.Height);
                    if (i != passingLanes)
                    {
                        graphicsPath.Translate(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, scoreLane.HitRect.Height);
                        gradientRect.Y += scoreLane.HitRect.Height;
                        scoreLane       = laneBook.Next(scoreLane);
                    }
                }
            }
        }
示例#17
0
        /// <summary>
        /// ノーツ間を繋ぐ帯の描画(直線)
        /// </summary>
        private static void DrawSlideLine(Graphics g, Note past, Note future, Point drawLocation, LaneBook laneBook, ref RectangleF gradientRect)
        {
            if (gradientRect.Width <= 0)
            {
                gradientRect.Width = 1;
            }
            if (gradientRect.Height <= 0)
            {
                gradientRect.Height = 1;
            }
            //相対位置
            PointF pastRerativeLocation = new PointF(past.Location.X - drawLocation.X, past.Location.Y - drawLocation.Y);
            int    passingLanes         = future.LaneIndex - past.LaneIndex;
            float  positionDistance     = (future.Position.Tick - past.Position.Tick) * ScoreInfo.UnitBeatHeight;
            float  diffX = (future.Position.Lane - past.Position.Lane) * ScoreInfo.UnitLaneWidth;

            //ノーツfutureの位置はノーツpastの位置に2ノーツの距離を引いて表す。またTopRightの水平位置はfutureのWidthを使うことに注意
            PointF topLeft  = pastRerativeLocation.Add(diffX, -positionDistance).Add(drawOffset);
            PointF topRight = pastRerativeLocation.Add(diffX, -positionDistance).Add(-drawOffset.X, drawOffset.Y).AddX(future.Width);
            //以下の2つはレーンをまたがないときと同じ
            PointF bottomLeft  = pastRerativeLocation.Add(drawOffset).AddY(deltaHeight);
            PointF bottomRight = pastRerativeLocation.Add(-drawOffset.X, drawOffset.Y).AddX(past.Width).AddY(deltaHeight);

            using (GraphicsPath graphicsPath = new GraphicsPath())
            {
                graphicsPath.AddPolygon(new PointF[] { topLeft, bottomLeft, bottomRight, topRight });
                ScoreLane  scoreLane = laneBook.Find(x => x.Contains(past));
                RectangleF clipRect;
                for (int i = 0; i <= passingLanes && scoreLane != null; ++i)
                {
                    if (Status.DrawTickFirst < scoreLane.EndTick && scoreLane.StartTick < Status.DrawTickLast)
                    {
                        clipRect = new RectangleF(
                            scoreLane.LaneRect.X - drawLocation.X,
                            scoreLane.LaneRect.Y - drawLocation.Y,
                            scoreLane.LaneRect.Width,
                            scoreLane.LaneRect.Height);
                        g.Clip = new Region(clipRect);
                        using (LinearGradientBrush myBrush = new LinearGradientBrush(gradientRect, baseColor, baseColor, LinearGradientMode.Vertical))
                        {
                            myBrush.InterpolationColors = colorBlend;
                            g.FillPath(myBrush, graphicsPath);
                        }
                        using (Pen myPen = new Pen(lineColor, 2))
                        {
                            g.DrawLine(
                                myPen,
                                (graphicsPath.PathPoints[1].X + graphicsPath.PathPoints[2].X) / 2,
                                graphicsPath.PathPoints[1].Y,
                                (graphicsPath.PathPoints[0].X + graphicsPath.PathPoints[3].X) / 2,
                                graphicsPath.PathPoints[0].Y);
                        }
                    }
                    // インクリメント
                    if (i != passingLanes)
                    {
                        graphicsPath.Translate(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, scoreLane.HitRect.Height);
                        gradientRect.Y += scoreLane.HitRect.Height;
                        scoreLane       = laneBook.Next(scoreLane);
                    }
                }
            }
        }
示例#18
0
        /// <summary>
        /// このスライドを描画します。
        /// </summary>
        /// ノーツのリストに対して前から回して、そのノーツとそれと次のノーツまでの帯を描画し、そのノーツを描画
        public override void Draw(Graphics g, Point drawLocation, LaneBook laneBook)
        {
            if (g == null)
            {
                return;
            }
            base.Draw(g, drawLocation, laneBook);
            var        list = this.OrderBy(x => x.Position.Tick).ToList();
            RectangleF gradientRect = new RectangleF();
            var        stepList = list.Where(x => x is SlideBegin || x is SlideTap || x is SlideEnd).ToList();
            Note       gradientNote, gradientNext, next, curve;

            foreach (Note note in list)
            {
                // 画面外の場合は描画しないようにしてなるべく処理を軽くしたい
                if (note.Position.Tick > Status.DrawTickLast)
                {
                    continue;
                }
                if (list.IndexOf(note) < list.Count - 1 && !(note is SlideCurve))
                {
                    //スライド帯のグラデーション用矩形を設定する
                    if (note is SlideBegin || note is SlideTap || note is SlideEnd)
                    {
                        gradientNote = note;
                        gradientNext = stepList.Next(note);
                        if (gradientNext != null)
                        {
                            float distance = (gradientNext.Position.Tick - gradientNote.Position.Tick) * ScoreInfo.UnitBeatHeight;
                            //x座標と幅は適当な値を入れたけどちゃんとうごいてるっぽい?重要なのはy座標と高さ
                            gradientRect = new RectangleF(0, gradientNote.Location.Y - distance + drawOffset.Y - drawLocation.Y, 10, distance);
                        }
                    }
                    //スライド帯を描画する
                    next = list.Next(note);
                    if (!(next is SlideCurve))
                    {
                        // 画面外の場合は描画しないようにしてなるべく処理を軽くしたい
                        if (next.Position.Tick < Status.DrawTickFirst)
                        {
                            continue;
                        }
                        DrawSlideLine(g, note, next, drawLocation, laneBook, ref gradientRect);
                    }
                    else
                    {
                        curve = next;
                        //SlideRelayは末尾に来ることはないし,SlideRelayが2つ以上連続に並ぶことはないという確信の元実装
                        //↑実際ノーツの束縛処理でそうなるような実装をしている(した)
                        if (list.IndexOf(curve) < list.Count - 1)
                        {
                            next = list.Next(curve);
                            // 画面外の場合は描画しないようにしてなるべく処理を軽くしたい
                            if (next.Position.Tick < Status.DrawTickFirst)
                            {
                                continue;
                            }
                            DrawSlideCurve(g, note, curve, next, drawLocation, laneBook, ref gradientRect);
                        }
                    }
                }
                //クリッピングの解除を忘れないこと
                g.ResetClip();
                //非表示設定のノーツは描画しないようにする
                if (note is SlideRelay && !Status.IsSlideRelayVisible)
                {
                    continue;
                }
                if (note is SlideCurve && !Status.IsSlideCurveVisible)
                {
                    continue;
                }
                note.Draw(g, drawLocation);
            }
        }
示例#19
0
        /// <summary>
        /// 与えられた座標がスライド帯の上に乗っているか判定します
        /// </summary>
        public bool Contains(PointF locationVirtual, LaneBook laneBook)
        {
            var list = this.OrderBy(x => x.Position.Tick).ToList();

            foreach (Note note in list)
            {
                if (list.IndexOf(note) >= list.Count - 1)
                {
                    break;
                }
                Note next = list.ElementAt(list.IndexOf(note) + 1);
                if (note is SlideCurve)
                {
                    continue;
                }
                else if (next is SlideCurve)
                {
                    var ret = ContainsInCurve(note, next, list.ElementAt(list.IndexOf(next) + 1), laneBook, locationVirtual);
                    if (ret)
                    {
                        return(true);
                    }
                }
                //
                int passingLanes = next.LaneIndex - note.LaneIndex;
                if (passingLanes == 0)
                {
                    PointF topLeft     = next.Location.Add(drawOffset);
                    PointF topRight    = next.Location.Add(-drawOffset.X, drawOffset.Y).AddX(next.Width);
                    PointF bottomLeft  = note.Location.Add(drawOffset);
                    PointF bottomRight = note.Location.Add(-drawOffset.X, drawOffset.Y).AddX(note.Width);
                    using (GraphicsPath hitPath = new GraphicsPath())
                    {
                        hitPath.AddLines(new PointF[] { topLeft, bottomLeft, bottomRight, topRight });
                        if (hitPath.IsVisible(locationVirtual))
                        {
                            return(true);
                        }
                    }
                }
                else if (passingLanes >= 1)
                {
                    float positionDistance = (next.Position.Tick - note.Position.Tick) * ScoreInfo.UnitBeatHeight;
                    float diffX            = (next.Position.Lane - note.Position.Lane) * ScoreInfo.UnitLaneWidth;
                    #region 最初のレーンでの判定処理
                    PointF topLeft     = note.Location.Add(drawOffset).Add(diffX, -positionDistance);
                    PointF topRight    = note.Location.Add(-drawOffset.X, drawOffset.Y).AddX(next.Width).Add(diffX, -positionDistance);
                    PointF bottomLeft  = note.Location.Add(drawOffset);
                    PointF bottomRight = note.Location.Add(-drawOffset.X, drawOffset.Y).AddX(note.Width);
                    using (GraphicsPath hitPath = new GraphicsPath())
                    {
                        hitPath.AddLines(new PointF[] { topLeft, bottomLeft, bottomRight, topRight });
                        if (hitPath.IsVisible(locationVirtual))
                        {
                            return(true);
                        }
                    }
                    #endregion
                    #region 以降最後までの判定処理
                    ScoreLane prevLane, curLane;
                    for (prevLane = laneBook.Find(x => x.Contains(note)), curLane = laneBook.Next(prevLane);
                         curLane != null && laneBook.IndexOf(curLane) <= next.LaneIndex;
                         prevLane = curLane, curLane = laneBook.Next(curLane))
                    {
                        topLeft.X      = curLane.LaneRect.X + next.Position.Lane * ScoreInfo.UnitLaneWidth + drawOffset.X;
                        topLeft.Y     += prevLane.LaneRect.Height;
                        topRight.X     = topLeft.X + next.Width - 2 * drawOffset.X;
                        topRight.Y    += prevLane.LaneRect.Height;
                        bottomLeft.X   = curLane.LaneRect.X + note.Position.Lane * ScoreInfo.UnitLaneWidth + drawOffset.X;
                        bottomLeft.Y  += prevLane.LaneRect.Height;
                        bottomRight.X  = bottomLeft.X + note.Width - 2 * drawOffset.X;
                        bottomRight.Y += prevLane.LaneRect.Height;
                        using (GraphicsPath hitPath = new GraphicsPath())
                        {
                            hitPath.AddLines(new PointF[] { topLeft, bottomLeft, bottomRight, topRight });
                            if (hitPath.IsVisible(locationVirtual))
                            {
                                return(true);
                            }
                        }
                    }
                    #endregion
                }
            }
            return(false);
        }
示例#20
0
        private static void DrawHoldLine(Graphics g, Note past, Note future, Point drawLocation, LaneBook laneBook)
        {
            float distance = (future.Position.Tick - past.Position.Tick) * ScoreInfo.UnitBeatHeight;
            //グラデーション矩形
            //x座標と幅は適当だけど動いてるはず。重要なのはy座標と高さ
            RectangleF gradientRect = new RectangleF(0, past.Location.Y - distance + drawOffset.Y - drawLocation.Y, 10, distance <= 0 ? 1 : distance);
            //相対位置
            PointF pastRerativeLocation = new PointF(past.Location.X - drawLocation.X, past.Location.Y - drawLocation.Y);
            int    passingLanes         = future.LaneIndex - past.LaneIndex;
            float  positionDistance     = (future.Position.Tick - past.Position.Tick) * ScoreInfo.UnitBeatHeight;
            float  diffX = (future.Position.Lane - past.Position.Lane) * ScoreInfo.UnitLaneWidth;
            //ノーツfutureの位置はノーツpastの位置に2ノーツの距離を引いて表す。またTopRightの水平位置はfutureのWidthを使うことに注意
            PointF topLeft  = pastRerativeLocation.Add(diffX, -positionDistance).Add(drawOffset);
            PointF topRight = pastRerativeLocation.Add(diffX, -positionDistance).Add(-drawOffset.X, drawOffset.Y).AddX(future.Width);
            //以下の2つはレーンをまたがないときと同じ
            PointF bottomLeft  = pastRerativeLocation.Add(drawOffset);
            PointF bottomRight = pastRerativeLocation.Add(-drawOffset.X, drawOffset.Y).AddX(past.Width);

            using (GraphicsPath graphicsPath = new GraphicsPath())
            {
                graphicsPath.AddLines(new PointF[] { topLeft, bottomLeft, bottomRight, topRight });
                ScoreLane scoreLane = laneBook.Find(x => x.Contains(past));
                for (int i = 0; i <= passingLanes && scoreLane != null; ++i)
                {
                    if (Status.DrawTickFirst < scoreLane.EndTick && scoreLane.StartTick < Status.DrawTickLast)
                    {
                        RectangleF clipRect = new RectangleF(
                            scoreLane.LaneRect.X - drawLocation.X,
                            scoreLane.LaneRect.Y - drawLocation.Y,
                            scoreLane.LaneRect.Width,
                            scoreLane.LaneRect.Height);
                        g.Clip = new Region(clipRect);
                        using (LinearGradientBrush myBrush = new LinearGradientBrush(gradientRect, baseColor, baseColor, LinearGradientMode.Vertical))
                        {
                            myBrush.InterpolationColors = colorBlend;
                            g.FillPath(myBrush, graphicsPath);
                        }
                    }
                    // インクリメント
                    if (i != passingLanes)
                    {
                        graphicsPath.Translate(ScoreLane.Width + ScorePanel.Margin.Left + ScorePanel.Margin.Right, scoreLane.HitRect.Height);
                        gradientRect.Y += scoreLane.HitRect.Height;
                        scoreLane       = laneBook.Next(scoreLane);
                    }
                }
            }
        }
示例#21
0
 public void InsertScoreForward(Score score, int beatNumer, int beatDenom, int barCount)
 {
     LaneBook.InsetScoreForward(ScoreBook, score, beatNumer, beatDenom, barCount);
 }
示例#22
0
 public void DeleteScore(Score score, int count)
 {
     LaneBook.DeleteScore(ScoreBook, score, count);
 }
示例#23
0
 public void DivideLane(Score score)
 {
     LaneBook.DivideLane(score);
 }
示例#24
0
 public void InsertScoreBackwardWithNote(Score score, int beatNumer, int beatDenom, int barCount)
 {
     LaneBook.InsertScoreBackwardWithNote(NoteBook, ScoreBook, score, beatNumer, beatDenom, barCount);
 }
示例#25
0
 public void FillLane(ScoreLane begin)
 {
     LaneBook.FillLane(begin);
 }
示例#26
0
 public virtual void RelocateOnlyAndUpdate(Position position, LaneBook laneBook)
 {
     RelocateOnly(position);
     UpdateLocation(laneBook);
 }