Exemplo n.º 1
0
        void ComputeAndMergeAnOctant(Octant octant)
        {
            /*
             *  计算并合并第一行(因为要考虑到观察者的影响但又不能过度消耗计算量)
             *
             *  向前走直到地图边界
             *      if(阴影没有完全覆盖八分角)
             *          计算并合并每一行
             *      else
             *          填充整行的阴影
             */
            bool       isFullShadow = false;
            ShadowLine shadowLine   = new ShadowLine();

            ComputeAndMergeStartLine(octant, shadowLine);                                             // 因为观察者自身对视线的遮挡会导致各种问题,所以单独拿出一行来处理

            for (int mainStep = 1; _visibleMap.Contains(octant.GetPosition(mainStep, 0)); mainStep++) // 第一行单独处理了,这里从距离1开始
            {
                if (!isFullShadow)
                {
                    isFullShadow = ComputeAndMergeALineAndGetIsFullShadow(octant, mainStep, shadowLine);
                }
                else
                {
                    FillALineShadow(octant, mainStep);
                }
            }
        }
Exemplo n.º 2
0
        bool ComputeAndMergeALineAndGetIsFullShadow(Octant octant, int mainStep, ShadowLine shadowLine)
        {
            /*
             *  循环到一行结束或地图边界
             *  {
             *      获取投影
             *      通过投影判断可见度并存入视野
             *      通过投影判断是否遮挡视线并存入阴影线
             *  }
             *  返回阴影是否覆盖了整个八分角
             */
            Vector2 currentPosition;

            for (int sideStep = 0; sideStep <= mainStep + LINE_PATCH && _visibleMap.Contains(currentPosition = octant.GetPosition(mainStep, sideStep)); sideStep++)
            {
                Shadow projection = ShadowLine.GetQuadProjection(mainStep, sideStep);
                DrawShadow(shadowLine, currentPosition, projection);
                UpdateShadowLine(currentPosition, shadowLine, projection);
            }

            return(shadowLine.IsFullShadow());
        }
Exemplo n.º 3
0
        void ComputeAndMergeStartLine(Octant octant, ShadowLine shadowLine)
        {
            int     mainStep = 0;
            Vector2 currentPosition;

            for (int sideStep = 1; sideStep <= LINE_PATCH && _visibleMap.Contains(currentPosition = octant.GetPosition(mainStep, sideStep)); sideStep++) // 边缘方向从1开始,跳过观察者所在的位置
            {
                Shadow projection = ShadowLine.GetQuadProjection(mainStep, sideStep);
                DrawShadow(shadowLine, currentPosition, projection);
                UpdateShadowLine(currentPosition, shadowLine, projection);
            }
        }
Exemplo n.º 4
0
        void FillALineShadow(Octant octant, int mainStep)
        {
            /*
             *  循环到一行结束或地图边界
             *      填充阴影
             */
            Vector2 currentPosition;

            for (int sideStep = 0; sideStep <= mainStep && _visibleMap.Contains(currentPosition = octant.GetPosition(mainStep, sideStep)); sideStep++)
            {
                _viewField.SetVisible(currentPosition, false);
            }

            /*
             *  前面for判断里有一句 _visibleMap.Contains(currentPosition = octant.GetPosition(mainStep, sideStep))
             *  这一句是利用括号控制代码顺序,以括号为分隔,看成两个部分:
             *  第一部分,括号内的运算 currentPosition = octant.GetPosition(mainStep, sideStep) 运算后 currentPosition 就变为了这次循环的位置
             *  第二部分:括号外的运算,在经过第一部分后实际上变成了这样: _visibleMap.Contains(currentPosition)
             *  两步合到一起就完成了更新 currentPosition 并判断是否越界的效果
             */
        }