Generador de islas
Ruido multiplicado por una máscara radial y pintado en una Image banda a banda. Haz clic para otra isla.
El editor de arriba está ejecutando este proyecto. Cambia una línea y se recarga.
Clases de Godot usadas
FastNoiseLiteImageImageTexture
El código
scripts/main.gd
extends Node
const MAP: Vector2i = Vector2i(320, 180)
const PIXEL: float = 4.0
const SEED: int = 20260814
const BANDS: Array = [
{limit = 0.28, color = '#161c2c'},
{limit = 0.40, color = '#2a2f3d'},
{limit = 0.46, color = '#f3d48d'},
{limit = 0.60, color = '#8eef97'},
{limit = 0.74, color = '#4c9c60'},
{limit = 0.86, color = '#8da5f3'},
{limit = 2.00, color = '#e6ecff'},
]
var rng: RandomNumberGenerator = RandomNumberGenerator.new()
var map: Sprite2D
var label: Label
func _ready() -> void:
_add_background()
map = Sprite2D.new()
map.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
map.scale = Vector2(PIXEL, PIXEL)
map.position = get_viewport().get_visible_rect().size * 0.5
add_child(map)
label = Label.new()
label.position = Vector2(28, 22)
label.add_theme_color_override('font_color', Color('#e6ecff'))
label.add_theme_color_override('font_shadow_color', Color('#12141a'))
label.add_theme_constant_override('shadow_offset_y', 2)
add_child(label)
rng.seed = SEED
_generate(SEED)
print('click for another island, the first one always comes from SEED')
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.pressed:
_generate(rng.randi())
func _generate(island_seed: int) -> void:
var noise: FastNoiseLite = FastNoiseLite.new()
noise.seed = island_seed
noise.noise_type = FastNoiseLite.TYPE_SIMPLEX
noise.fractal_octaves = 5
noise.frequency = 0.016
var image: Image = Image.create(MAP.x, MAP.y, false, Image.FORMAT_RGBA8)
var center: Vector2 = Vector2(MAP) * 0.5
var radius: float = MAP.y * 0.54
for y in MAP.y:
for x in MAP.x:
var falloff: float = clampf(1.0 - (Vector2(x, y) - center).length() / radius, 0.0, 1.0)
var value: float = noise.get_noise_2d(x, y) * 0.5 + 0.5
image.set_pixel(x, y, _band_color(value * pow(falloff, 0.55) * 1.35))
map.texture = ImageTexture.create_from_image(image)
label.text = 'seed %d, click for another' % island_seed
func _band_color(height: float) -> Color:
for band in BANDS:
if height < band.limit:
return Color(band.color)
return Color(BANDS[BANDS.size() - 1].color)
func _add_background() -> void:
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
# ColorRect defaults to MOUSE_FILTER_STOP and would eat the click before _unhandled_input
background.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(background)
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)