|Attention||Topic was automatically imported from the old Question2Answer platform.|
In Godot 3.3.2. I’m attempting to make a Worms-like game. I found this tutorial by OptionalDev on youtube.
In this, terrain is generated by cutting the top portion of a sprite off following a random noise pattern. The collision is custom-built to say anything above that line is air, and anything below it is solid.
However, I want to make a tunnel map. I can generate maps that I like, with about 30% of the map covered in ground and 10% covered in roof and open air in between.
However, the collision becomes a problem. Following this tutorial - the roof would have no collision, which I obviously don’t want. You also don’t get the benefits of Godot’s native collision objects.
The tutorials I’ve seen of MeshInstance2D all suppose a Sprite that hasn’t been programmatically modified, and I’m not sure it is what I want anyway. As this is one sprite, and not several blocks, CollisionShape2D doesn’t seem like a good choice.
Of course, the goal of this will be destructible terrain.
Any guidance on where I should look next would be much appreciated.
I have managed to recreate the tutorial’s collisions on the roof as well, but I’m still wondering if there is a way to programmatically make Godot generate CollisionShape2Ds that cover the visible portions of the image.
I should also point out that the image isn’t actually cut or removed at all - merely the “open” portion is set to Color(0,0,0,0) - the Alpha being 0 is the most important part.
I’m using the following code - only one modification from the tutorial’s code, which is better commented.
onready var FG = $Foreground const CLEAR = Color(0, 0, 0, 0) var line =  func _ready() -> void: randomize() _generate_map() func _generate_map(): var fg_data = FG.texture.get_data() fg_data.lock() var noise = OpenSimplexNoise.new() noise.seed = randi() noise.octaves = 2 noise.period = 180 noise.persistence = 0.8 for x in range(fg_data.get_width()): var high = ((noise.get_noise_1d(x) + 1) * fg_data.get_height() * 0.3) + fg_data.get_height() * 0.08 line.append(high) for y in range(high): fg_data.set_pixelv(Vector2(x, y + (high*0.3)), CLEAR) fg_data.unlock() FG.texture.set_data(fg_data)