예제 #1
0
    /**
     * Generate a world and store it on disk
     * @param world_id - name of the world
     * @param width - width of the world
     * @param height - height of the world
     */
    public void generate_world(string world_id, int width, int height)
    {
        var timer = System.Diagnostics.Stopwatch.StartNew();

        // create noise
        var noise_generator = new NoiseGenerator();
        var map_data        = noise_generator.GenerateNoise(height, width);

        // flatten noise to 0 or 1
        var threshold     = 0.5f; // walkable iff value <= threshold
        var alt_threshold = 0.47f;

        for (int i = 0; i < height; ++i)
        {
            for (int j = 0; j < width; ++j)
            {
                var value = map_data[i, j];
                map_data[i, j] = value <= alt_threshold ? 1.1f : value <= threshold ? 1.0f : 0.0f;
            }
        }

        // place portal entrance
        var portal_entrance = new int[] { Random.Range(0, height - 3), Random.Range(0, width - 3) };

        place_portal_in_map(portal_entrance, 3.0f, ref map_data);

        // place dungeon entrance
        var dungeon_entrance = new int[2];
        {
            bool dungeon_placed = false;
            while (!dungeon_placed)   // make sure it doesn't overwrite the portal entrance
            {
                dungeon_entrance = new int[] { Random.Range(0, height - 3), Random.Range(0, width - 3) };
                dungeon_placed   = place_portal_in_map(dungeon_entrance, 4.0f, ref map_data);
            }
        }

        // place towns

        // town 1
        var town_1_size = 16;
        var town_1      = new Town(town_1_size, town_1_size);
        {
            bool town_1_placed = false;
            while (!town_1_placed)
            {
                town_1.pos    = new int[] { Random.Range(0, height - town_1.height), Random.Range(0, width - town_1.width) };
                town_1_placed = place_town_in_map(town_1, ref map_data);
            }
        }

        // town 2
        var town_2_size = 8;
        var town_2      = new Town(town_2_size, town_2_size);
        {
            bool town_2_placed = false;
            while (!town_2_placed)
            {
                town_2.pos    = new int[] { Random.Range(0, height - town_2.height), Random.Range(0, width - town_2.width) };
                town_2_placed = place_town_in_map(town_2, ref map_data);
            }
        }

        // town 3
        var town_3_size = 4;
        var town_3      = new Town(town_3_size, town_3_size);

        {
            bool town_3_placed = false;
            while (!town_3_placed)
            {
                town_3.pos    = new int[] { Random.Range(0, height - town_3.height), Random.Range(0, width - town_3.width) };
                town_3_placed = place_town_in_map(town_3, ref map_data);
            }
        }

        // make sure key points are reachable
        build_path_between(portal_entrance, dungeon_entrance, map_data);
        build_path_between(town_1.pos, portal_entrance, map_data);
        build_path_between(town_2.pos, portal_entrance, map_data);
        build_path_between(town_3.pos, portal_entrance, map_data);
        build_path_between(town_3.pos, town_1.pos, map_data);
        build_path_between(town_3.pos, town_2.pos, map_data);
        build_path_between(town_2.pos, town_1.pos, map_data);

        // save map to disk
        var map_color    = world_id.Substring(0, world_id.IndexOf('_'));
        var tilemap_data = new TileMapData(map_width, map_height, map_color);

        for (int i = 0; i < map_height; ++i)
        {
            for (int j = 0; j < map_width; ++j)
            {
                var tile = new TileMapData.Tile();
                tile.value = map_data[i, j];
                tilemap_data.setTile(i, j, tile);
            }
        }

        // store the key points in the tile map data for future reference for the merchant pathfinding
        tilemap_data.portal_entrance  = new int[] { portal_entrance[0] + 1, portal_entrance[1] + 1 };
        tilemap_data.dungeon_entrance = new int[] { dungeon_entrance[0] + 1, dungeon_entrance[1] + 1 };
        tilemap_data.town_1           = new int[] { town_1.pos[0] + town_1.height / 2, town_1.pos[1] + town_1.width / 2 };
        tilemap_data.town_2           = new int[] { town_2.pos[0] + town_2.height / 2, town_2.pos[1] + town_2.width / 2 };
        tilemap_data.town_3           = new int[] { town_3.pos[0] + town_3.height / 2, town_3.pos[1] + town_3.width / 2 };

        // save to disk
        tilemap_data.saveToDisk(world_id + "_map_data.bin");

        Debug.Log(string.Format("Time to generate {1}: {0} ms", timer.ElapsedMilliseconds, world_id));
    }