Naive WFC kind of working
This commit is contained in:
52
wfc/generator.gd
Normal file
52
wfc/generator.gd
Normal file
@@ -0,0 +1,52 @@
|
||||
extends Node
|
||||
## The generator works with pure numbers, you'll need something else to convert it to actual tiles
|
||||
|
||||
## Makes a new chunk, derived from the given WFC samples
|
||||
func generate_chunk_at(_x: int, _y: int, _chunk_array: Array[Chunk], _samples: Array[PackedInt32Array]) -> Chunk:
|
||||
#TODO: fix the chunk-edges
|
||||
var chunk: Chunk = Chunk.new(_x, _y)
|
||||
|
||||
var latch: int = 1
|
||||
while latch:
|
||||
latch = 0 #if set to true, the generator needs another pass
|
||||
#iterate over unset tiles with valid neighbours
|
||||
for x in range(Chunk.CHUNK_WIDTH):
|
||||
for y in range((Chunk.CHUNK_HEIGHT)):
|
||||
if chunk.data[y * Chunk.CHUNK_HEIGHT + x] == 0: #direct access, to skip extra checks
|
||||
#TODO: convert this to the low-entropy method
|
||||
if _set_tile_from_samples(chunk, x, y, _samples) > 0:
|
||||
latch += 1
|
||||
print("latch: ", latch)
|
||||
|
||||
print(chunk.data)
|
||||
_chunk_array.append(chunk)
|
||||
return chunk
|
||||
|
||||
## Returns the value set, or -1 if no options found
|
||||
func _set_tile_from_samples(chunk: Chunk, tile_x: int, tile_y: int, _samples: Array[PackedInt32Array]) -> int:
|
||||
var valid: Array[PackedInt32Array] = []
|
||||
|
||||
#use a lambda for easy reading below
|
||||
var compare := func (tile_value: int, sample: int) -> bool:
|
||||
return tile_value <= 0 or tile_value == sample
|
||||
|
||||
#find all valid samples
|
||||
for sample in _samples:
|
||||
if !compare.call(chunk.get_tile(tile_x -1, tile_y -1), sample[0]): continue
|
||||
if !compare.call(chunk.get_tile(tile_x , tile_y -1), sample[1]): continue
|
||||
if !compare.call(chunk.get_tile(tile_x +1, tile_y -1), sample[2]): continue
|
||||
if !compare.call(chunk.get_tile(tile_x -1, tile_y ), sample[3]): continue
|
||||
# //
|
||||
if !compare.call(chunk.get_tile(tile_x +1, tile_y ), sample[5]): continue
|
||||
if !compare.call(chunk.get_tile(tile_x -1, tile_y +1), sample[6]): continue
|
||||
if !compare.call(chunk.get_tile(tile_x , tile_y +1), sample[7]): continue
|
||||
if !compare.call(chunk.get_tile(tile_x +1, tile_y +1), sample[8]): continue
|
||||
|
||||
valid.append(sample)
|
||||
print("Valid samples: ", valid.size())
|
||||
if valid.size() <= 0: return -1
|
||||
var s = valid.pick_random()
|
||||
|
||||
#set the tile to the randomly selected value
|
||||
chunk.set_tile(tile_x, tile_y, s[4])
|
||||
return s[4]
|
||||
Reference in New Issue
Block a user