[SOLVED] Viewport is changing my adjustments range

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Message
Author
ijffdrie
Regular
Posts: 32
Joined: Mon Apr 13, 2020 1:11 pm
itch: pink-productions
Contact:

[SOLVED] Viewport is changing my adjustments range

#1 Post by ijffdrie »

Good day, everyone.

I've been working on creating a setup that takes maps and tilesets defined in Tiled, and portrays them as navigable maps in a 3/4 perspective in Ren'py. The player character is portrayed as a sprite on the map, and is controlled by the keyboard, with the camera following the player's sprite around (eventually to be expanded with the ability to follow other things for cutscenes and such). The camera tries to keep the player centered, except when it is bounded by the edges of the map. Essentially, think of how old Pokemon or RPGMaker games are set up.

However, I've been having some issues getting the viewport to function properly. First, the code in question:

The label by which I transition to a map. Start_coord and map must be set before calling the call_map label:

Code: Select all

label call_map:
    $ player_sprite = RPGPlayerSprite()
    $ player_sprite.set_location(start_coord.x, start_coord.y)
    $ map.load_movement_map()
    $ camera = Camera(map)
    call screen rpg_map(map)
The map screen:

Code: Select all

screen rpg_map(map):
    viewport id "rpg_map_view":
        xadjustment camera.x
        yadjustment camera.y

        frame:
            background None

            for layer_key in sorted(map.layers):
                $ map_layer = map.layers[layer_key]
                frame:
                    background None
                    pos map_layer.offset
                    $ tile_y_coord = 0
                    for tile_row in map_layer.data:
                        $ tile_x_coord = 0
                        for tile in tile_row:
                            $ tile_img = tile.image
                            add tile_img pos (tile_x_coord, tile_y_coord)

                            $ tile_x_coord += map.tile_size.x
                        $ tile_y_coord += map.tile_size.y

            add player_sprite
the camera class, as defined in init python. The player sprite calls the camera's center_on_location() function as part of its render function:

Code: Select all

class Camera:
        def __init__(self, set_map):
            self.map = set_map
            self.x = renpy.display.behavior.Adjustment(value=0, range=self.map.image_size.x)
            self.y = renpy.display.behavior.Adjustment(value=0, range=self.map.image_size.y)

        def center_on_location(self, player_x, player_y):
            max_x = map.image_size.x - config.screen_width + 8
            centered_x = player_x - (config.screen_width / 2) + (map.tile_size.x / 2)
            final_x = max(min(max_x, centered_x), 0)
            self.x.change(final_x)

            max_y = (map.image_size.y - config.screen_height) + 8
            centered_y = player_y - (config.screen_height / 2) + (map.tile_size.y / 2)
            final_y = max(min(max_y, centered_y), 0)
            self.y.change(final_y)
This code doesn't work, with the camera not moving along with the player character at all. However, oddly enough, when I added scrollbars "both" to the viewport, it suddenly did work (though, since I'd rather not have scrollbars present, I can't settle for this workaround). After playing around with the console a bit to try and solve this, I figured out that, whenever the viewport is supposed to move, the range of the adjustment objects changes. The range for my test map is 1280 for both the x and y axes. If the scrollbars "both" line is present, the range changes to 31499 for the x axis and 32059 for the y axis. If that line is not present, it changes to 0 for both axes (hence the camera never moving).

Obviously, I'm doing something wrong here, but I can't for the life of me figure out what.
Last edited by ijffdrie on Fri Apr 17, 2020 11:47 am, edited 1 time in total.

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Problem: Viewport is changing my adjustments range

#2 Post by Alex »

Try to add 'draggable' property for the viewport, and just a simple variables to store viewport's adjustments - viewtopic.php?f=8&t=58441#p526802

ijffdrie
Regular
Posts: 32
Joined: Mon Apr 13, 2020 1:11 pm
itch: pink-productions
Contact:

Re: Problem: Viewport is changing my adjustments range

#3 Post by ijffdrie »

Alex wrote: Mon Apr 13, 2020 4:39 pm Try to add 'draggable' property for the viewport, and just a simple variables to store viewport's adjustments - viewtopic.php?f=8&t=58441#p526802
Implemented the suggested changes, but the behavior is unchanged; without bars, the viewport's adjustments ranges change to 0, and it won't move.

Code: Select all

label call_map:
    $ player_sprite = RPGPlayerSprite()
    $ player_sprite.set_location(start_coord.x, start_coord.y)
    $ map.load_movement_map()
    $ camera = Camera(map)
    $ camera_x = ui.adjustment(value=0, range=map.image_size.x)
    $ camera_y = ui.adjustment(value=0, range=map.image_size.y)
    call screen rpg_map(map)

[code]    class Camera:
        def __init__(self, set_map):
            self.map = set_map

        def center_on_location(self, player_x, player_y):
            max_x = map.image_size.x - config.screen_width + 8
            centered_x = player_x - (config.screen_width / 2) + (map.tile_size.x / 2)
            final_x = max(min(max_x, centered_x), 0)
            camera_x.change(final_x)

            max_y = (map.image_size.y - config.screen_height) + 8
            centered_y = player_y - (config.screen_height / 2) + (map.tile_size.y / 2)
            final_y = max(min(max_y, centered_y), 0)
            camera_y.change(final_y)

Code: Select all

screen rpg_map(map):
    viewport id "rpg_map_view":
        draggable True
        xadjustment camera_x
        yadjustment camera_y

        frame:
            background None

            for layer_key in sorted(map.layers):
                $ map_layer = map.layers[layer_key]
                frame:
                    background None
                    pos map_layer.offset
                    $ tile_y_coord = 0
                    for tile_row in map_layer.data:
                        $ tile_x_coord = 0
                        for tile in tile_row:
                            $ tile_img = tile.image
                            add tile_img pos (tile_x_coord, tile_y_coord)

                            $ tile_x_coord += map.tile_size.x
                        $ tile_y_coord += map.tile_size.y

            add player_sprite

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Problem: Viewport is changing my adjustments range

#4 Post by Alex »

Try not to set value and range for adjustment - let the viewport do it

Code: Select all

$ camera_x = ui.adjustment()

ijffdrie
Regular
Posts: 32
Joined: Mon Apr 13, 2020 1:11 pm
itch: pink-productions
Contact:

Re: Problem: Viewport is changing my adjustments range

#5 Post by ijffdrie »

Alex wrote: Mon Apr 13, 2020 5:55 pm Try not to set value and range for adjustment - let the viewport do it

Code: Select all

$ camera_x = ui.adjustment()
Results are identical. No movement without scrollbars "both"

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Problem: Viewport is changing my adjustments range

#6 Post by Alex »

ijffdrie wrote: Mon Apr 13, 2020 6:02 pm Results are identical. No movement without scrollbars "both"
This might happened 'cause you didn't limit the viewport's visible area, so its whole content is shown and theres no need to scroll it.
Try to put your viewport inside a 'side' layout (the way it made in docs and my sample).

"scrollbars
...If scrollbars is not None, the viewport takes properties prefixed with "side". These are passed to the created side layout." - https://www.renpy.org/doc/html/screens.html#viewport

https://www.renpy.org/doc/html/screens.html#side

ijffdrie
Regular
Posts: 32
Joined: Mon Apr 13, 2020 1:11 pm
itch: pink-productions
Contact:

Re: Problem: Viewport is changing my adjustments range

#7 Post by ijffdrie »

I tried adding the "side" statement and a couple of different options for areas, but it still doesn't seem to be working without the scrollbars. Current code is

Code: Select all

screen rpg_map(map):
    side "c":
        area (0, 0, config.screen_width, config.screen_height)
        viewport id "map_viewport":
            xadjustment camera_x
            yadjustment camera_y
            draggable True 

            frame:
                background None

                for layer_key in sorted(map.layers):
                    $ map_layer = map.layers[layer_key]
                    frame:
                        background None
                        pos map_layer.offset
                        $ tile_y_coord = 0
                        for tile_row in map_layer.data:
                            $ tile_x_coord = 0
                            for tile in tile_row:
                                if tile is not None:  # Some tiles are empty, this skips over those.
                                    $ tile_img = tile.image
                                    add tile_img pos (tile_x_coord, tile_y_coord)

                                $ tile_x_coord += map.tile_size.x
                            $ tile_y_coord += map.tile_size.y
                add player_sprite

Code: Select all

label call_map:
    $ player_sprite = RPGPlayerSprite()
    $ player_sprite.set_location(start_coord.x, start_coord.y)
    $ map.load_movement_map()
    $ camera = Camera(map)
    $ camera_x = ui.adjustment()
    $ camera_y = ui.adjustment()
    call screen rpg_map(map)

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Problem: Viewport is changing my adjustments range

#8 Post by Alex »

Got no ideas why it works with scrollbars and not without them...
For test purposes you could put back frame's backgrounds to see their actual sizes.

Looks like you want to show a map made of tiles. If they are all the same size try to show them in a grid, so you don't need all the offset calculations - viewtopic.php?f=8&t=55947&p=514658#p514658.


You can put each layer in its own viewport and use the same adjustments to make all them move simultaneously.

Code: Select all

screen vp_scr():
    frame:
        align(0.5, 0.5)
        side "c":# b r":
            area (0, 0, 200, 200)

            viewport id "my_vp":
                draggable True
                xadjustment my_x_adj
                yadjustment my_y_adj

                vbox:
                    hbox:
                        add Solid("#ccc"):
                            size(200, 200)
                        add Solid("#fff"):
                            size(200, 200)
                        add Solid("#ccc"):
                            size(200, 200)
                    hbox:
                        add Solid("#fff"):
                            size(200, 200)
                        add Solid("#ccc"):
                            size(200, 200)
                        add Solid("#fff"):
                            size(200, 200)
                            
            #bar value XScrollValue("my_vp")
            #vbar value YScrollValue("my_vp")
                            
    frame:
        background None
        align(0.5, 0.5)
        side "c":# b r":
            area (0, 0, 200, 200)

            viewport id "my_vp_2":
                draggable True
                xadjustment my_x_adj # same vars
                yadjustment my_y_adj  
                vbox:
                    at transform:
                        alpha 0.0
                        linear 2.5 alpha 0.2
                        linear 2.5 alpha 0.0
                        repeat
                    hbox:
                        add Solid("#c0c"):
                            size(200, 200)
                        add Solid("#0f0"):
                            size(200, 200)
                        add Solid("#c0c"):
                            size(200, 200)
                    hbox:
                        add Solid("#0f0"):
                            size(200, 200)
                        add Solid("#c0c"):
                            size(200, 200)
                        add Solid("#0f0"):
                            size(200, 200)
                                 

            
            #bar value XScrollValue("my_vp_2")
            #vbar value YScrollValue("my_vp_2")

label start:
    $ my_x_adj = ui.adjustment()
    $ my_y_adj = ui.adjustment()
    
    "..."
    show screen vp_scr
    "... ..."
    hide screen vp_scr
    "... ... ..."
    show screen vp_scr
    "?!"

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Problem: Viewport is changing my adjustments range

#9 Post by Remix »

When I did a viewport movement through code thing, I did:

Basic viewport with no adjustment settings, no scrollbars, no XScrollValues etc

Code: Select all

screen vp_screen:

    fixed:

        viewport:
            id "vp_id"
            area (10, 10, 1260, 700)

            draggable True
            scrollbars None

            ### Content
Then to address the viewport and adjust the position:

vp = renpy.get_widget('vp_screen', 'vp_id') ## the viewport widget

vp.yadjustment.change(2500) ## alter y adjustment to be 2500 pixels
Frameworks & Scriptlets:

ijffdrie
Regular
Posts: 32
Joined: Mon Apr 13, 2020 1:11 pm
itch: pink-productions
Contact:

Re: Problem: Viewport is changing my adjustments range

#10 Post by ijffdrie »

Code: Select all

class Camera:
        def center_on_location(self, player_x, player_y):
            max_x = rpg_current_map.image_size.x - config.screen_width + 8
            centered_x = player_x - (config.screen_width / 2) + (rpg_current_map.tile_size.x / 2)
            final_x = max(min(max_x, centered_x), 0)
            x = final_x

            max_y = (rpg_current_map.image_size.y - config.screen_height) + 8
            centered_y = player_y - (config.screen_height / 2) + (rpg_current_map.tile_size.y / 2)
            final_y = max(min(max_y, centered_y), 0)
            y = final_y

            vp = renpy.get_widget('rpg_map', 'map_viewport')
            vp.xadjustment.change(x)
            vp.yadjustment.change(y)

Code: Select all

screen rpg_map:
    fixed:
        viewport:
            scrollbars None
            draggable True
            id "map_viewport"
            area (0, 0, config.screen_width, config.screen_height)

            frame:
                background None

                for layer_key in sorted(rpg_current_map.layers):
                    $ map_layer = rpg_current_map.layers[layer_key]
                    frame:
                        background None
                        pos map_layer.offset
                        if type(map_layer) is MapLayerTile:
                            $ tile_y_coord = 0
                            for tile_row in map_layer.data:
                                $ tile_x_coord = 0
                                for tile in tile_row:
                                    if tile is not None: # Some tiles are empty, this skips over those.
                                        $ tile_img = tile.image
                                        add tile_img pos (tile_x_coord, tile_y_coord)

                                    $ tile_x_coord += rpg_current_map.tile_size.x
                                $ tile_y_coord += rpg_current_map.tile_size.y
                        elif type(map_layer) is MapLayerObject:
                            for layer_object in map_layer.data:
                                $ object_x_coord = layer_object.x
                                $ object_y_coord = layer_object.y
                                $ object_img = layer_object.image
                                add object_img pos (object_x_coord, object_y_coord)
                add player_sprite
Sadly, this still doesn't work. However, interestingly, it still doesn't work, no matter what I try. Never any result without scrollbars. I even tried just assigning entirely new adjustments with every change of the camera. Considering similar solutions worked for you guys, but not for me, there must be something elsewhere in my code or maybe even my setup that's somehow interfering with the viewport positioning.
Looks like you want to show a map made of tiles. If they are all the same size try to show them in a grid, so you don't need all the offset calculations - viewtopic.php?f=8&t=55947&p=514658#p514658.
A grid would be a better implementation of that code as it was, but it's not suitable for what I'm building towards. Essentially, what I'm trying to do is build an engine that allows for using RPGMaker-style maps in Ren'py games, using Tiled as an editor, and offering some additional options. Among the additional options is using tileset sprites that diverge from the grid size.

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Problem: Viewport is changing my adjustments range

#11 Post by Alex »

ijffdrie wrote: Thu Apr 16, 2020 1:49 pm ... there must be something elsewhere in my code or maybe even my setup that's somehow interfering with the viewport positioning.
Try to get rid of position calculations - put your map in a grid or v/hboxes. I've got issues when tried to calculat individual positions of tiles. Looks like it makes the whole map to be in a 'fixed' container untill you specify to use scrollbars that makes the whole thing use a 'side' container.

ijffdrie
Regular
Posts: 32
Joined: Mon Apr 13, 2020 1:11 pm
itch: pink-productions
Contact:

Re: Problem: Viewport is changing my adjustments range

#12 Post by ijffdrie »

Already tried to see if the problem was with that section. The issue remained even when I commented it out entirely, leaving only the player_sprite in the frame.


edit: I've now also tried leaving out the player_sprite but leaving the background (and making that draggable, rather than having the player_sprite react to key_press events), to see if the issue was with that part. No dice.

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Problem: Viewport is changing my adjustments range

#13 Post by Alex »

Code: Select all

screen rpg_map:
    fixed:
        viewport:
            scrollbars None
            draggable True
            id "map_viewport"
            area (0, 0, config.screen_width, config.screen_height)
You still use 'fixed'... try

Code: Select all

screen rpg_map:
    side "c":# b r":
        area (0, 0, config.screen_width, config.screen_height)
        viewport:
            scrollbars None
            draggable True
            id "map_viewport"

ijffdrie
Regular
Posts: 32
Joined: Mon Apr 13, 2020 1:11 pm
itch: pink-productions
Contact:

Re: Problem: Viewport is changing my adjustments range

#14 Post by ijffdrie »

Outcome doesn't change depending on having a side instead of a fixed. I also tried it with the section that places the map tiles commented out, to no effect.

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Problem: Viewport is changing my adjustments range

#15 Post by Remix »

I presume you have checked all your positional math?
The values you pass into the change() methods are correct and are integers?
Try changing the function to use hard values as a test... vp.xadjustment.change(600)

You could also explicitly set the viewport childsize to make sure that isn't a factor.

Not easy to help further as I do not have similar code to play with.
All I know is the snippet I provided works fine here for a large composite inside viewport.
Frameworks & Scriptlets:

Post Reply

Who is online

Users browsing this forum: Google [Bot]