buttons actions, navigation and game flow issues [SOLVED]

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
oskigrn
Newbie
Posts: 9
Joined: Thu Aug 23, 2018 1:03 pm
Contact:

buttons actions, navigation and game flow issues [SOLVED]

#1 Post by oskigrn »

Hi everyone,

I'm having some issues trying to implement a simple navigation system for my game. I've partially solved but I want to know what is wrong done in any case in order to understand how renpy works.

This is my goal: I want to have the current location of the player stored in a variable of the player object which always contains a string with the name of an screen, and everytime the user clicks on a navigation button just hide the current location screen, change the current location variable and show the 'new' current location screen with the new value. I've tried like this:

Code: Select all

init python:
    class cl_player:
        def __init__(self, fname, lname):
            self.fname = fname
            self.lname = lname
            self.current_location = "home"

label start:
   call create_player

label create_player:
    $ player = cl_player("TestFirstName", "TestLastName")
    return

imagebutton:
    auto "gui/quick_map_%s.png"
    action [Hide(player.current_location), SetVariable(player.current_location, "map"), Show(player.current_location),]

# Every location has obviously their own screen with modal True
Like this, the first action of the imagebutton works fine but not the second. For some reason the SetVariable statement don't crashes the game but don't changes the variable value either, and after that, obviously the new screen is not shown.

I've tried to use a global variable instead of an object one, like this:

Code: Select all

label start:
   $ current_location = "home"

imagebutton:
    auto "gui/quick_map_%s.png"
    action action [Hide(current_location), SetVariable("current_location", "map"), Show(current_location)]
In this case, surprinsingly, the second action actually works, but not the third. The variable value is changed but the new location screen is not shown. So, I've just set the new screen manually:

Code: Select all

imagebutton:
    auto "gui/quick_map_%s.png"
    action action [Hide(current_location), SetVariable("current_location", "map"), Show("map")]
This work fine, finally, and solved the issue. But I really would preffer to be able to work with variables instead of manual text and specially with the object variable because it will be more convenent when the game gains complexity.

So, these are the two most imortant questions:
First one, Why in the first case the variable value change works on a global variable but not on an object one?
and, Second one, why in the second case the third action doesn't work as the variable value has not been changed?

I've already tried to other aproaches to solve the problem. The first one using a python action to change the player.current_position value:

Code: Select all

init python:
    def setCurrentLocation(Location):
         player.current_location = Location

imagebutton:
    auto "gui/quick_map_%s.png"
    action [Hide(player.current_location), Call(setCurrentLocation("map")), Show("map"),]
I still don't know how to use python, so probably there are sintaxys mistakes but the strange part is that the python action is executed few clicks before the button is even shown and for sure not clicked.

So, the third question: How I should use the python action? and most important, why is executed before clicking the button?

The third approach I've tried is using a renpy label:

Code: Select all

label setCurrentLocationLabel (loc):
    $ player.current_location = loc
    return "nothing"

imagebutton:
    auto "gui/quick_map_%s.png"
    action [Hide(player.current_location), Call("setCurrentLocationLabel", "map"), Show("map"),]
In this case the first two actions work well but the third is not executed. Seems like once I get out the action tuple I cannot get back in.

I could invert the action list like [Hide(player.current_location), Show("map"), Call("setCurrentLocationLabel", "map"),] and probably works but it's not like I want to do it, my goal was, hide, change and show in that especific order.

So, forth question, Do you see what I'm doing wrong here? It is posible to get back to the action list once you've called a label? Maybe is something related with the return clause?

I know is a large post, so thank you very much in advace :)
Last edited by oskigrn on Sat Aug 25, 2018 12:22 pm, edited 1 time in total.

philat
Eileen-Class Veteran
Posts: 1912
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: buttons actions, navigation and game flow issues

#2 Post by philat »

In the first example, use SetField, not SetVariable, for your second action. You could also move ALL your commands to the label, not just the location change.

User avatar
MaydohMaydoh
Regular
Posts: 165
Joined: Mon Jul 09, 2018 5:49 am
Projects: Fuwa Fuwa Panic
Tumblr: maydohmaydoh
Location: The Satellite of Love
Contact:

Re: buttons actions, navigation and game flow issues

#3 Post by MaydohMaydoh »

First of all, you need to use SetField instead of SetVariable when changing a class attribute.

Code: Select all

imagebutton:
    auto "gui/quick_map_%s.png"
    action SetField(player, 'current_location', "map")
Second, because when the action list is called, it takes the variables as they are at the time, so even though you're setting the variable to "map" when you click the button, the variable was set to "home" when you clicked it. If that makes sense. So double clicking the button should change the screen.

Also, instead of showing and hiding screens, you can give each screen a tag. When a new screen is shown, it replaces other screens with the same tag.
You should also set the object outside of any blocks using default.
Here's a quick example of something that works:

Code: Select all

init python:
    class cl_player:
        def __init__(self, fname, lname):
            self.fname = fname
            self.lname = lname
            self.current_location = "home"
        def change_location(self, location):
            self.current_location = location
            return location
            
default player = cl_player("Test", "McGee")

screen home():
    tag my_screens
    
    imagebutton:
        auto "gui/quick_map_%s.png"
        action Show(player.change_location("map"))
        
screen map():
    tag my_screens
    
    imagebutton:
        auto "gui/quick_map_%s.png"
        action Show(player.change_location("home"))
        
label start:
    call screen home
Using player.change_location, changes current_location to whatever you tell it to, then it returns the location to be shown.
Something like that?
Another way would be to have the hovered function set the attribute then clicking will show the new screen

Code: Select all

imagebutton:
    auto "gui/quick_map_%s.png"
    action Show(player.current_location)
    hovered SetField(player, 'current_location', "map")
    selected False
You need to give the button "selected False" or it'll assume its selected role as the attribute is the same as the screen name until you hover the button.

oskigrn
Newbie
Posts: 9
Joined: Thu Aug 23, 2018 1:03 pm
Contact:

Re: buttons actions, navigation and game flow issues [SOLVED]

#4 Post by oskigrn »

Cool! Thank you both so much. You've helped a lot :) I completely forgot the tag option!

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot], piinkpuddiin, snotwurm