Changing a Viewport's Image

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
DesertFox
Regular
Posts: 196
Joined: Sun Jul 28, 2013 1:29 pm
Completed: Over The Hills And Far Away
Projects: My Little Dictator
Organization: WarGirl Games
Contact:

Changing a Viewport's Image

#1 Post by DesertFox »

I'm trying to implement two buttons (or just one toggle button) that will change the add "map1" to another image.

Code: Select all

screen viewport1():
    modal True
    style_group "actual_map"
    xalign 0.0
    viewport id "vp":
        edgescroll (100, 200)
        xmaximum 1055
        ymaximum 768
        draggable False
        mousewheel True
        child_size (2000, 1777)
        add "map1"

screen map1toggle:
    hbox:
        xalign 0.65
        yalign 0.9
        textbutton _("{b}GEOGRAPHIC{/b}") action .....
        null width 10
        textbutton _("{b}POLITICAL{/b}") action ......      

screen mapchoice1():
    $ config.rollback_enabled=False
    add "gui/unit_selection_background.png"
    tag menu
    use viewport1
    use map1toggle
Any ideas how to implement something like this?
I'm certain this is probably simple as anything but my brain's just not working on this.

User avatar
PyTom
Ren'Py Creator
Posts: 16088
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: Changing a Viewport's Image

#2 Post by PyTom »

Since you pass a lot of data around, let's use an object to store it in.

Code: Select all

init python:
    class ScreenData(object):
        def __init__(self):
            self.map = "geographic"

screen viewport1(data):
    viewport id "vp":
        style_group "actual_map"
        edgescroll (100, 200)
        xmaximum 1055
        ymaximum 768
        draggable False
        mousewheel True
        child_size (2000, 1777)
        add (data.map + ".png")

screen map1toggle(data):
    hbox:
        xalign 0.65
        yalign 0.9
        textbutton _("{b}GEOGRAPHIC{/b}") action SetField(data, "map", "geographic")
        null width 10
        textbutton _("{b}POLITICAL{/b}") action SetField(data, "map", "political")      

screen mapchoice1(data):
    add "gui/unit_selection_background.png"
    use viewport1(data)
    use map1toggle(data)

label start:
     $ data = ScreenData()
     
     "Where do you want to go?"

     $ _rollback = False
     call screen mapchoice1(data)
     $ _rollback = True
The object provides a nice namespace that lets you easily pass data around from one part of the game to another. SetField lets you set fields on the object. The object's data is initialized by its __init__ method.

Some other notes:

"modal True" in the viewport1 screen doesn't do anything. Modal only works in the screen that's actually shown, which I assume is mapchoice1.

xalign 0.0 and style_group "actual_map" don't do anything where they are. They have to be applied to a displayable. I'm surprised this even compiles.

Unless I don't understand something, "tag menu" isn't necessary. It's used to have the various game-menu screens replace each other, which is unlikely to be what you want here.
screen mapchoice1():
$ config.rollback_enabled=False
Is something a horrible person would write. Config variables should not be changed outside of init blocks. It's doubly bad because python code in screens isn't allowed to have side effects, since such code can be run when a screen is predicted. The result is that you will disable rollback at completely random times - not what you want.

As some bonus advice, in my - untested - code, I wrote:

Code: Select all

     $ data = ScreenData()
     
     "Where do you want to go?"

      # intentionally omitted as unimportant.
     call screen mapchoice1(data)
This sets up the data for the screens a few statements in advance. This lets the prediction system understand the screen as it's about to be shown to the player, and gives its time to pull in any images required. If you did:

Code: Select all

     "Where do you want to go?"

     $ data = ScreenData()
     
     call screen mapchoice1(data)
The more obvious approach, data wouldn't be defined in time for screen prediction to occur. (Ren'Py will still have a go at it, but the predicition will be a lot less accurate.)
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

DesertFox
Regular
Posts: 196
Joined: Sun Jul 28, 2013 1:29 pm
Completed: Over The Hills And Far Away
Projects: My Little Dictator
Organization: WarGirl Games
Contact:

Re: Changing a Viewport's Image

#3 Post by DesertFox »

Thank you for providing that and explaining through it, that works perfectly! :D

Quick question - when it comes to having many variations for different screens (so mapchoice2, involving geographic2 and political2 etc. and so on) will I need to redefine self.map within init python, or is there a variable I should use?

I guess my coding was a little messy. I wasn't aware that 'style_groups' had to be within displayables. I thought they applied to a screen as a whole. I'll have to have some decent testers go through it with a fine tooth comb once I've got a working version together.

It's useful to see the parameter lists at work too :)

User avatar
PyTom
Ren'Py Creator
Posts: 16088
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: Changing a Viewport's Image

#4 Post by PyTom »

You could, for example, have:

Code: Select all

init python:
    class ScreenData(object):
        def __init__(self, geographic_map, political_map):
            self.geographic_map = geographic_map
            self.political_map = political_map
            self.map = geographic_map

# ...

        textbutton _("{b}GEOGRAPHIC{/b}") action SetField(data, "map", data.geographic_map)
        null width 10
        textbutton _("{b}POLITICAL{/b}") action SetField(data, "map", data.political_map)      

# ...

     $ data = ScreenData("geo7", "pol7")
     
     "Where do you want to go?"

      # intentionally omitted as unimportant.
     call screen mapchoice1(data)
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

DesertFox
Regular
Posts: 196
Joined: Sun Jul 28, 2013 1:29 pm
Completed: Over The Hills And Far Away
Projects: My Little Dictator
Organization: WarGirl Games
Contact:

Re: Changing a Viewport's Image

#5 Post by DesertFox »

That works brilliantly! Thank you :D

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Kocker