Return value returned from screen when pressing textbutton

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
cppietime
Newbie
Posts: 10
Joined: Mon Feb 09, 2015 11:45 am
Contact:

Return value returned from screen when pressing textbutton

#1 Post by cppietime »

I'm having a little trouble... I have two screens, and I want one screen, upon pressing a textbutton, to return the value returned by another screen, but I can't figure out how to do this.

Pseudocode is as follows:

show first-screen
if(button is pushed):
show second-screen
return second-screen's returned value

I've tried the following code:

Code: Select all

screen mainBattle(char, enemey):
    frame align(0.12, 0.12):
        vbox xalign 0.05:
            text "YOU: [char.hp] / [char.maxHP] HP"
            text "ENEMY: [enemy.hp] / [enemy.maxHP] HP"
            
            textbutton "fight" action Return(screen call choose(char))
            
            
screen choose(char):
    vbox:
        for i in char.skills:
            textbutton "[i.name]" action Return(i)

# Labels/Script parts

#Start
label start:
    
    #Init everything
    python:
        testAtt = Skill("Test", "Attack", 20, 30, 10)
        
        character = Actor("Hero", 100, [testAtt])
        enemy = Actor("Monster", 100, [testAtt])

    call screen mainBattle(character, enemy)
    $ thing = _return
    
    e "[thing.name]"

    return
I've left some of the code out, but Skill and Actor are both classes, and I want pressing the button to return the Skill chosen from a menu. Instead, when starting the game I get:

Code: Select all

File "game/script.rpy", line 38: Syntax error while parsing python expression.
    Return(screen call choose(char))
So I see I'm clearly doing *something* wrong, I figure I'm not calling the screen properly, or just not using the textbutton right at all, so how can I make this work?

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

Re: Return value returned from screen when pressing textbutt

#2 Post by philat »

Calling screens from other screens isn't really allowed, as far as I can tell. http://lemmasoft.renai.us/forums/viewto ... =8&t=11910

Making a workaround using show and hide shouldn't be too difficult, though.

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Return value returned from screen when pressing textbutt

#3 Post by trooper6 »

I think there might be a way to do this...but I need to go teach and won't be back home until tonight. I'll ponder while I'm away.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Return value returned from screen when pressing textbutt

#4 Post by trooper6 »

Okay, I found a way to get this to work...but I know there must be a better way to do this. Someone smart? Do you know a better way to do this?

ui.callsinnewcontext will allow you to call a new label...which can then call a new screen. So all of that works. But the problem I had was I couldn't figure out how to return the nested data along the chain (maybe someone else knows how to do this?)...so I had the choose screen SetVariable on a tempSkill instead. This works! But I'm sure it could be done better.

Code: Select all

screen mainBattle(char, enemy):
    frame align (0.12, 0.12):
        vbox xalign 0.05:
            text "YOU: [char.hp]/[char.maxHP] HP"
            text "ENEMY: [enemy.hp]/[enemy.maxHP] HP"
            textbutton "Fight" action ui.callsinnewcontext("choosetest", char)
            textbutton "End Fight" action [SetVariable("tempSkill", None), Hide("mainBattle")]
            if tempSkill:
                text "Result: [tempSkill.name]"

screen choose(char):
    vbox:
        for i in char.skills:
            textbutton "[i.name]" action [SetVariable("tempSkill", i), Return()]
    
init python:
    class Char():
        def __init__(self, name, hp, mhp, skills):
            self.name = name
            self.hp = hp
            self.maxHP = mhp
            self.skills = skills 

    class Skill():    
        def __init__(self, name, number):
            self.name = name
            self.number = number

label choosetest(char):
    call screen choose(char)
    return

# The game starts here.
label start:
    $fight = Skill("Fight", 12)
    $defend = Skill("Defend", 14)
    $talk = Skill("Talk", 16)
    $hero = Char("Hero", 10, 10, [fight, defend, talk])
    $villain = Char("Villain", 12, 12, [fight, defend, talk])
    $tempSkill = None
    
    show screen mainBattle(hero, villain)
    
    "You can click on the fight button and see the result."
    
    "You should click the End Fight button here and then move on."
    
    show screen mainBattle(hero, villain)
    
    "Look at that! Reset the tempSkill Variable and you can begin again!."
    
    return

    
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Return value returned from screen when pressing textbutt

#5 Post by trooper6 »

So I figured out how to have a screen call a screen and also get and change the necessary variable...see my above code...but I wasn't able to figure out how to pass a variable through the return function from a screen to its label to the parent screen.

Anyone have an idea how to do this?
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
Yuuji
Regular
Posts: 96
Joined: Tue Jan 20, 2015 3:08 am
Location: Russia, Perm
Contact:

Re: Return value returned from screen when pressing textbutt

#6 Post by Yuuji »

I think one of solutions is to create global variable, python function and use them.For example, child screen assigns some value to variable, returns and parent screen uses this value. Well, perhaps this is not perfect solution :)
There's no point in standing around with your mouth open waiting for talent to fall from the sky. You make your own. No matter what you're doing, the most essential thing is not to give up.

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Return value returned from screen when pressing textbutt

#7 Post by trooper6 »

Hi everyone, I've been experimenting with this question again, wanting to see if I could get a better answer than I gave.

So I created a tester project and came up with three different ways to achieve the result. Although all of them ultimately didn't pass information back, they just modified information in the character given.

I'll show you what I did:

Code: Select all

init python:
    class Char():
        def __init__(self, name, mhp, skills=None):
            self.name = name
            self.curHP = mhp
            self.maxHP = mhp
            self.skills = skills
            self.active_skill = None
                
screen battle(char):
    default skill = None
    frame align (1.0, 0.0):
        vbox:
            label "[char.name]"
            text "[char.curHP]/[char.maxHP] HP"
            text "Skill to Use: [char.active_skill]"
            text "-----"
            
            textbutton "Choose Skill, Show Screen" action Show("choose", char=char)
            textbutton "Choose Skill Renpy Func" action Function(renpy.call_in_new_context, "chooselabel", char)
            textbutton "Choose Skill Ui Call" action ui.callsinnewcontext("choosetest", char)
            textbutton "End Choice" action [Hide("battle")]

screen choose(char):
    modal True 
    frame align (0.0, 0.0):
        vbox:
            label "[char.name]'s Skills"
            for sk in char.skills:
                textbutton "[sk]" action [SetField(char, "active_skill", sk), Hide("choose")]

label chooselabel(char):
    call screen choose2(char)
    return
    
screen choose2(char):
    modal True 
    frame align (0.0, 0.0):
        vbox:
            label "[char.name]'s Skills"
            for sk in char.skills:
                textbutton "[sk]" action [SetField(char, "active_skill", sk)]
            
label nested_screens:
    $pc = Char("Tim", 15, ["Attack", "Defend", "Talk"])
    
    show screen battle(pc)
            
    "Click on each one of the buttons in turn to show how it works."

    "Test Over"
    hide screen battle
    
    return
Okay, that all works. But I've been pondering the original question of returning information. So...I've been experimenting with this.

This is my experiment:

Code: Select all

init python:
    class Char():
        def __init__(self, name, mhp, skills=None):
            self.name = name
            self.curHP = mhp
            self.maxHP = mhp
            self.skills = skills
            self.active_skill = None
                
screen battle(char):
    default skill = None
    default result = None
    $result = _return
    frame align (1.0, 0.0):
        vbox:
            label "[char.name]"
            text "[char.curHP]/[char.maxHP] HP"
            text "Skill to Use: [char.active_skill]"
            text "Return: [result]"
            text "-----"
            
            textbutton "Choose Skill" action Show("choose", char=char)
            textbutton "Choose Skill Func" action Function(renpy.call_in_new_context, "choosetest", char)
            textbutton "Choose Skill Ui Call" action ui.callsinnewcontext("choosetest", char)
            textbutton "End Choice" action [Hide("battle")]

            
        
screen choose(char):
    modal True 
    frame align (0.0, 0.0):
        vbox:
            label "[char.name]'s Skills"
            for sk in char.skills:
                textbutton "[sk]" action [SetField(char, "active_skill", sk), Hide("choose")]

label choosetest(char):
    call screen choose2(char)
    "Returning from the choose 2 screen: [_return]"
    return(_return)
    
screen choose2(char):
    modal True #I added this for my new experiment
    frame align (0.0, 0.0):
        vbox:
            label "[char.name]'s Skills"
            for sk in char.skills:
                textbutton "[sk]" action [SetField(char, "active_skill", sk), Return(sk)]
            
label check():
    "Hello"
    return("Goodbye")
    
label nested_screens:
    $pc = Char("Tim", 15, ["Attack", "Defend", "Talk"])

    "Testing return with expression."
    call check
    $result =  _return
    "Returning from the check label: [result]"
    
    show screen battle(pc)
            
    "Test out the three buttons."

    "Test Over"
    hide screen battle
    
    return
So what you'll see that I've done is to test sending information back from a label.

So...I start with a little label check...calling that label, printing "Hello" and then returning "Goodbye." Which I print. All is good.
Then I call up the battle screen. And the battle screen has Goodbye as the return text...interesting.

Okay, so now if you try one of the two buttons that calls the chooselabel interesting things happen.
That label calls the choose2 screen. That screen then returns whichever skill you chose. You can see that it does actually return that skill because I print it.
Then I return that skill back to the first screen...but it never shows up in that battle screen.
I imagine that must have something to do with the calling in new context?

So...is there way to return a variable back to a calling screen? It worked with the random goodbye..but nothing afterwards.

Thoughts?
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot]