Animate a line2D sprite

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By matti0006

I am currently creating a game where I want my player to shoot a laser, which I implemented as a Line2D.
I am using a sprite that repeats (as a tile):
laser_sprite

I can accomplish this quite simply by importing the texture as ‘Repeating’ and then giving the Line2D an ImageTexture

What I would like to do, however, is change the sprite every frame, by ‘looping’ the sprite 1 pixel, to make it seem like the laser is flowing. What I mean is that on frame 1 I have the following sprite:
laser_sprite
While on frame 2 I have:
laser_sprite
It’s probably hard to see, but the second image has the righternmost column of image 1 removed and added as its first column. This process then repeats 64 times (as my laser tile is 64 pixels wide)

I have tried giving the Line2D an AtlasTexture, then give that an ImageTexture. This ImageTexture contains all the frames I want to use as a spritesheet. Then, in code, I try and update the Region property of the AtlasTexture. However, it seems Line2D doesn’t allow this behavior, as the sprite doesn’t change.

Any ideas on how to approach this?

:bust_in_silhouette: Reply From: p7f

You could add an AnimationPlayer and change the frames. However, if all frames are the same but displaced one pixel, and they are in repeate mode, you may better use a simple shader:

shader_type canvas_item;

void fragment(){
    COLOR = texture(TEXTURE, vec2(UV.x + TIME, UV.y));
}

Note, just use the first frame, with repeat mode enabled, and this shader.

Thanks, this is great stuff.

First time I’ve seen a shader used, I’d like to understand what the code actually does. Here’s my current understanding:

fragment automatically runs for every pixel on every frame.
Within fragment, we update the COLOR value of each pixel.
To do this, we find the desired pixel in the sprite TEXTURE using texture, why does this return a color?

The second parameter of texture is the desired pixel, UV is the coords of the current pixel, and because we have repeat mode on, we can get away with UV.x + TIME without adding a modulo operation?

Thanks again for the help!

matti0006 | 2020-07-29 20:56

First, is partially correct. The fragment function runs for each “fragment” of the canvas item. A texture may be 16x16 pixels, but OpenGL interpolates and you may end up with many fragments per pixel. COLOR is just the output of the fragment function, you must put there the color you want that fragment have. The funxtion texture is a function used to retrieve the color of a given sampler2d (in short, the type for textures in OpenGL) and given some coordinates. UV are those coords, but have in mind that they go from 0 to 1 in both axis (so modulo wont work). Thats why they are called “UV” instead of “XY”. Its just a linear transformation of xy axis.

p7f | 2020-07-29 22:01