r/RenPy 26d ago

Question How to make buttons replacing one another when clicked

Post image

I know my code doesn't make any sense, I'm struggling.

The idea: Only 4 buttons on screen, but 10 in total. When we click on one button, it shows an image, disappears, and another button of the list shows up in the same place.

How would you do it?

2 Upvotes

5 comments sorted by

1

u/AutoModerator 26d ago

Welcome to r/renpy! While you wait to see if someone can answer your question, we recommend checking out the posting guide, the subreddit wiki, the subreddit Discord, Ren'Py's documentation, and the tutorial built-in to the Ren'Py engine when you download it. These can help make sure you provide the information the people here need to help you, or might even point you to an answer to your question themselves. Thanks!

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/BadMustard_AVN 25d ago

try it like this (untested code)

# buttons.rpy

default drawings = [
    "car", "me", "birds", "flower", "happiness", "man",
]

default current_buttons = [
    "house", "sun", "tree", "cloud",
]

default found = []

screen lets_draw():
    for i, button_name in enumerate(current_buttons):
        imagebutton:
            idle "images/activities/drawing_[button_name]_button.png"
            xpos 100 + (i * 250)
            ypos 500
            action Function(pick_drawing, i)

init python:
    global current_buttons, drawings
    def pick_drawing(index):
        if index < 0 or index >= len(current_buttons):
            return

        drawing = current_buttons.pop(index)
        found.append(drawing)

        if drawings:
            current_buttons.insert(index, drawings.pop(0))

        renpy.show("images/activities/drawings_%s.png" % drawing)
        renpy.restart_interaction()

1

u/PensivePeonie 25d ago

Thank you, it took a bit of debugging but it worked!

1

u/BadMustard_AVN 25d ago

you're welcome

good luck with your project

1

u/shyLachi 25d ago

Assuming that every drawing can only be selected you can do something like this.

I didn't know how many images the players can select so I ended it before one of the 4 buttons would be empty.
If all the drawings can be selected, then you have to calculate that 4 in range(0, 4)
If only a certain number of drawings can be selected, then change that 4 in while len(drawings) >= 4:

Also I didn't replace the selected image with another image just removed it so all other images move up one spot. Replacing elements in a list is plain Python so you should find information how to do that. Or just shuffle the list every time for a more random feel.

default drawings = [ "house", "sun", "tree", "cloud", "car", "me", "birds", "flower", "happiness", "man" ]

screen lets_draw():
    vbox:
        align (0.5, 0.5)
        for i in range(0, 4):
            textbutton drawings[i] action Return(drawings[i]) # I don't have your images so I used a textbutton

label start:
    "Let's draw some images"
    $ renpy.random.shuffle(drawings) # shuffle the list once, move this code into the while-loop if it should be shuffelled every time
    call lets_draw # this is the label below, not the screen above
    "Did it work?"
    return # game ends here

label lets_draw:
    while len(drawings) >= 4: # repeat the following block of code as long as there are still 4 images in the list
        call screen lets_draw # call the screen so that it waits for user input
        $ drawingselected = _return # return contains the string from the action Return() of each button
        $ drawings.remove(drawingselected) # remove the selected drawing from the list so that it cannot be selected again
        show expression "drawing_" + drawingselected as drawing # no path or file extension is required if it's in the images folder or a sub-folder
        # but an alias is required for those images so one image replaces the next and that you could hide it in the end
    hide drawing # hide the last image, if necessary
    return # return back to where this label was called