endles dynamic background scroll

Example of endles dynamic background scroll with mod wavefunctioncollapse and tiles from a tileset. GDScript
 avatar
unknown
plain_text
10 days ago
4.7 kB
1
Indexable
extends Node2D

# Scene tree setup
#
# Node2D (this Script)
# 	Parallax2D
#		TileMapLayer

var screen = Vector2()
var tileScreen = Vector2i()

var lastButtomElements = Array()
var lastLeftElement = -1
var lastRow = -1

@onready var Scroll = $Parallax2D
@onready var Map = $Parallax2D/Map

# Tile definitions
# Define what Tile can dock on what Tile
var tileList = [
	{	"desc":"0 water",
		"multipl":1,
		"atlasCords":Vector2i(8,11),
		"allowedTop":[0,8],
		"allowedR":[0,6,11],
		"version":[]
	},
	{	"desc":"1 gras",
		"multipl":80,
		"atlasCords":Vector2i(0,0),
		"allowedTop":[1,2,3,4],
		"allowedR":[1,3,5,7],
		"version":[Vector2i(1,0),Vector2i(2,0),Vector2i(0,1),Vector2i(1,1),Vector2i(2,1),Vector2i(0,2),Vector2i(1,2),Vector2i(2,2)]
	},
	{	"desc":"2 grasUfer_cb",
		"multipl":1,
		"atlasCords":Vector2i(8,12),
		"allowedTop":[0,8],
		"allowedR":[2,4,10,11],
		"version":[]
	},
	{	"desc":"3 grasUfer_lb",
		"multipl":1,
		"atlasCords":Vector2i(7,12),
		"allowedTop":[5,7,10],
		"allowedR":[2,4,10,11],
		"version":[]
	},
	{	"desc":"4 grasUfer_rb",
		"multipl":1,
		"atlasCords":Vector2i(9,12),
		"allowedTop":[6,9],
		"allowedR":[1,3,5,7],
		"version":[]
	},
	{	"desc":"5 grasUfer_lc",
		"multipl":1,
		"atlasCords":Vector2i(7,11),
		"allowedTop":[5,7,10],
		"allowedR":[0,6],
		"version":[]
	},
	{	"desc":"6 grasUfer_rc",
		"multipl":1,
		"atlasCords":Vector2i(9,11),
		"allowedTop":[6,9,11],
		"allowedR":[1,3,5,7],
		"version":[]
	},
	{	"desc":"7 grasUfer_lt",
		"multipl":1,
		"atlasCords":Vector2i(7,10),
		"allowedTop":[1,2,3,4],
		"allowedR":[8,9],
		"version":[]
	},
	{	"desc":"8 grasUfer_ct",
		"multipl":1,
		"atlasCords":Vector2i(8,10),
		"allowedTop":[1,2,3,4],
		"allowedR":[8,9],
		"version":[]
	},
	{	"desc":"9 grasUfer_rt",
		"multipl":1,
		"atlasCords":Vector2i(9,10),
		"allowedTop":[1,2,3,4],
		"allowedR":[1,3,5,7],
		"version":[]
	},
	{	"desc":"10 grasCorner_lb",
		"multipl":1,
		"atlasCords":Vector2i(10,11),
		"allowedTop":[0,8],
		"allowedR":[0,6,11],
		"version":[]
	},
	{	"desc":"11 grasCorner_rb",
		"multipl":1,
		"atlasCords":Vector2i(11,11),
		"allowedTop":[0,8],
		"allowedR":[0,2,4,10],
		"version":[]
	},
	{	"desc":"Error",
		"multipl":1,
		"atlasCords":Vector2i(22,4),
		"allowedTop":[1,2,3,4,5,6,7,8,9,10],
		"allowedR":[1,2,3,4,5,6,7,8,9,10],
		"version":[]
	},
]

# Detect what Line of Tiles is outside the view
func _process(_delta):
	var gP = int(Map.global_position.y*-1/16)
	if lastRow != gP:
		lastRow = gP
		var posMap = Vector2i(0,0)
		posMap.y = lastRow
		lastLeftElement = -1
		for posx in range(tileScreen.x):
			posMap.x = posx
			Map.set_cell(posMap, 0, getTile(posMap), 0)
	
# calculate how many Lines of Tiles we will need
# set the repeat point (view+Tile_size) so that one Line is allwas out of view
func _ready():
	screen = get_viewport().get_visible_rect().size
	tileScreen.x = screen.x / 16
	tileScreen.y = screen.y / 16
	lastRow = tileScreen.y
	Scroll.repeat_size.y = 16+screen.y
	generateMap(Map)

# Generate the Map 
# starting at the bottomleft corner of the view (+one Line out of view)
func generateMap(newMap):
	var posMap = Vector2i(0,0)
	for posy in range(tileScreen.y):
		posMap.y = tileScreen.y-posy-1
		lastLeftElement = -1
		for posx in range(tileScreen.x):
			posMap.x = posx
			newMap.set_cell(posMap, 0, getTile(posMap), 0)

func getTile(linePos)->Vector2i:
	var listOfAllowedTiles = Array([1])
	if len(lastButtomElements) == tileScreen.x:
		listOfAllowedTiles = tileList[lastButtomElements[linePos.x]].allowedTop
	else:
		for i in len(tileList):
			listOfAllowedTiles.append(i)
	
	if lastLeftElement != -1:
		var temp_allow = Array()
		for i in tileList[lastLeftElement].allowedR:
			if listOfAllowedTiles.find(i) != -1:
				temp_allow.append(i)
				
		if len(temp_allow) == 0:
			print("error: ","lastLeft:",tileList[lastLeftElement].desc," lastBottum: ",tileList[lastButtomElements[linePos.x]].desc,tileList[lastLeftElement].allowedR, listOfAllowedTiles)
			temp_allow.append(12)
			
		var modList = Array()
		for i in temp_allow:
			var r = tileList[i].multipl
			for x in range(r):
				modList.append(i)
				
		listOfAllowedTiles = modList
	
	var rnd = randi_range(0,len(listOfAllowedTiles)-1)
	lastLeftElement = listOfAllowedTiles[rnd]
	
	if len(lastButtomElements) != tileScreen.x:
		lastButtomElements.append(lastLeftElement)
	else:
		lastButtomElements[linePos.x] = lastLeftElement
	
	# randomize terainVersions
	var cords = tileList[lastLeftElement].atlasCords
	if len(tileList[lastLeftElement].version) != 0:
		if randi_range(0,10) > 8:
			var rnd_version = randi_range(0,len(tileList[lastLeftElement].version)-1)
			cords = tileList[lastLeftElement].version[rnd_version]
	return cords
Leave a Comment