![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | delphonso |
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.
.
EDIT:
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)