[Solved]How can I reuse the 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
bonnie_641
Regular
Posts: 138
Joined: Sat Jan 13, 2018 10:57 pm
Projects: Código C.O.C.I.N.A.
Deviantart: rubymoonlily
Contact:

[Solved]How can I reuse the screens?

#1 Post by bonnie_641 »

Edit:
Thanks to m_from_space for giving me an excellent tip on how to reuse screens.
And also thanks to jeffster for guiding me in the study of Python.

The answer to my question is summarized as follows:
- thanks to Per K Grok, Xavimat and RicharDann I was able to write the receiving code and search for information:

Code: Select all

# ◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◇#
# ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・★#
# ◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆#
# screen search receiving user input: 

screen ask_ing():
    modal True
    tag all_scr
    
    
    add "images/frog_base.jpg"
    add(renpy.Keymap(game_menu=None)) # prevents the right button from working during interaction

    frame:
        #background Solid("#E20490")
        xalign 0.5
        yalign 0.388
        xsize 470
        ysize 100
        #color "#000000"
        has vbox
        label "" text_color "#fff"
        input:
            default ""
            value VariableInputValue('ingridence') #<------ this variable records the value of the input
            length 40
        imagebutton:
            idle "images/frog_btn.png" 
            hover "images/frog_btn1.png" 
            #hovered [ Play ("test_five", "sfx/click.mp3") ]
            xpos 410 ypos -40 #xalign 0.4 yalign 0.6 xanchor 1.1 yanchor 1.3
            focus_mask True 
            #activate_sound 'sfx/xxx.mp3'
            action Show("tell_ing"), Hide("ask_ing")

Code: Select all

# ◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◇#
# ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・★#
# ◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆#
# Screen that searches for information stored in list:

screen tell_ing():
    
    default checkno=0
    modal True
    tag all_scr #<-------this item is very important. If you put in each screen of the same group, they must by obligation use the same tag to close them later.


    add(renpy.Keymap(game_menu=None))


    frame:
        background "images/frog_base1.jpg"

        vbox:
            spacing 10
            
            
            for i in range(len(ing_list)-1): #<---- searches from the beginning of the string to the last letter. 
                $ ingridence.lower() #<------------- change to lowercase
                $ ingridence = '_'.join(ingridence.split(' ')) # <------- removes all blanks and replaces them all with underscores
                if ingridence.lower() == ing_list[i][0]: #<------ compares the entered data with the keyword. if the user typed "apple", the program will search for "apple".
                    
                    $ checkno=1 #<------ If you found "apple", put a flag on it
                    $ ingridence = ingridence.lower() 
                    
                    timer 0.01 action Show("vocabulario") 



For now, I made a pivot screen, which derives the value of "ingridence" to compare the values stored in other variables.

Code: Select all

screen vocabulario(): # <------ screen pivot

    tag grupo
    modal True
    
    add "images/frog_base1.jpg"
    
    frame:# texto ppal "a"
        #background "#ffffff"
        area (400, 260, 790, 357) #(x, y, w, h)
        viewport:
            #id "cultura_"
            draggable True
            scrollbars "vertical"
            vscrollbar_unscrollable "hide" #allows you to hide scrollbar if necessary
            mousewheel True
            has vbox
            spacing 10
            xsize 940
            xfill True
            use contenido_ing(ingridence) #<-------- THIS SMALL LINE OF CODE LINKS TO ANOTHER SMALLER SCREEN... :D 

Code: Select all

screen contenido_ing(ingridence):
    if ingridence == "a":
        $ ingridence = a 
   #(...)
    if ingridence == "to_go_away_from_a_place" or "to go away from a place": # <--- IF IT'S A PHRASE... IT WILL LOOK FOR IT WITH UNDERSCORES, SINCE THIS IS HOW THE VARIABLE IS DEFINED.
        $ ingridence = to_go_away_from_a_place
    #(...)
    
    
    # AND HERE RECYCLES THE SCREEN.
    for s in ingridence:
        text s:
            justify True

Code: Select all

# When there are links redirecting from the main word ({a=label_custom}{/a}, where label_custom has the name of the stored variable e.g.: define apple= [""" add description here"""]
# you must create a label of that word, changing
# the variable "INGRIDENCE"

label to_go_away_from_a_place():
    $ ingridence = to_go_away_from_a_place
    call screen vocabulario()

label a():
    $ ingridence = a
    call screen vocabulario()


I know that because of language differences, it may be very difficult to explain what I did, but I am committed to study to improve the code.
However, the code works and that matters. I have been learning for a long time and it has been a very long process. I still have a lot to learn, but I thank you from the bottom of my heart for all the help I received in this forum.

So I give this issue as "solved". :D

# ◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◇◆◇◆◇◆◇#

Hi everyone! :D
I am creating a list of words.
I made the first word appear successfully.

Reasoning: the variable "ingridence" would go through the entire list to check whether or not it matches the position in the list.

Code: Select all

(...)
            for i in range(len(ing_list)-1):
                $ ingridence.lower()
                if ingridence.lower() == ing_list[i][0]:
                    $ checkno=1
                    $ ingridence = ingridence.lower()
                    frame:# texto ppal "a"
                        #background "#ffffff"
                        area (400, 260, 790, 357) #(x, y, w, h)
                        viewport:
                            #id "cultura_"
                            draggable True
                            scrollbars "vertical"
                            mousewheel True
                            has vbox
                            spacing 10
                            xsize 940
                            xfill True
                            (...)
The first question was how to present this variable to be used later in "screen" or "label".

Code: Select all

for i in range(len(ing_list)-1):
	(...)
	timer 0.01 action Jump(ingridence) # other options:  text ing_list[i][0] : (add style); text ing_list[i][1]: (add style) , etc...
At first I used "text ing_list", however the game takes too long to add +30 words (not to mention the accessories (screen containing styles and the gui of each one).

I reduced the gui by one to simplify the process and optimize resources:

Code: Select all

screen lado_izquierdo(): #Here is the left panel showing letters
    frame:
        background Solid("#F00057")
        area (0, 100, 300, 610) #(x, y, w, h)
        viewport:
            id "letras"
            draggable True
            scrollbars "vertical"
            mousewheel True
            has vbox
            spacing 10
            xsize 340
            xfill True
            for s in letras:
                text s:
                    justify True
                    size 16

 screen texto_principal():  #Here is the right panel showing the concept: (Ingridence : "blah blah blah blah...")
    frame:# texto ppal "a"
        #background "#ffffff"
        area (327, 60, 950, 650) 
        viewport:
            id "concepto"
            draggable True
            scrollbars "vertical"
            mousewheel True
            has vbox
            spacing 10
            xsize 940
            xfill True
            for s in concepto:
                text s:
                    #font "BalsamiqSans_Regular.ttf"
                    justify True
               

The conflict is in how to reuse the screens so as not to add +30 screens (one for each item in the list) and add the imagebuttons without blocking the action of each one.

Code: Select all

# close game button
    imagebutton:
        idle "images/idle_x.png"
        hover "images/hover_x.png"
        pos (1244,0)
        focus_mask True
        #activate_sound 'click.wav'
        action Jump("fin")
        
    # resize window button: will change later with another screen 
    imagebutton:
        idle "images/idle_max.png"
        hover "images/hover_max.png"
        pos (1200,0)
        focus_mask True
        #activate_sound 'click.wav'
        action Jump("menu_pc")

    # minimize window button:  will change later with another screen 
    imagebutton:
        idle "images/idle_min.png"
        hover "images/hover_min.png"
        pos (1160,0)
        focus_mask True
        #activate_sound 'click.wav'
        action Jump("menu_pc")

    # menu containing other labels: You can hide the menu and choose what content you want to see.
    imagebutton:
        idle "images/idle_menu3.png"
        hover "images/hover_menu3.png"
        pos (1249,43)
        focus_mask True
        #activate_sound 'click.wav'
        action If(renpy.get_screen("menu3_scr"), true=Hide("menu3_scr"), false=ShowMenu("menu3_scr"))
To make everything work at the same time is almost impossible. The zorders don't work, I tried with game layers and one layer overrides the other.
To give you an idea, it's like using a browser, where you tell the search engine what you want to search for. When you click, you get to the dictionary offered by the search engine and the page interface appears (it's a local search).

How can I make all screens (left panel, content panel and imagebutton) appear for each searched word?
The imagebuttons are the same (because they are part of the browser), while the panels change for each word (left panel will show 5 possible results for each word, while the content panel will only have 1 item at a time).

Thank you in advance
Attachments
problem.jpg
(129.08 KiB) Not downloaded yet
Last edited by bonnie_641 on Sun May 12, 2024 8:48 pm, edited 3 times in total.
I speak and write in Spanish. I use an English-Spanish translator to express myself in this forum. If I make any mistakes, please forgive me.
I try my best to give an answer according to your question. :wink:

User avatar
m_from_space
Eileen-Class Veteran
Posts: 1009
Joined: Sun Feb 21, 2021 3:36 am
Contact:

Re: How can I reuse the screens?

#2 Post by m_from_space »

bonnie_641 wrote: Wed May 08, 2024 8:05 pm How can I make all screens (left panel, content panel and imagebutton) appear for each searched word?
The imagebuttons are the same (because they are part of the browser), while the panels change for each word (left panel will show 5 possible results for each word, while the content panel will only have 1 item at a time).

Thank you in advance
I am sure I don't fully understand what is going on here, but in general it is possible to just write one screen and use it in multiple ways by calling it with arguments (or no arguments if nothing has to be different). So here is an example that hopefully makes my point and gives you an idea:

Code: Select all

screen a_single_button(number):
    textbutton f"I am button #{number}" action NullAction()

screen list_of_10_buttons():
    vbox:
        for i in range(10):
            use a_single_button(i+1)
            
label start:
    show screen list_of_10_buttons
    "Wow, so many buttons that don't do anything!"

User avatar
bonnie_641
Regular
Posts: 138
Joined: Sat Jan 13, 2018 10:57 pm
Projects: Código C.O.C.I.N.A.
Deviantart: rubymoonlily
Contact:

Re: How can I reuse the screens?

#3 Post by bonnie_641 »

m_from_space wrote: Thu May 09, 2024 11:55 am

Code: Select all

screen a_single_button(number):
    textbutton f"I am button #{number}" action NullAction()

screen list_of_10_buttons():
    vbox:
        for i in range(10):
            use a_single_button(i+1)
            
label start:
    show screen list_of_10_buttons
    "Wow, so many buttons that don't do anything!"
[/quote]
:shock:
I have read your answer many, many times....
At first, I thought you didn't understand my question, but after comparing it with other codes on the forum, I realized that you put the easiest example to reuse the screens.
I thank you from the bottom of my heart for your great help.
Finally... after more than 1 month and 4 days, I could reorganize and optimize the code thanks to you. You are my hero (as well as Alex and Hell-oh-world).

One question (although it's optional if you answer): is there any way to dodge the "if" checks?

Code: Select all

(...)
# An "extreme" substitution is performed, in which the 30 variables obtain the values of ing_list[i][0] and ing_list [i][1].
# I made the transfer of values using the variable "ingridence".
#At the beginning, each variable had its own screen, but I was able to reuse... 1 screen for all.  :o 

if ingridence == "a":
        $ ingridence = a 
if ingridence == "b":
        $ ingridence = b
# (check more than 30 times... although my goal is to make a dictionary of 200.000 entries XD) 
    
for i in ingridence:
	text i:
		justify True
		#more style here
I don't know if it will affect the performance of the game, but I'll risk doing the "if" checks.
Thank you very much for everything. :D
I speak and write in Spanish. I use an English-Spanish translator to express myself in this forum. If I make any mistakes, please forgive me.
I try my best to give an answer according to your question. :wink:

jeffster
Veteran
Posts: 440
Joined: Wed Feb 03, 2021 9:55 pm
Contact:

Re: How can I reuse the screens?

#4 Post by jeffster »

bonnie_641 wrote: Fri May 10, 2024 7:17 pm

Code: Select all

(...)
# An "extreme" substitution is performed, in which the 30 variables obtain the values of ing_list[i][0] and ing_list [i][1].
# I made the transfer of values using the variable "ingridence".
#At the beginning, each variable had its own screen, but I was able to reuse... 1 screen for all.  :o 

if ingridence == "a":
        $ ingridence = a 
if ingridence == "b":
        $ ingridence = b
# (check more than 30 times... although my goal is to make a dictionary of 200.000 entries XD) 
    
for i in ingridence:
	text i:
		justify True
		#more style here
The idea of Python language is to be very simple and elegant, and to be used in "Pythonic" (i.e. simple and elegant) way.
https://docs.python.org/3/reference/index.html

For that reason, there are convenient data structures like list, dict, set and so on,
https://docs.python.org/3/tutorial/intr ... html#lists

and there are "comprehensions", i.e. syntax constructions to operate with data types in a concise and elegant manner.
https://docs.python.org/3/tutorial/datastructures.html

For example, if you have a dict of ingredients, you can do it in several ways, e.g.:

Code: Select all

default ingredients = {
    'apple': ["Apple is a fruit I really like", "apple.png"],
    'avocado': ["Avocado is a fruit (I think?)", "avocado.png"],
    }
Then you can address them like

Code: Select all

screen apple():
    # Apple description:
    text ingredients['apple'][0]
    # Apple picture:
    add ingredients['apple'][1]

# Or:

call screen show_ingredient('apple')

screen show_ingredient(ingr):
    # Ingredient's description:
    text ingredients[ingr][0]

    # Ingredient's picture:
    add ingredients[ingr][1]

And if you want to filter the dict by keys, you can use (really many methods including) comprehensions:

Code: Select all

    $ a = [x for x in ingredients if x.startswith('a')]
    $ ap = [x for x in ingredients if x.startswith('ap')]
Here a will be

Code: Select all

['apple', 'avocado']
and ap will be

Code: Select all

['apple']
You can run Python interpreter and check how various constructions work:

Code: Select all

Python 3.12.3 (main, Apr 23 2024, 01:16:07) [GCC 13.2.1 20240417] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> ingredients = {
...     'apple': ["Apple is a fruit I really like", "apple.png"],
...     'avocado': ["Avocado is a fruit (I think?)", "avocado.png"],
...     }
>>> a = [x for x in ingredients if x.startswith('a')]
>>> a
['apple', 'avocado']
>>> ap = [x for x in ingredients if x.startswith('ap')]
>>> ap
['apple']
>>> 
If the problem is solved, please edit the original post and add [SOLVED] to the title. 8)

User avatar
bonnie_641
Regular
Posts: 138
Joined: Sat Jan 13, 2018 10:57 pm
Projects: Código C.O.C.I.N.A.
Deviantart: rubymoonlily
Contact:

Re: How can I reuse the screens?

#5 Post by bonnie_641 »

jeffster wrote: Fri May 10, 2024 9:39 pm
For example, if you have a dict of ingredients, you can do it in several ways, e.g.:

Code: Select all

default ingredients = {
    'apple': ["Apple is a fruit I really like", "apple.png"],
    'avocado': ["Avocado is a fruit (I think?)", "avocado.png"],
    }
Then you can address them like

Code: Select all

screen apple():
    # Apple description:
    text ingredients['apple'][0]
    # Apple picture:
    add ingredients['apple'][1]

# Or:

call screen show_ingredient('apple')

screen show_ingredient(ingr):
    # Ingredient's description:
    text ingredients[ingr][0]

    # Ingredient's picture:
    add ingredients[ingr][1]

And if you want to filter the dict by keys, you can use (really many methods including) comprehensions:

Code: Select all

    $ a = [x for x in ingredients if x.startswith('a')]
    $ ap = [x for x in ingredients if x.startswith('ap')]
Here a will be

Code: Select all

['apple', 'avocado']
and ap will be

Code: Select all

['apple']
You can run Python interpreter and check how various constructions work:

Code: Select all

Python 3.12.3 (main, Apr 23 2024, 01:16:07) [GCC 13.2.1 20240417] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> ingredients = {
...     'apple': ["Apple is a fruit I really like", "apple.png"],
...     'avocado': ["Avocado is a fruit (I think?)", "avocado.png"],
...     }
>>> a = [x for x in ingredients if x.startswith('a')]
>>> a
['apple', 'avocado']
>>> ap = [x for x in ingredients if x.startswith('ap')]
>>> ap
['apple']
>>> 
Wow! Thank you so much for helping me. :D <3
I will study the pages you recommended and edit parts of code that, while working for now, would be problematic to maintain over time :oops:
I speak and write in Spanish. I use an English-Spanish translator to express myself in this forum. If I make any mistakes, please forgive me.
I try my best to give an answer according to your question. :wink:

User avatar
bonnie_641
Regular
Posts: 138
Joined: Sat Jan 13, 2018 10:57 pm
Projects: Código C.O.C.I.N.A.
Deviantart: rubymoonlily
Contact:

Re: [Solved]How can I reuse the screens?

#6 Post by bonnie_641 »

Issue resolved. For backup, I left in the first post how it was solved. Thanks for reading.
I speak and write in Spanish. I use an English-Spanish translator to express myself in this forum. If I make any mistakes, please forgive me.
I try my best to give an answer according to your question. :wink:

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot]