+6 votes

Hi all!

I'm trying to make an infinite scrolling background in Godot. The idea is very simple.
I have two instance of the same background in the scene and move them to the left at a certain speed by also taking in to account delta.

x -= speed * delta

When the image pass the left edge of the screen which is position 0, I change the position of the image to the right edge of the screen and repeat all over again to create an infinite scrolling background effect.

However, in Godot for some reason I always get a little gap between the two image like 2-3 pixels only.

gap between the two image

Doesn't matter what I try to do, sooner or later that gap always appear but sometime only after a few seconds and sometime it is also flashing like a rendering glitch. The numbers seems to be correct so it is either a rendering issue or the two instance of the background is out of sync a few milliseconds. Both instance using the same script so I don't know if it matters.

I was searching the forum how others making infinite scrolling background but the only thing I find is that how to make parallax scrolling background when moving the camera but it is not exactly what I need since I don't move the camera. I want to move the background image only and I can't find any answer to why do I get this gap or line between the two image over time or how to make an infinite scrolling background in Godot that constantly moves to one direction and repeat.

Could anyone please help me with either how to fix that line/gap or suggest any other ways to go about making an infinite scrolling background in Godot?
I would appreciate any help.

Thanks.

in Engine by (66 points)
reshown by

have you tried something like what is explained here? http://kidscancode.org/blog/2017/04/godot_101_12/ it's using an older version of godot, but you should be able to adapt it to the version you are using.

Hi. Yes I did looked at those tutorials but all of them talking about how to make camera scroll and parallax scrolling effect. I did find a tutorial mentioned to move the camera left and right to make the effect I'm looking for. But I want to do it the other way around and instead of moving the camera I want to move the background.

Something tells me I can use the ParallaxLayer class to create an infinite scrolling background because the documentation saying I can use motion offset to control scrolling without using a camera and it got options to mirror and repeat the image. So maybe I can use it for what I need, but I could not figure out just yet how. If anyone could give me a kick in to the right direction like what properties I can use for this that would be great :)

Or if someone got any idea why do I get that gap/line when moving the background image that would be great too :)

Thanks

Could you post your project? Or a stripped down version of it with just the relevant parts?

Already had a look at this tutorial?
https://devga.me/tutorials/godot2d/creating-parallax-clouds/

About the Camera topic:

The ParallaxBackground’s scroll value. Calculated automatically when
using a Camera2D, but can be used to manually manage scrolling when no
camera is present.

I'm not into 2D but this looks helpful IMHO.

Yes, thank you. This is what I've seen too but could not figure out how to actually use it the way I need it. All the examples I've found was demonstrating how to use it to create parallax effect when scrolling the Camera. But I managed to figure out a way to make infinite scrolling background, going to post it now and mark it as a solution.

Thanks a lot for your help.

2 Answers

+3 votes
Best answer

I managed to create an infinite scrolling background.

Instead of moving and swapping 2 images to create the effect, I decided to set the image to "Repeat" in the import properties and then used the Region property of the sprite class to create a tiled sprite from the background as shown in this tutorial:
http://kidscancode.org/blog/2017/04/godot_101_12/

Then what I did is move the sprite to the left and when the origin point of the sprite (the middle of the Region) is about to leave the screen on the left I simply reset the position of the sprite back to the original and continue move to the left. The result is an infinite scrolling background effect.

This is my solution, but in case anyone have any better idea how to go about this, please share.

Thanks.

by (66 points)

hey,
I've been trying out working with shaders recently and just managed to succeed creating an infinite scrolling background without using a Camera and just a few lines of shader code. I thought this might be helpful to someone maybe..

So, I added my background texture to a sprite (make sure you set "Repeat" to Enabled in the Import section, just as mentioned above).
Then I added a new Shader Material to the sprite and added a new shader to that with the following code:

shader_type canvas_item;

uniform vec2 direction = vec2(1.0,0.0);
uniform float speed_scale = 0.05;

void fragment(){

     vec2 move = direction * TIME * speed_scale;

     COLOR = texture(TEXTURE, UV + move);   
}

now my background is infinitly moving to the left. Because of the "uniform" keyword you can simply adjust the direction and speed in the editor or through the gdscript of the Sprite, by using

material.set_shader_param("direction", Vector2(0.0,1.0))
material.set_shader_param("speed_scale",0.02)

Hope this helps

+5 votes

The parallax nodes makes infinite backgrounds really easy.

Add these three nodes to your background scene:

ParallaxBackground
--┖╴ParallaxLayer
---- ┖╴Sprite

Then add your background image to the sprite.
On the parallaxLayer node set the mirroring x and y to the dimensions of your background image.

the background will keep up with the camera, so however you move the camera the background will be handled automatically.

if you are building something like a title screen, without a camera node, then you can handle the scroll manually.

constantly move the background to the right:

extends ParallaxBackground

func _process(delta):
    scroll_offset.x += 1000 * delta

or move the background in a circle:

extends ParallaxBackground

export(int) var speed: int = 1000
export(float) var rotation_speed = 0.4

var direction = Vector2(1, 0)

func _process(delta):
    scroll_offset += direction * speed * delta
    direction = direction.rotated(rotation_speed * delta)

You might need to import the image with repeat enabled.

by (24 points)

Thanks, this worked perfectly and feels like an elegant, easily customizable and Godot-y solution!

Wow, thank you. I think this is the intended way of doing it, and should be the answer to this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.