4
\$\begingroup\$

I've recently attempt for the first time to implement a map generation system and while it does work, it doesn't work exactly the same I want but I'm not really sure on what changes I can make it to make it generate the type of map I want.

This is my map generation code

///<summary>Generates a Room at a Start Position</summary>
    void GenerateMap(Vector2 roomStartPos)
    {
        Vector2 startPos = roomStartPos;

        int roomTileNum = random.Next(minRoomTiles, maxRoomTiles);
        for (int i = 0; i < roomTileNum; i++)
        {
            if (CheckTilePosValid(startPos)) //Checks if a position is taken by a tile already
            {
                Tile newTile = CreateTile(startPos); //Creates a Tile at a passed in Position
                startPos = GetRandomEdgeDirection(newTile.SpritePosition); //Gets a Random position next to the passed in Position

            }
            else
            {
                startPos = GetRandomEdgeDirection(startPos);
                i--;
            }
        }
    }

It's likely a really bad way of generating a map. It basically gets a random number of tiles to generate, it will then place a Tile at the start position and select a new position in a random direction (Up, Down, Left, Right). It'll then place a new tile at that new position specified, it will then simply loop through that till it's placed every tile. The "CheckTilePosValid()" function is used to determine if the random position that is gathered has already been taken by a tile. If the position isn't taken then it will create the tile and continue through the loop, while if the position is taken then it will get a new position and basically keeping doing that till it gets a position that hasn't been taken already.

This generates maps like this: enter image description here

enter image description here

The issue is mainly with the first image since as you can see, the map is very stretched out which isn't what I want. I'd more want a map similar to the second image, tiles much closer together and not so stretched out but is still random enough.

I'm just not sure how exactly I can achieve this so I was wondering if anyone would be able to help me? Would I need to completely rework my generation system or can I just make simple changes to fix this? I'd very much appreciate the help :)

\$\endgroup\$
  • \$\begingroup\$ I would try playing with weighted random numbers. E.g. if you prefer the layout of your first picture, make tile placements towards right/left more likely than up/down. If you prefer layout more like the second picture, make tile placements in rotary direction more likely (e.g. if last tile was placed to the right, make down placements more likely). Another thing to try would be to force a width/height ratio of the map. E.g. If ratio is not allowed to exceed 3 (three times wider than height), forbid placing tiles that breaks this requirement. \$\endgroup\$ – Skitskraj May 17 '18 at 10:28
1
\$\begingroup\$

You could consider a different approach where you place some number of nodes on your map and then attach them together via hallways. This would allow you to generate your rooms at appropriate sizes because you'd be focusing on the rooms instead of the generation.

If you're looking for "Dead ends" I would simply use one of the following two options:

  • Generate some 0x0 rooms.

  • Generate Dead-End Nodes (basically the same as the above, but one is a special case and the other is a hack.)

You may start with your nodes, create your rooms, then have A* find a path between your rooms for you. Either way, I think that's enough to get your brain moving.

EDIT: I just realized I answered your related question before: Basic Random Tile Map Generation

Apologies that this advice is somewhat contradictory to my previous advice, as my previous was under the assumption you didn't want "hallways."

Either way, both pieces of advice hinge on building a room then dealing with additional randomization. I would literally have a room class that is something like:

class Room
{
    int width, height;
    Point TopLeftCorner;
    public static Room Generate()
    {
        Room room = new Room();
        Random rnd = new Random(/*timestamp or seed*/);

        // get our dimensions
        room.height = rnd.Next(2,6);
        room.width = rnd.Next(2,6);

        // create a point where the room can exist without hitting the edge
        TopLeftCorner = new Point(
                            rnd.Next(0,screenWidth-room.width),
                            rnd.Next(0,screenHeight-room.height));

        room.BuildRoom(); // where you place your tiles
    }

    void Buildroom()
    {
        //pseudo code cause I'm lazy
        for i in width
            for j in height
                placeTile(i,j)
    }

    // approximates center of room
    public Point RoomNode()
    {
        Point returnpt = new Point(width >> 1, height >> 1);
    }
}

After this, the remaining code would be about picking which sides you'd want to connect with a hallway and then using another generate function to walk tiles out between the rooms.

\$\endgroup\$
  • \$\begingroup\$ I likely should of just responded to my previous post though I thought it'd be best to make a new on. As yea, orginally I was wanting a map generation system that would make multiple rooms connected to each other though I've decided that one room would likely be best for what I want. \$\endgroup\$ – codelyoko373 May 5 '18 at 5:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.