Пример #1
0
        /// <summary>
        /// いまのところSlideカーブでの当たり判定用パスを作るためのみに使う
        /// 汎用性を高めればDrawSlideCurveメソッドとかをスッキリできそう
        /// </summary>
        /// <param name="past"></param>
        /// <param name="curve"></param>
        /// <param name="future"></param>
        /// <param name="drawOffset"></param>
        /// <returns></returns>
        public static GraphicsPath CreateSlideCurvePath(Note past, Note curve, Note future, PointF drawOffset)
        {
            GraphicsPath graphicsPath           = new GraphicsPath();
            PointF       pastRerativeLocation   = new PointF(past.Location.X, past.Location.Y);
            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);
            PointF bottomRight = pastRerativeLocation.Add(-drawOffset.X, drawOffset.Y).AddX(past.Width);
            //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);

            //
            graphicsPath.AddBezier(bottomLeft, curveCenter.AddX(-widthAnchor / 2f), topLeft);
            graphicsPath.AddLine(topLeft, topRight);
            graphicsPath.AddBezier(topRight, curveCenter.AddX(widthAnchor / 2f), bottomRight);
            graphicsPath.AddLine(bottomLeft, bottomRight);
            return(graphicsPath);
        }
Пример #2
0
        /// <summary>
        /// 真上向きAirのGraphicsPathを返します
        /// </summary>
        /// <returns></returns>
        protected virtual GraphicsPath GetAirPath(Point drawLocation)
        {
            GraphicsPath graphicsPath = new GraphicsPath();
            PointF       baseLocation = Location.Add(-drawLocation.X, -drawLocation.Y);
            PointF       topCenter    = baseLocation.AddX(Width / 2f).AddY(borderWidth).Add(drawOffset);
            PointF       topRight     = topCenter.AddX(Width / 2f - (Size - 1) * widthRatio).AddY(airHeight - airLineHeight - borderWidth);
            PointF       topLeft      = topCenter.AddX(-(Width / 2f - (Size - 1) * widthRatio)).AddY(airHeight - airLineHeight - borderWidth);
            PointF       bottomCenter = topCenter.AddY(airLineHeight - borderWidth);
            PointF       bottomRight  = topRight.AddY(airLineHeight - borderWidth);
            PointF       bottomLeft   = topLeft.AddY(airLineHeight - borderWidth);

            graphicsPath.AddLines(new PointF[] { topCenter, topRight, bottomRight, bottomCenter, bottomLeft, topLeft });
            graphicsPath.CloseFigure();
            return(graphicsPath);
        }
Пример #3
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);
                    }
                }
            }
        }