예제 #1
0
        /// <summary> Constructor. </summary>
        /// <param name="position"> The position of the given chunk. </param>
        public Chunk(ChunkCoordinate position)
        {
            Position = position;
            _items   = new GridItem[NumberOfGridItemsWide * NumberOfGridItemsHigh];

            // TODO do this elsewhere

            for (int y = 0; y < NumberOfGridItemsHigh; y++)
            {
                for (int x = 0; x < NumberOfGridItemsWide; x++)
                {
                    var gridPosition = new GridCoordinate(position, new InnerChunkGridCoordinate(x, y));
                    var gridItem     = GetGridItemAt(gridPosition);

                    this[gridPosition.InnerChunkGridCoordinate] = gridItem;
                }
            }
        }
예제 #2
0
        /// <summary>
        ///  Checks the array index/position to verify that it has the correct position information and if
        ///  it does not, re-reads the data from the world and updates the data.
        /// </summary>
        /// <param name="index"> The index position to update. </param>
        /// <param name="coordinate"> The coordinate representing the position to update. </param>
        private void Invalidate(Array2DIndex index, GridCoordinate coordinate)
        {
            var existingData = _visibleGridItems[index];

            if (existingData.Position == coordinate)
            {
                return;
            }
            var chunkCoordinate = coordinate.ChunkCoordinate;

            if (!_worldGrid.IsValid(chunkCoordinate))
            {
                return;
            }

            var chunk = _worldGrid[chunkCoordinate];
            var data  = chunk[coordinate.InnerChunkGridCoordinate];

            UpdateData(index, data, coordinate, chunk);
        }
예제 #3
0
        private void ValidateConversion(GridCoordinate gridPosition, Array2DIndex arrayIndex)
        {
            var worked = ConvertToGridItemIndex(gridPosition).X == arrayIndex.X &&
                         ConvertToGridItemIndex(gridPosition).Y == arrayIndex.Y;

            if (worked)
            {
                return;
            }

            // to aid in debugging
            worked = ConvertToGridItemIndex(gridPosition).X == arrayIndex.X &&
                     ConvertToGridItemIndex(gridPosition).Y == arrayIndex.Y;

            var message = new StringBuilder();

            message.AppendFormat("Array Index ({0}) was converted into Grid Position ({1})", arrayIndex, gridPosition);
            message.AppendFormat("But we expected ({0},{1})",
                                 ConvertToGridItemIndex(gridPosition).X,
                                 ConvertToGridItemIndex(gridPosition).Y);

            Debug.Log(message);
        }
 public bool Equals(GridCoordinate other)
 {
     return(X == other.X && Y == other.Y);
 }
예제 #5
0
 /// <summary>
 ///  Checks the array index/position to verify that it has the correct position information and if
 ///  it does not, re-reads the data from the world and updates the data.
 /// </summary>
 /// <param name="coordinate"> The coordinate representing the position to update. </param>
 private void InvalidatePosition(GridCoordinate coordinate)
 {
     Validate(coordinate);
     Invalidate(ConvertToGridItemIndex(coordinate), coordinate);
 }
예제 #6
0
        /// <summary> Updates the cells that have changed because the target has changed. </summary>
        /// <param name="previousCoordinate"> The last position we were at. </param>
        private void UpdateChangedUnits(GridCoordinate previousCoordinate)
        {
            var xDiff = _currentPosition.X - previousCoordinate.X;
            var yDiff = _currentPosition.Y - previousCoordinate.Y;

            if (xDiff == 0 && yDiff == 0)
            {
                return;
            }

            if (Math.Abs(xDiff) >= _visibleGridItems.Width ||
                Math.Abs(yDiff) >= _visibleGridItems.Height
                )
            {
                // if we ever move more units than we have, then just invalidate the whole thing.
                UpdateAllUnits();
                return;
            }

            // if we're at (x,y) from (x-1, y-1), then (x+halfWidth, y+halfHeight) just came into view (of
            // course if we just came from (x+1, y+1), then (x-halfWidth, y-halfWidth) just came into view.

            // This used to be `amountToOffsetX = MathUtils.Signed(xDiff, _numUnitsWideHalfThreshold)` but
            // then when we moved right it would update the top-right corner one higher than when we moved
            // up. I'm not sure why we need to invalidate one higher when moving in the positive direction
            // but it seems to work.
            //
            // My current theory as to why is that it has something to do with one of the conversion
            // algorithms preferring the positive direction over the negative.
            var amountToOffsetX = xDiff > 0 ? _numUnitsWideHalfThreshold + 1 : -_numUnitsWideHalfThreshold;
            var amountToOffsetY = yDiff > 0 ? _numUnitsHighHalfThreshold + 1 : -_numUnitsHighHalfThreshold;

            var start = previousCoordinate.Offset(amountToOffsetX, amountToOffsetY);
            var end   = _currentPosition.Offset(amountToOffsetX, amountToOffsetY);

            var startColumn = start.X;
            var endColumn   = end.X;

            // make sure our for loop will work :: )
            if (startColumn > endColumn)
            {
                MathUtils.Swap(ref startColumn, ref endColumn);
            }

            var startRow = start.Y;
            var endRow   = end.Y;

            if (startRow > endRow)
            {
                MathUtils.Swap(ref startRow, ref endRow);
            }

            // OPTIMIZATION 1 - Instead of using PositiveRemainder, we could just have loop through twice
            // (when needed) because we know that we can only have to dis-jointed sets of rows[/columns]
            //
            // OPTIMIZATION 2 - We're currently always hitting the area where the rows/columns overlap
            // twice.  We could optimize this out (especially if/when we do #1 above).

            // update the rows that need to be updated
            for (var y = startRow; y < endRow; y++)
            {
                for (var x = _currentPosition.X - _numUnitsWideHalfThreshold;
                     x <= _currentPosition.X + _numUnitsWideHalfThreshold;
                     x++)
                {
                    InvalidatePosition(new GridCoordinate(x, y));
                }
            }

            // update that columns that need to be updated
            for (var y = _currentPosition.Y - _numUnitsHighHalfThreshold;
                 y <= _currentPosition.Y + _numUnitsHighHalfThreshold;
                 y++)
            {
                for (var x = startColumn; x < endColumn; x++)
                {
                    InvalidatePosition(new GridCoordinate(x, y));
                }
            }
        }