0 votes

I'm following NAD LABS' tutorial on procedural tile generation, & came across a problem. Sometimes, when I play the scene, all of the tiles are grass tiles, & none of them are water tiles. I thought of scanning the screen & seeing if the amount of water tiles are < insert random integer here, then restart the scene until there's a reasonable amount of water tiles on the screen. Can anyone tell me how to scan the screen & how to get a tile's ID?

BTW here's the code I'm using:

extends Node2D

var width = 60
var height = 34
onready var tile_map = get_node("ProceduralWorldTileMap")
var open_simplex_noise = OpenSimplexNoise.new()

func _ready():
    randomize()
    open_simplex_noise.seed = randi()
    open_simplex_noise.octaves = 5
    _generate_map()

func _generate_map():
    for x in width:
        for y in height:
            var map = floor(abs(open_simplex_noise.get_noise_2d(x, y) * 3))
            tile_map.set_cell(x, y, map)

Sincerely, Some Random Newbie

Godot version 3.3
in Engine by (56 points)

1 Answer

0 votes

So what you're trying to accomplish and the method you're using to generate a random tile map are conflicting. If you have 1 water tile and 1 grass tile in your TileSet it's equally likely that you'll get a grass or a water tile. I would suggest making your map generation function more general first. Then you can add more water tiles to your TileSet to make them have a higher probability of occurring. So if you have 3 water tiles and 1 grass in your TileSet, your code is 3x more likely to select a water tile than a grass tile.

func _generate_map():
    var tile_set = tile_map.tile_set
    var tile_types = tile_set.get_tiles_ids()
    var max_index = tile_types.size() - 1
    for x in width:
        for y in height:
            var map = floor(abs(open_simplex_noise.get_noise_2d(x, y) * max_index))
            tile_map.set_cell(x, y, map)

If you insist on the more brute force method of having a minimum number of water tiles on the map then this will do that but you'll lose the niceness of the open_simplex_noise generation and the water tiles will look more randomly thrown in there:

func _generate_map():
    var water_tile_index = 2  # whatever the index of your water tile index is
    var water_tiles_generated = []
    var minimum_number_of_water_tiles = 30
    var tile_set = tile_map.tile_set
    var tile_types = tile_set.get_tiles_ids()
    var max_index = tile_types.size() - 1
    for x in width:
        for y in height:
            var map = floor(abs(open_simplex_noise.get_noise_2d(x, y) * max_index))
            tile_map.set_cell(x, y, map)
            if map == water_tile_index:
                water_tiles_generated.append(Vector2(x,y))

    while water_tiles_generated.size() < minimum_number_of_water_tiles:
        randomize()
        var random_vector = Vector2(randi() % width + 1, randi() % height +1)
        if random_vector in water_tiles_generated:
            continue
        else:
            tile_map.set_cell(random_vector.x, random_vector.y, water_tile_index)
            water_tiles_generated.append(random_vector)
by (3,665 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.