|
|
|
|
Reply From: |
Zylann |
There are many ways to do this, but I can explain one.
You should be able to do this in several steps.
First, your animation needs to be tileable, so it can be repeated horizontally across the screen without seams.
This raises the question about how your animation should look like:
- Is is the same pattern repeating vertically as well?
- Or does it have two animations, one at the top (splashes) and then something repeating downwards (bubbles) ?
- Or is it an entire animated vertical strip, high enough so it can cover the screen?
Once you figured out how to make one vertical strip arranged in one of those three ways, you can save one strip as a LavaStrip
scene, then look into repeating it horizontally.
Create a LavaRoot
node under the root of your level, and put one lava strip as child. Then, duplicate it several times horizontally, so that you end up with something like this:
- LavaRoot (Node2D) <-- this one will raise slowly
- LavaVerticalStrip
- LavaVerticalStrip2
- LavaVerticalStrip3
- ...
You can do that in editor, or using a script by calling duplicate()
and moving the copy to the right using something like .position += Vector2(lava_strip_width, 0)
.
The amount of copies required should be just enough to cover the area visible by the camera.
Then, to make it look infinite, we can translate LavaRoot
along the X axis by some amount depending on the camera X position, so that it will always be shown.
You can do this in a script on LavaRoot
:
func _process(delta):
position.x = camera_position.x
However that will make the lava follow the camera along X, which will look static. Here is a trick to make it look like it is part of the level:
func _process(delta):
position.x = stepify(camera_position.x, lava_strip_width)
This will make the X position change by increments that are the same width as the repeated strips of lava, so it will appear fixed inside the world, while in fact it keeps all strips of lava in view. Since all strips are the same, the illusion is seamless.
Notes:
I wrote two variables here without explaining how to get them, to keep the logic clear.
lava_strip_width
is basically the width of each of your strips, you should be able to get it from the texture you used for the animation.
camera_position
can be obtained either by using get_node(path).position
with the path to your camera, or by using the following code:
func _get_camera_center():
var ctrans = get_canvas_transform()
var top_left = -ctrans.get_origin()
var vsize = get_viewport_rect().size
var center = (top_left + 0.5*vsize) / ctrans.get_scale()
return center
Note 2:
I wrote all this by head, I haven’t tested any of this, so it’s possible that some adjustments may be needed. I know however that this approach should work well, I hope it is what you were looking for.