/// <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); }
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 } }