[Solved] How to make a history of screens?

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
Saa
Regular
Posts: 32
Joined: Tue Aug 20, 2013 7:11 pm
Tumblr: nipahgirl
Contact:

[Solved] How to make a history of screens?

#1 Post by Saa »

In my game, there's a phone/social media funcionality where each new "page" is a screen. So if you click a post to reply to it, it shows you a "reply(post)" screen (where post is an object from the Posts class), and if you click someone's name, it takes you to a "profile(person)" screen (where person is an object from this recipe)

Thing is, I want to make a "back" button that takes you to the last screen you saw. Since you can go to a profile by clicking a post and a post by clicking a reply, and do this infinite times (click a profile then a post in it then a name in it then a post in the person's profile...), this is proving pretty challenging. I've tried to do it by using a list and storing post and person objects in it, but it doesn't work, sometimes buttons just turn unclickable, and it doesn't even give me any errors so I have no idea what's wrong. It also feels terribly inefficient, since it's storing whole objects in it.

Current code:

Code: Select all

default iraAdded = False
default luxAdded = False
default bizAdded = False
default barAdded = False
default sleepyAdded = False
################################################################################
## Stylesheet
################################################################################
style phone_vbox:
    color "#ffffff"
    xsize  350

style opname:
    color "#00f"
    hover_underline True
    selected_underline True
################################################################################
## Posts
################################################################################
init python:
    import renpy.store as store
    reply_screen = False
    class Posts(store.object):
        def __init__(self, poster, pid, post, visi, liked, repliable, reply1, aff1, reply2, aff2):
            self.poster = poster
            self.pid = pid
            self.post = post
            self.visi = visi
            self.liked = liked
            self.repliable = repliable
            self.reply1 = reply1
            self.reply2 = reply2
            self.aff1 = aff1
            self.aff2 = aff2
            posts.insert(0, self)
        # def comment(self):
            # global comment_screen
            # comment_screen = True
            # renpy.call_in_new_context(self.comment_label, current_post=self)
            # comment_screen = False
    class Comments(store.object):
        def __init__(self, poster, pid, comment):
            self.poster = poster
            self.pid = pid
            self.comment = comment
            comments.append(self)
    def add_message (poster, pid, post, repliable, reply1, aff1, reply2, aff2):
        visi = False
        liked = False
        if poster.added == True:
            visi = True
        message = Posts(poster, pid, post, visi, liked, repliable, reply1, aff1, reply2,  aff2)
        if visi == True:
            renpy.notify("New post!")
    def add_comment (poster, pid, comment, reply, repliable, reply1, aff1, reply2, aff2):
        comment = Comments(poster, pid, comment)
        if reply==True:
            renpy.notify("Someone replied to your reply!")
        else:
            pass
        for i in posts:
            if i.pid == pid:
                i.repliable = repliable
                i.reply1 = reply1
                i.reply2 = reply2
                i.aff1 = aff1
                i.aff2 = aff2
    def addFriend (friend):
        for i in posts:
            if i.poster == friend:
                i.visi = True
        friend.added = True
        renpy.notify("Friend added!")
    def like(i):
        if i.liked == False:
            i.liked = True
        else:
            i.liked = False
        i.poster.affection +=0.1
    def affe(poster, afpoint):
        poster.affection += afpoint
    def clearphist():
        phonehistory = []
    def remphist():
        phonehistory.pop(0)
################################################################################
## Phone screen
################################################################################
screen phone():
    modal True
    zorder 100
    style_prefix "phone"
    imagebutton idle "gui/overlay/confirm.png" action [Hide("phone"), Hide("reply"), Hide("profile")] keysym("K_ESCAPE")
    add "images/placeholder/phoneimgmap.png" xalign .5
    button:
        pos (455, 631)
        action [Hide("phone"), Hide("reply"), Hide("profile"), Function(clearphist)]
    viewport xmaximum 350 ymaximum 510 draggable True mousewheel True pagekeys True:
        xalign .5
        yalign 0.4
        vbox:
            for i in posts:
                if i.visi==True:
                    frame:
                        background "#fff"
                        xsize 350
                        hbox:
                            imagebutton idle i.poster.propic action Show("profile", None, i.poster)
                            textbutton i.poster.username:
                                text_style "opname"
                                action Show("profile", None, i.poster)
                    frame background "#eee" xsize 350 ysize 2
                    frame:
                        background "#fff"
                        xsize 350
                        text i.post
                    frame:
                        background "#eee"
                        xsize 350
                        hbox:
                            button:
                                background "#fff"
                                xsize 170
                                if i.liked==False:
                                    text "♡ Like" text_align 0.5 hover_underline True
                                elif i.liked==True:
                                    text "♥ Unlike" text_align 0.5 hover_underline True
                                action Function(like, i)
                            null width 1
                            button:
                                background "#fff"
                                xsize 170
                                text "← Reply" text_align 0.5 hover_underline True
                                action Show("reply", None, i)
                    null width 350 height 10
screen reply(post):
    zorder 101
    style_prefix "phone"
    add "images/placeholder/phone.png" xalign .5
    button:
        pos (35, 635)
        if len(phonehistory)>0 and isinstance(phonehistory[0], CharacterStats) == True:
            action [Hide("reply"), Show("profile", None, phonehistory[0]), Function(remphist)]
        else:
            action Hide("reply")
    viewport xmaximum 350 ymaximum 510 draggable True mousewheel True pagekeys True:
        xalign .5
        yalign 0.4
        vbox:
            frame:
                background "#fff"
                xsize 350
                hbox:
                    imagebutton idle post.poster.propic action [Show("profile", None, post.poster), Hide("reply"), AddToSet(phonehistory, post)]
                    textbutton post.poster.username:
                        text_style "opname"
                        action [Show("profile", None, post.poster), Hide("reply"), AddToSet(phonehistory, post)]
            frame background "#eee" xsize 350 ysize 2
            frame:
                background "#fff"
                xsize 350
                text post.post
            frame:
                background "#eee"
                xsize 350
                button:
                    background "#fff"
                    xsize 345
                    if post.liked==False:
                        text "♡ Like" text_align 0.5 hover_underline True
                    elif post.liked==True:
                        text "♥ Unlike" text_align 0.5 hover_underline True
                    action Function(like, post)
            for i in comments:
                if i.pid == post.pid:
                    frame:
                        background "#fff"
                        xsize 350
                        vbox:
                            hbox:
                                imagebutton idle i.poster.propic action [Show("profile", None, i.poster), Hide("reply"), AddToSet(phonehistory, post)]
                                textbutton i.poster.username:
                                    text_style "opname"
                                    action [Show("profile", None, i.poster), Hide("reply"), AddToSet(phonehistory, post)]
                            text i.comment
                    frame background "#eee" xsize 350 ysize 2
            if post.repliable==True:
                frame:
                    background "#eee"
                    xsize 350
                    hbox:
                        imagebutton idle m.propic action NullAction()
                        vbox:
                            textbutton post.reply1 text_style "replychoice" action [Function(add_comment, m, post.pid, post.reply1, False, False, "", 0, "", 0), Function(affe, post.poster, post.aff1), Hide("reply"), Show("reply", None, post)]
                            textbutton post.reply2 text_style "replychoice" action [Function(add_comment, m, post.pid, post.reply2, False, False, "", 0, "", 0), Function(affe, post.poster, post.aff2), Hide("reply"), Show("reply", None, post)]
screen profile(person):
    zorder 102
    style_prefix "phone"
    add "images/placeholder/phone.png" xalign .5
    button:
        pos (35, 635)
        if len(phonehistory)>0 and isinstance(phonehistory[0], Posts)==True:
            action [Show("reply", phonehistory[0]), Hide("profile"), Function(remphist)]
        else:
            action [Hide("profile")]
    viewport xmaximum 350 ymaximum 510 draggable True mousewheel True pagekeys True:
        xalign .5
        yalign 0.4
        vbox:
            add person.propic xalign .5
            text person.username xalign .5
            text person.bio style "pbio" xalign .5
            for i in posts:
                if i.poster==person:
                    frame:
                        background "#fff"
                        xsize 350
                        hbox:
                            imagebutton idle person.propic action NullAction()
                            textbutton person.username:
                                text_style "opname"
                                action NullAction()
                    frame background "#eee" xsize 350 ysize 2
                    frame:
                        background "#fff"
                        xsize 350
                        text i.post
                    frame:
                        background "#eee"
                        xsize 350
                        hbox:
                            button:
                                background "#fff"
                                xsize 170
                                if i.liked==False:
                                    text "♡ Like" text_align 0.5 hover_underline True
                                elif i.liked==True:
                                    text "♥ Unlike" text_align 0.5 hover_underline True
                                action Function(like, i)
                            null width 1
                            button:
                                background "#fff"
                                xsize 170
                                text "← Reply" text_align 0.5 hover_underline True
                                action [Show("reply", None, i), Hide("profile"), AddToSet(phonehistory, person)]
                    null width 350 height 10
style phone_prompt is gui_prompt
style phone_prompt_text is gui_prompt_text
style phone_button is gui_medium_button
style phone_button_text is gui_medium_button_text
style phone_text:
    color "#000"
style replychoice:
    color "#000"
    #text_color "#fff"
style pbio:
    size 10
Last edited by Saa on Wed May 08, 2019 10:20 am, edited 3 times in total.

User avatar
nature1996
Regular
Posts: 62
Joined: Wed Jun 21, 2017 10:35 am
Contact:

Re: How to make a history of screens?

#2 Post by nature1996 »

Try using Call rather than Show, and using return to close the screen
Je parle aussi français

User avatar
Saa
Regular
Posts: 32
Joined: Tue Aug 20, 2013 7:11 pm
Tumblr: nipahgirl
Contact:

Re: How to make a history of screens?

#3 Post by Saa »

nature1996 wrote: Tue May 07, 2019 4:52 pm Try using Call rather than Show, and using return to close the screen
Call only works for labels, it gives me an error if I try using it for screens.

I tried using a function to call screens for me:

Code: Select all

    def showprofile(person):
        renpy.call_screen("profile", person)
    def showreply(post):
        renpy.call_screen("reply", post)
But I get the error "Cannot start an interaction in the middle of an interaction, without creating a new context".

User avatar
nature1996
Regular
Posts: 62
Joined: Wed Jun 21, 2017 10:35 am
Contact:

Re: [Not yet solved] How to make a history of screens?

#4 Post by nature1996 »

I was talking about the screen code replace any action

Code: Select all

Show("screen")
by:

Code: Select all

action Function(renpy.call_screen, "screen")
It should call the screen, which will pile it. If you exit the screen using "action Return()", it should go back to the previous one.
Je parle aussi français

User avatar
Saa
Regular
Posts: 32
Joined: Tue Aug 20, 2013 7:11 pm
Tumblr: nipahgirl
Contact:

Re: [Not yet solved] How to make a history of screens?

#5 Post by Saa »

nature1996 wrote: Tue May 07, 2019 5:55 pm I was talking about the screen code replace any action

Code: Select all

Show("screen")
by:

Code: Select all

action Function(renpy.call_screen, "screen")
It should call the screen, which will pile it. If you exit the screen using "action Return()", it should go back to the previous one.
That's pretty much what I did, and even doing exactly what you said gave the same "Cannot start an interaction in the middle of an interaction, without creating a new context" error.

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3794
Joined: Mon Dec 14, 2015 5:05 am
itch: Imperf3kt
Location: Your monitor
Contact:

Re: [Not yet solved] How to make a history of screens?

#6 Post by Imperf3kt »

Try using action Call("screen")
Note the capitalised C
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor

Twitter

User avatar
Saa
Regular
Posts: 32
Joined: Tue Aug 20, 2013 7:11 pm
Tumblr: nipahgirl
Contact:

Re: [Not yet solved] How to make a history of screens?

#7 Post by Saa »

Imperf3kt wrote: Tue May 07, 2019 6:37 pm Try using action Call("screen")
Note the capitalised C
It gives me a ScriptError: could not find label 'reply'.

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

Re: [Not yet solved] How to make a history of screens?

#8 Post by philat »

Hard to offer much other than general comments as it's not testable, but perhaps set a variable for the back button when you're showing the new screen. In other words, screen A has a button that 1) shows screen B, 2) sets a variable called previous_screen to "A". screen B has a back button that basically does Show(previous_screen).

Edit: Never mind, realized I misread the question. I don't know see why your general approach wouldn't work.

User avatar
Saa
Regular
Posts: 32
Joined: Tue Aug 20, 2013 7:11 pm
Tumblr: nipahgirl
Contact:

Re: [Solved] How to make a history of screens?

#9 Post by Saa »

I found the issue! There were three, actually.

The first: when clicking outside the phone, I forgot to reset the list.

The code was:

Code: Select all

imagebutton idle "gui/overlay/confirm.png" action [Hide("phone"), Hide("reply"), Hide("profile")] keysym("K_ESCAPE")
And should have been:

Code: Select all

imagebutton idle "gui/overlay/confirm.png" action [Hide("phone"), Hide("reply"), Hide("profile"), Function(clearphist)] keysym("K_ESCAPE")
The second: I forgot to specify the transition when returning to the reply screen from the profile screen.

The code was:

Code: Select all

action [Show("reply", phonehistory[0]), Hide("profile"), Function(remphist)]
And should have been:

Code: Select all

action [Show("reply", None, phonehistory[0]), Hide("profile"), Function(remphist)]
The third: I got the order list wrong. The last element in the list was the most recent, not the first. This caused all kinds of issues.
The code was:

Code: Select all

phonehistory[0]
And should have been:

Code: Select all

phonehistory[-1]
Thank you to everyone who tried to help! It's working perfectly now.

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], LegsWild