Zooming in in viewport

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.
Post Reply
Message
Author
User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
Joined: Wed Nov 23, 2011 5:30 pm
Completed: Don't Look (AGS game)
Projects: KANPEKI! ★Perfect Play★
Organization: Crappy White Wings
Location: Germany
Contact:

Zooming in in viewport

#1 Post by Milkymalk »

Hi, I have this problem I just can't seem to solve.

I want to show a map in a viewport. When it appears, it starts zoomed out to be entirely visible. Then, after a short delay, it should zoom in to the player's location on the map.

The problem here is that I have no idea how to do all the zooming and waiting outside of the image declaration.

I have this:

Code: Select all

init python:
    mapxsize = 5000
    mapysize = 4406
    mapfactor = float(config.screen_height)/ mapysize
    dummypos = (2100, 1700)

image mapsheet:
    "map.jpg"
    zoom mapfactor
    pause 3.0
    ease 1.0 crop (a, b, config.screen_width, config.screen_height) 

screen mapscreen:
    viewport id "worldmap":
        draggable True
        edgescroll (50, 500)
        add "mapsheet" at truecenter

label start:
    "Let's start!"
    $ a = max(0, min(dummypos[0]-(config.screen_width/2), mapxsize-config.screen_width))
    $ b = max(0, min(dummypos[1]-(config.screen_height/2), mapysize-config.screen_height))
    call screen mapscreen
    return
Which works *almost* fine, except that it starts the image's last line "ease 1.0 crop" from (0, 0, 0, 0) instead from what is shown at the moment.

Then there's the problem that I don't really want a cropped image, I want the full image inside the viewport for scrolling. So I was thinking of cheating by exchanging the cropped image with the full image scrolled to the right position after the zooming is done, but it feels overly complicated and I'm sure there is a better way to do this.

Also, I would be grateful if someone could explain to me how to move the variables a and b to the screen and out of the general script.
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
Joined: Wed Nov 23, 2011 5:30 pm
Completed: Don't Look (AGS game)
Projects: KANPEKI! ★Perfect Play★
Organization: Crappy White Wings
Location: Germany
Contact:

Re: Zooming in in viewport

#2 Post by Milkymalk »

I fiddled around and now have this:

Code: Select all

init python:
    mapxsize = 5000
    mapysize = 4406
    mapfactor = float(config.screen_height)/ mapysize
    dummypos = (2100, 1700)

image mapsheet:
    "map.jpg"

transform mapzoom:
    xalign 0.5
    yalign 0.5
    zoom mapfactor
    pause 3.0
    ease 5.0 zoom 1.0
    
    
screen mapscreen(x, y):
    viewport id "worldmap":
        draggable True
        edgescroll (50, 500)
        xinitial x
        yinitial x
        add "mapsheet" at mapzoom

                   
# The game starts here.
label start:
    $ a = max(0, min(dummypos[0]-(config.screen_width/2), mapxsize-config.screen_width))
    $ b = max(0, min(dummypos[1]-(config.screen_height/2), mapysize-config.screen_height))
    e "You've created a new Ren'Py game."
    call screen mapscreen(a, b)

    return
The viewport now zooms in to the right spot, but on the way there it jumps wildly around because it seems it tries to keep the exact initial coordinates in its focus, which are of course off-image at first because the image is zoomed out, and as it's zoomed in and becomes large enough to have those coordinates the viewport moves there, resulting in awkward movement instead of zooming straight onto that spot.
Using floats as initials only makes it zoom to (0, 0).

My next idea was to make the initials dynamic:

Code: Select all

init python:
    mapxsize = 5000
    mapysize = 4406
    mapfactor = float(config.screen_height)/ mapysize
    dummypos = (2100, 1700)

    def dynamicinitial(a):
        bounds = renpy.get_image_bounds("mapsheet", layer='screens')
        if a == 0:
            return bounds[2]
        else:
            return bounds[3]
    
image mapsheet:
    "map.jpg"
    subpixel True

transform mapzoom:
    zoom mapfactor
    pause 3.0
    ease 5.0 zoom 1.0
            
screen mapscreen(x, y):
    viewport id "worldmap":
        draggable True
        edgescroll (50, 500)
        add "mapsheet" at mapzoom
        xinitial dynamicinitial(0)
        yinitial dynamicinitial(1)

label start:
    $ a = max(0, min(dummypos[0]-(config.screen_width/2), mapxsize-config.screen_width))
    $ b = max(0, min(dummypos[1]-(config.screen_height/2), mapysize-config.screen_height))
    e "You've created a new Ren'Py game."
    call screen mapscreen(a, b)

    return
But whatever I do, I always get "None" returned from renpy.get_image_bounds. The image doesn't seem to exist on any layer.

I tried currying the function:

Code: Select all

screen mapscreen(x, y):
    $ curryinitial = renpy.curry(dynamicinitial)
    viewport id "worldmap":
        draggable True
        edgescroll (50, 500)
        add "mapsheet" at mapzoom
        xinitial curryinitial(0)
        yinitial curryinitial(1)
But this gives me this error:
While running game code:
File "game/script.rpy", line 50, in script
call screen mapscreen(a, b)
File "renpy/common/000statements.rpy", line 426, in execute_call_screen
store._return = renpy.call_screen(name, *args, **kwargs)
TypeError: unsupported operand type(s) for *: 'int' and 'Curry'
Different question: Can I put condition switches into a transform? Like so:

Code: Select all

transform mapzoom(x=-1, y=-1):
    xalign 0.5
    yalign 0.5
    zoom mapfactor
    if x, y >= 0:
        pause 3.0
        ease 1.0 zoom 1.0 xalign x yalign y 
If I do this, I get an indentation error for "pause 3.0" instead.

So please, if anybody can help me here I would be very happy. As you can see, I already tried a lot of things and nothing worked.
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
Joined: Wed Nov 23, 2011 5:30 pm
Completed: Don't Look (AGS game)
Projects: KANPEKI! ★Perfect Play★
Organization: Crappy White Wings
Location: Germany
Contact:

Re: Zooming in in viewport

#3 Post by Milkymalk »

I figured it out!

I had to use child_size and a hbox to make the viewport canvas as big as the zoomed in map, then place the zoomed out map so that it aligns with the screen edges. Then, as it zooms in, I slide the map's position over so the desired spot stays in the center:

Code: Select all

init python:
    mapsize = (5000, 4406)
    mapfactor = float(config.screen_height)/ mapsize[1]
    dummypos = (2100, 1700)

image mapsheet:
    "map.jpg"
    subpixel True

transform mapzoom(x, y):
    xpos x+config.screen_width/2
    ypos y+config.screen_height/2
    xanchor 0.5
    yanchor 0.5
    zoom mapfactor
    pause 3.0
    ease 1.5 zoom 1.0 xpos mapsize[0]/2 ypos mapsize[1]/2
            
screen mapscreen(x, y):
    $ a = max(0, min(x-(config.screen_width/2), mapsize[0]-config.screen_width))
    $ b = max(0, min(y-(config.screen_height/2), mapsize[1]-config.screen_height))
    viewport id "worldmap":
        child_size (5000, 4406)
        draggable True
        edgescroll (50, 500)
        hbox:
            xsize mapsize[0]
            ysize mapsize[1]
        add "mapsheet" at mapzoom(a, b)
        xinitial a
        yinitial b

label start:
    "Click to zoom the map."
    call screen mapscreen(dummypos[0], dummypos[1])

    return
    
    
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

Post Reply

Who is online

Users browsing this forum: Imperf3kt