示例#1
0
        /// <summary>
        /// Generates sidewalk border inside the target rectangle.
        /// </summary>
        /// <param name="target">Target side rectangle</param>
        /// <param name="sidewalkTexture">Used texture</param>
        /// <returns>Rest of the target rectangle what's empty</returns>
        private Rectangle GenerateSidewalks(Rectangle target, Texture2D sidewalkTexture)
        {
            for (int x = 0; x < target.Width; x++)
            {
                foreach (int y in new int[] { 0, target.Height - 1 })
                {
                    int X = target.X + x;
                    int Y = target.Y + y;
                    mapBitmap[X * bitmapSize.Height + Y] = MapFillType.Sidewalk;
                    FlatObject sidewalk = new FlatObject(new PositionInTown(this, new Vector2(X * SquareWidth, Y * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), sidewalkTexture);
                    groundObjects.AddLast(sidewalk);
                }
            }
            for (int y = 1; y < (target.Height - 1); y++)
            {
                foreach (int x in new int[] { 0, target.Width - 1 })
                {
                    int X = target.X + x;
                    int Y = target.Y + y;
                    mapBitmap[X * bitmapSize.Height + Y] = MapFillType.Sidewalk;
                    FlatObject sidewalk = new FlatObject(new PositionInTown(this, new Vector2(X * SquareWidth, Y * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), sidewalkTexture);
                    groundObjects.AddLast(sidewalk);
                }
            }

            return new Rectangle(target.X + 1, target.Y + 1, target.Width - 2, target.Height - 2);
        }
示例#2
0
        /// <summary>
        /// Generates sidewalks what surround quarter border road and weren't generated by interfaces.
        /// </summary>
        /// <param name="emptyRanges">Ranges for sidewalks placement</param>
        /// <param name="sidewalkModel">Used sidewalk texture</param>
        private void GenerateRestOfBorderSidewalks(Dictionary<TownQuarterInterfacePosition, List<Range>> emptyRanges, Texture2D sidewalkTexture)
        {
            // Corners
            foreach (Tuple<int, int> p in new Tuple<int, int>[]
            {
                new Tuple<int, int>(BlockWidth - 1, BlockWidth),
                new Tuple<int, int>(BlockWidth - 1, BlockWidth - 1),
                new Tuple<int, int>(BlockWidth, BlockWidth - 1),

                new Tuple<int, int>(bitmapSize.Width - BlockWidth - 1, BlockWidth - 1),
                new Tuple<int, int>(bitmapSize.Width - BlockWidth, BlockWidth - 1),
                new Tuple<int, int>(bitmapSize.Width - BlockWidth, BlockWidth),

                new Tuple<int, int>(bitmapSize.Width - BlockWidth, bitmapSize.Height - BlockWidth - 1),
                new Tuple<int, int>(bitmapSize.Width - BlockWidth, bitmapSize.Height - BlockWidth),
                new Tuple<int, int>(bitmapSize.Width - BlockWidth - 1, bitmapSize.Height - BlockWidth),

                new Tuple<int, int>(BlockWidth, bitmapSize.Height - BlockWidth),
                new Tuple<int, int>(BlockWidth-1, bitmapSize.Height - BlockWidth),
                new Tuple<int, int>(BlockWidth-1, bitmapSize.Height - BlockWidth - 1)
            })
            {
                int x = p.Item1, y = p.Item2;
                mapBitmap[x * bitmapSize.Height + y] = MapFillType.Sidewalk;
                FlatObject sidewalk = new FlatObject(new PositionInTown(this, new Vector2(x * SquareWidth, y * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), sidewalkTexture);
                groundObjects.AddLast(sidewalk);
            }

            // Ranges
            foreach (KeyValuePair<TownQuarterInterfacePosition, List<Range>> sideRanges in emptyRanges)
            {
                foreach (Range range in sideRanges.Value)
                {
                    for (int i = 0; i < range.Length; i++)
                    {
                        int x, y;
                        switch (sideRanges.Key)
                        {
                            case TownQuarterInterfacePosition.Top:
                                x = range.Begin + i;
                                y = BlockWidth - 1;
                                break;
                            case TownQuarterInterfacePosition.Right:
                                x = bitmapSize.Width - BlockWidth;
                                y = range.Begin + i;
                                break;
                            case TownQuarterInterfacePosition.Bottom:
                                x = range.Begin + i;
                                y = bitmapSize.Height - BlockWidth;
                                break;
                            case TownQuarterInterfacePosition.Left:
                                x = BlockWidth - 1;
                                y = range.Begin + i;
                                break;
                            default:
                                throw new InvalidOperationException("Unknown TownQuarterInterfacePosition value.");
                        }

                        mapBitmap[x * bitmapSize.Height + y] = MapFillType.Sidewalk;
                        FlatObject sidewalk = new FlatObject(new PositionInTown(this, new Vector2(x * SquareWidth, y * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), sidewalkTexture);
                        groundObjects.AddLast(sidewalk);
                    }
                }
            }
        }
示例#3
0
        /// <summary>
        /// Generates road and sidewalks interfaces - street for joining with other quarters.
        /// </summary>
        /// <param name="degree">Number of'quarters neighbors - degree of vertex</param>
        /// <param name="roadTexture">Used road texture</param>
        /// <param name="sidewalkTexture">Used sidewalk texture</param>
        private void GenerateInterfaces(int degree, Texture2D roadTexture, Texture2D sidewalkTexture)
        {
            Dictionary<TownQuarterInterfacePosition, List<Range>> emptyRanges = new Dictionary<TownQuarterInterfacePosition, List<Range>>(4);
            emptyRanges.Add(TownQuarterInterfacePosition.Top, new List<Range>(new Range[] { new Range(BlockWidth + 1, bitmapSize.Width - BlockWidth - 1) }));
            emptyRanges.Add(TownQuarterInterfacePosition.Bottom, new List<Range>(new Range[] { new Range(BlockWidth + 1, bitmapSize.Width - BlockWidth - 1) }));
            emptyRanges.Add(TownQuarterInterfacePosition.Left, new List<Range>(new Range[] { new Range(BlockWidth + 1, bitmapSize.Height - BlockWidth - 1) }));
            emptyRanges.Add(TownQuarterInterfacePosition.Right, new List<Range>(new Range[] { new Range(BlockWidth + 1, bitmapSize.Height - BlockWidth - 1) }));

            for (int i = 0; i < degree; i++)
            {
                TownQuarterInterfacePosition side;
                List<TownQuarterInterfacePosition> possibleSides = new List<TownQuarterInterfacePosition>(
                    from key in emptyRanges.Keys where emptyRanges[key].Count(rangeItem => rangeItem.Length > 2 * BlockWidth + 1) > 0 select key
                    );

                if (possibleSides.Count < 1)
                {
                    throw new NoSpaceForInterfaceException("This quarter has already full all sides of interfaces. Degree argument is too big.");
                }

                side = possibleSides[game.Random.Next(0, possibleSides.Count - 1)];

                List<Range> possibleRanges = emptyRanges[side].FindAll(rangeItem => rangeItem.Length > 2 * BlockWidth + 1);

                int rangeIndex = game.Random.Next(0, possibleRanges.Count - 1);
                Range range = possibleRanges[rangeIndex];
                emptyRanges[side].Remove(range);

                int position = range.Begin
                    + (int)((0.35 + game.Random.NextDouble() * 0.3) // percentage position in range
                    * range.Length);

                emptyRanges[side].Add(new Range(range.Begin, position - 1));
                emptyRanges[side].Add(new Range(position + 1, range.End));

                AxisDirection direction
                    = (side == TownQuarterInterfacePosition.Right || side == TownQuarterInterfacePosition.Left) ? AxisDirection.Horizontal : AxisDirection.Vertical;

                TownQuarterInterface iface = new TownQuarterInterface { SidePosition = side, Quarter = this, OppositeInterface = null };
                for (int p = 0; p < BlockWidth; p++)
                {
                    int rx, ry, slx, sly, srx, sry;
                    switch (direction)
                    {
                        case AxisDirection.Horizontal:
                            rx = (p + (side == TownQuarterInterfacePosition.Left ? 0 : bitmapSize.Width - BlockWidth));
                            ry = position;
                            slx = rx;
                            srx = rx;
                            sly = ry - 1;
                            sry = ry + 1;
                            break;
                        case AxisDirection.Vertical:
                            rx = position;
                            ry = (p + (side == TownQuarterInterfacePosition.Top ? 0 : bitmapSize.Height - BlockWidth));
                            slx = rx - 1;
                            srx = rx + 1;
                            sly = ry;
                            sry = ry;
                            break;
                        default:
                            throw new InvalidOperationException("Unknown AxisDirection value.");
                    }

                    if (direction == AxisDirection.Horizontal)
                        iface.BitmapPosition = ry;
                    if (direction == AxisDirection.Vertical)
                        iface.BitmapPosition = rx;

                    mapBitmap[rx * bitmapSize.Height + ry] = MapFillType.Road;
                    mapBitmap[slx * bitmapSize.Height + sly] = MapFillType.Sidewalk;
                    mapBitmap[srx * bitmapSize.Height + sry] = MapFillType.Sidewalk;
                    FlatObject road = new FlatObject(new PositionInTown(this, new Vector2(rx * SquareWidth, ry * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), roadTexture);
                    FlatObject sidewalkL = new FlatObject(new PositionInTown(this, new Vector2(slx * SquareWidth, sly * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), sidewalkTexture);
                    FlatObject sidewalkR = new FlatObject(new PositionInTown(this, new Vector2(srx * SquareWidth, sry * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), sidewalkTexture);
                    groundObjects.AddLast(road);
                    groundObjects.AddLast(sidewalkL);
                    groundObjects.AddLast(sidewalkR);
                }

                //wall generator
                {
                    Texture2D wallTexture = game.ContentRepository.InterfaceWall;
                    float wallWidth = 6f; //m
                    const float wallHeight = 4.5f;
                    int count = (int)((BlockWidth - 1) * SquareWidth / wallWidth); //minus sidewalk
                    wallWidth = (BlockWidth - 1) * SquareWidth / count;
                    const float ifaceWallEpsilon = 0.006f; // 3mm
                    for (int p = 0; p < count; p++)
                    {
                        Vector2 beginL, endL, beginR, endR;
                        switch (direction)
                        {
                            case AxisDirection.Horizontal:
                                beginL.X = p * wallWidth + (side == TownQuarterInterfacePosition.Left ? 0 : bitmapSize.Width - BlockWidth + 1) * SquareWidth;
                                beginL.Y = (position - 1) * SquareWidth + ifaceWallEpsilon;
                                endL = beginL;
                                endL.X += wallWidth;

                                beginR.X = p * wallWidth + (side == TownQuarterInterfacePosition.Left ? 0 : bitmapSize.Width - BlockWidth + 1) * SquareWidth;
                                beginR.Y = (position + 2) * SquareWidth - ifaceWallEpsilon;
                                endR = beginR;
                                endR.X += wallWidth;
                                break;
                            case AxisDirection.Vertical:
                                beginL.Y = p * wallWidth + (side == TownQuarterInterfacePosition.Top ? 0 : bitmapSize.Height - BlockWidth + 1) * SquareWidth;
                                beginL.X = (position - 1) * SquareWidth + ifaceWallEpsilon;
                                endL = beginL;
                                endL.Y += wallWidth;

                                beginR.Y = p * wallWidth + (side == TownQuarterInterfacePosition.Top ? 0 : bitmapSize.Height - BlockWidth + 1) * SquareWidth;
                                beginR.X = (position + 2) * SquareWidth - ifaceWallEpsilon;
                                endR = beginR;
                                endR.Y += wallWidth;
                                break;
                            default:
                                throw new InvalidOperationException("Unknown AxisDirection value.");
                        }
                        Plate wallL = new Plate(this, beginL.ToVector3(wallHeight), endL.ToVector3(wallHeight), beginL.ToVector3(0), endL.ToVector3(0), wallTexture, wallTexture, true);
                        solidPlates.AddLast(wallL);
                        Plate wallr = new Plate(this, beginR.ToVector3(wallHeight), endR.ToVector3(wallHeight), beginR.ToVector3(0), endR.ToVector3(0), wallTexture, wallTexture, true);
                        solidPlates.AddLast(wallr);
                    }
                }

                interfaces.Add(iface);
            }

            GenerateRestOfBorderSidewalks(emptyRanges, sidewalkTexture);
            GenerateBorderBuildings(emptyRanges);
        }
示例#4
0
 /// <summary>
 /// Generates ground grass.
 /// </summary>
 /// <param name="grassTexture">Grass texture</param>
 /// <param name="emptyRectaglesInsideSidewalks">The target rectangles for the grass filling</param>
 private void GenerateGrass(Texture2D grassTexture, List<Rectangle> emptyRectaglesInsideSidewalks)
 {
     float grassWidth = 13.5f; //m
     foreach (Rectangle emptyRect in emptyRectaglesInsideSidewalks)
     {
         int xCount = (int)((emptyRect.Width * SquareWidth) / grassWidth) + 1;
         int yCount = (int)((emptyRect.Height * SquareWidth) / grassWidth) + 1;
         Vector2 size = new Vector2((emptyRect.Width * SquareWidth) / xCount, (emptyRect.Height * SquareWidth) / yCount);
         for (int x = 0; x < xCount; x++)
         {
             for (int y = 0; y < yCount; y++)
             {
                 Vector2 position = new Vector2(emptyRect.X * SquareWidth + x * size.X, emptyRect.Y * SquareWidth + y * size.Y);
                 FlatObject grass = new FlatObject(new PositionInTown(this, position), 0, size, grassTexture);
                 groundObjects.AddFirst(grass);
             }
         }
     }
 }
示例#5
0
        /// <summary>
        /// Generates border road network.
        /// </summary>
        /// <param name="roadTexture">Road texture</param>
        /// <returns>Empty rectangle inside the bitmap</returns>
        private Rectangle GenerateBorderRoads(Texture2D roadTexture)
        {
            int xOffset = BlockWidth;
            int yOffset = BlockWidth;
            int xCount = bitmapSize.Width - 2 * xOffset;
            int yCount = bitmapSize.Height - 2 * yOffset;

            for (int x = 0; x < xCount; x++)
            {
                int X = x + xOffset;
                foreach (int y in new int[] { 0, yCount - 1 })
                {
                    int Y = y + yOffset;
                    mapBitmap[X * bitmapSize.Height + Y] = MapFillType.Road;
                    FlatObject road = new FlatObject(new PositionInTown(this, new Vector2(X * SquareWidth, Y * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), roadTexture);
                    groundObjects.AddLast(road);
                }
            }
            for (int y = 1; y < yCount - 1; y++)
            {
                int Y = y + yOffset;
                foreach (int x in new int[] { 0, xCount - 1 })
                {
                    int X = x + xOffset;
                    mapBitmap[X * bitmapSize.Height + Y] = MapFillType.Road;
                    FlatObject road = new FlatObject(new PositionInTown(this, new Vector2(X * SquareWidth, Y * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), roadTexture);
                    groundObjects.AddLast(road);
                }
            }
            return new Rectangle(xOffset + 1, yOffset + 1, xCount - 2, yCount - 2);
        }
示例#6
0
        /// <summary>
        /// Splits the given rectangle with a road.
        /// </summary>
        /// <param name="target">Splited rectangle</param>
        /// <param name="roadTexture">Road texture</param>
        /// <returns>Array of new empty rectangles inside the splited rectangle</returns>
        private Rectangle[] AddSplittingRoad(ref Rectangle target, Texture2D roadTexture)
        {
            AxisDirection direction;
            if (target.Width < target.Height)
                direction = AxisDirection.Horizontal;
            else
                direction = AxisDirection.Vertical;

            int size = (direction == AxisDirection.Horizontal ? target.Height : target.Width);
            int secondDimensionSize = (direction == AxisDirection.Horizontal ? target.Width : target.Height);

            Random rand = new Random();
            int splitPosition = (int)(
                (0.35 + rand.NextDouble() * 0.3) //percentage side
                * (size - 1));

            for (int i = 0; i < secondDimensionSize; i++)
            {
                Vector2 position = Vector2.Zero;
                int bitmapIndex = -1;
                switch (direction)
                {
                    case AxisDirection.Horizontal:
                        position = new Vector2((i + target.X) * SquareWidth, (splitPosition + target.Y) * SquareWidth);
                        bitmapIndex = (i + target.X) * bitmapSize.Height + (splitPosition + target.Y);
                        break;
                    case AxisDirection.Vertical:
                        position = new Vector2((splitPosition + target.X) * SquareWidth, (i + target.Y) * SquareWidth);
                        bitmapIndex = (splitPosition + target.X) * bitmapSize.Height + (i + target.Y);
                        break;
                    default:
                        throw new InvalidOperationException("Unknown AxisDirection for splitting.");
                }

                mapBitmap[bitmapIndex] = MapFillType.Road;
                FlatObject road = new FlatObject(new PositionInTown(this, position), 0, new Vector2(SquareWidth, SquareWidth), roadTexture);
                groundObjects.AddLast(road);
            }

            Rectangle[] emptyRectangles = new Rectangle[2];
            if (direction == AxisDirection.Horizontal)
            {
                emptyRectangles[0] = new Rectangle(target.X, target.Y, target.Width, splitPosition);
                emptyRectangles[1] = new Rectangle(target.X, target.Y + splitPosition + 1, target.Width, target.Height - splitPosition - 1);
            }
            else if (direction == AxisDirection.Vertical)
            {
                emptyRectangles[0] = new Rectangle(target.X, target.Y, splitPosition, target.Height);
                emptyRectangles[1] = new Rectangle(target.X + splitPosition + 1, target.Y, target.Width - splitPosition - 1, target.Height);
            }
            return emptyRectangles;
        }