コード例 #1
0
        /// <summary>
        /// Scans for and applies reductions if specified anchor tile contains a collider.
        /// </summary>
        /// <remarks>
        /// <para>This method searches from left-to-right from specified anchor tile to
        /// find furthest tile horizontally that it can be reduced with. Once the initial
        /// horizontal sequence is known this method proceeds to scan vertically for other
        /// sequences of colliders that can further reduce the initial horizontal sequence.</para>
        /// </remarks>
        /// <param name="anchor">Index of anchor tile.</param>
        /// <returns></returns>
        private int Scan(TileIndex anchor)
        {
            ColliderInfo anchorInfo = null;

            this.GetColliderInfo(ref anchorInfo, anchor);
            if (anchorInfo == null)
            {
                return(anchor.column);
            }

            ColliderInfo info = null, firstInfo = null, lastInfo = null;

            // Begin tracking list of collider components which will be combined.
            this.ResetReducedColliderTracking();
            this.TrackReducedCollider(anchorInfo.Row, anchorInfo.Column, anchorInfo.Collider);

            try {
                TileIndex target        = anchor;
                BoxBounds reducedBounds = anchorInfo.Bounds;

                // Scan rightwards for colliders which can be combined with anchor.
                for (int column = anchor.column + 1; column < this.system.ColumnCount; ++column)
                {
                    if (this.markedTiles[anchor.row, column])
                    {
                        break;
                    }

                    this.GetColliderInfo(ref info, anchor.row, column);
                    if (!this.CanReduce(info, anchorInfo))
                    {
                        break;
                    }

                    // Can candidate collider be combined with anchor?
                    if (!reducedBounds.Encapsulate(info.Bounds))
                    {
                        break;
                    }

                    target.column = column;

                    this.TrackReducedCollider(info.Row, info.Column, info.Collider);
                }

                this.GetColliderInfo(ref info, target);
                var prevFirstBounds = anchorInfo.Bounds;
                var prevLastBounds  = info.Bounds;

                // Extend downwards if possible, though avoid crossing T-junctions since splitting
                // a T-junction will often cause more colliders to occur in result.
                for (int row = anchor.row + 1; row < this.system.RowCount; ++row)
                {
                    this.GetColliderInfo(ref firstInfo, row, anchor.column);
                    this.GetColliderInfo(ref lastInfo, row, target.column);
                    if (firstInfo == null || lastInfo == null || !this.CanReduce(firstInfo, anchorInfo) || this.CheckForTJunction(firstInfo, lastInfo))
                    {
                        goto FinishedExtendingDownards;
                    }

                    // Does first and last tile from previous row extend downwards?
                    if (!prevFirstBounds.Encapsulate(firstInfo.Bounds) || !prevLastBounds.Encapsulate(lastInfo.Bounds))
                    {
                        goto FinishedExtendingDownards;
                    }

                    // No need to track collider from `lastInfo` since it will be included
                    // within the following loop.
                    this.candidateColliders.Clear();
                    this.candidateColliders.Add(firstInfo.Collider);

                    // Reduce bounds for strip.
                    BoxBounds stripBounds = firstInfo.Bounds;
                    for (int column = anchor.column + 1; column <= target.column; ++column)
                    {
                        this.GetColliderInfo(ref info, row, column);
                        if (!this.CanReduce(info, anchorInfo) || !stripBounds.Encapsulate(info.Bounds))
                        {
                            goto FinishedExtendingDownards;
                        }
                        this.candidateColliders.Add(info.Collider);
                    }

                    // The following should not fail, but let's just be safe!
                    if (!reducedBounds.Encapsulate(stripBounds))
                    {
                        Debug.LogWarning("Unable to encapsulate collider on reduce.");
                        goto FinishedExtendingDownards;
                    }

                    target.row = row;

                    // Accept and track candidate colliders!
                    for (int i = 0; i < this.candidateColliders.Count; ++i)
                    {
                        this.TrackReducedCollider(row, anchor.column + i, this.candidateColliders[i]);
                    }

                    prevFirstBounds = firstInfo.Bounds;
                    prevLastBounds  = lastInfo.Bounds;
                }

FinishedExtendingDownards:
                ;

                bool hasManyColliders           = (this.reducedColliderCount > 1);
                bool hasOneHypotheticalCollider = (this.reducedColliderCount == 1 && this.reducedColliderComponents.Count == 0);
                if (hasManyColliders || hasOneHypotheticalCollider)
                {
                    this.Reduce(anchorInfo, reducedBounds);
                }

                return(target.column);
            }
            finally {
                ColliderInfo.Despawn(anchorInfo);
                ColliderInfo.Despawn(info);
                ColliderInfo.Despawn(firstInfo);
                ColliderInfo.Despawn(lastInfo);
            }
        }
コード例 #2
0
 /// <inheritdoc cref="this.GetColliderInfo(ref ColliderInfo, int, int)"/>
 /// <param name="index">Index of tile.</param>
 private void GetColliderInfo(ref ColliderInfo info, TileIndex index)
 {
     this.GetColliderInfo(ref info, index.row, index.column);
 }