godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.15k stars 21.19k forks source link

Possibility to cherry pick ParallaxBackground-Zoom bugfix to godot 2 #16324

Closed Ranoller closed 6 years ago

Ranoller commented 6 years ago

This is the bugfix: #12421 Was fixed in Godot 3. Bug still present in Godot 2.

wombatwingdings commented 6 years ago

Hi,

I wanted this too. I decided to write my own in gdscript. Here it is if you want to use it.

To use, you need to position your tilemap (if you're using one) into the negative Y axis. It goes funny if it's trying to draw a bit in the positive and a bit in the negative.

You need to create 4 * Sprites and place them in zorder -1. Set your repeating image in all 4. Make one visible ("PlxSprite") and hide the others, but show them in _ready() like this:

    get_node("maze/PlxSprite1").show()
    get_node("maze/PlxSprite2").show()
    get_node("maze/PlxSprite3").show()

const PARALLAX = 1.2      # moves 1.2 times slower than foreground

func ParallaxSprite():
    var s = get_node("maze/PlxSprite")
    var camnode = get_node("camera")
    var campos = camnode.get_camera_position() # returns centre of camera
    campos -= camnode.get_viewport_rect().size / 2 

    var picsize = s.get_texture().get_size()

    # the parallax goes funny when y or x is positive.
    var ybase = int(abs(campos.y)/(picsize.y*PARALLAX)) *(picsize.y*PARALLAX)
    var yfiller = picsize.y*PARALLAX - picsize.y
    var ypcent = ( abs(campos.y) - ybase ) / (picsize.y*PARALLAX)
    var yfillerOff = yfiller * ypcent

    var xbase = int(abs(campos.x)/(picsize.x*PARALLAX)) *(picsize.x*PARALLAX)
    var xfiller = picsize.x*PARALLAX - picsize.x
    var xpcent = ( abs(campos.x) - xbase ) / (picsize.x*PARALLAX)
    var xfillerOff = xfiller * xpcent

    var x = xbase+xfillerOff
    var y = -(ybase+yfillerOff)
    s.set_position(Vector2(x, y))

    get_node("maze/PlxSprite1").set_position(Vector2(x,y-picsize.y))
    get_node("maze/PlxSprite2").set_position(Vector2(x+picsize.x,y))
    get_node("maze/PlxSprite3").set_position(Vector2(x+picsize.x,y-picsize.y))

Call it from your _fixed_process() or whatever.

Have fun!

WombatWingdings

Ranoller commented 6 years ago

Thanks for the code, good workaround. For complex scenaries this can be crazy!!! I hope that some c++ coder want to backport the fix to have working native paralax-backgrounds.

akien-mga commented 6 years ago

If someone can cherry-pick it (with the later regression fixes..) without breaking compatibility for existin 2.1 projects, why not. If it changes the behaviour for existing projects, then it can't be backported at this stage in 2.1 (people should be able to upgrade to 2.1.5 without breaking their games).

Ranoller commented 6 years ago

I´m sure that nobody is using zoom with parallax backgrounds natively in godot2... because behavior is weird. All bug fixes can break compatibility with projects than uses a bug in their favor (not really breaking compatibility, only change behavior)... but hey, I respect that (although this rule does not always apply to bugs in the development of godot).

Ranoller commented 6 years ago

Accomplished by #16795 . Thanks!!!!