Ren'Py trying a make a Image button minigame

aPieceOfTissue

Newbie
Game Developer
Jan 22, 2019
40
86
I'm trying a make a minigame in my game where you can undress a girl when you click on her clothes.

For example:
demo1.png
Original image: T-shirt with Jacket
1st click: remove Jacket
2nd click: remove T-shirt

I know a little bit about how image button work but I don't know how to make this happen.

Also, is it possible to make an image button to always stay on top layer?
There are 3 layer of clothes: T-shirt, jeans, underwear
I want the T-shirt to always stay on top layer even if the player decide to remove her jeans first.

Thank you for reading my questions.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,608
2,256
It's RenPy... so there are at least 6 different ways you could do it...

The modern method would probably be .

It looks a little complicated at first (as most of the RenPy documentation does), but the simple answer is that you can create a single image which is made up of other images. Those other images can be included or excluded based on the value of a variable (or lots of variables).

In your case, you could have a default girl_undress = 0 statement to define a variable (0 = fully dressed). Then each time you click, you add one to it ($ girl_undress += 1).
Then just create the layered image so that it checks the variable to see if a layer of clothing should be shown or not based on the number.

Alternatively, have lots of different variables for things like girl_tshirt, girl_jeans and girl_underwear... then set them to True or False depending on whether they should be shown or not. If you haven't done any programming before, True/False is practically Yes/No and is just a "that's the way it's done" thing.

The only other thing you would need then is a custom to allow the player to interact with the (layered) picture, hotspots or buttons.
If you want to click on the actual pieces of clothing themselves (as images), you might want to investigate .
Or simply make do with a single to advance things.

There are lots of threads here on the forums about screens, imagebuttons and textbuttons, if you need extra help beyond the manual.

I will also add that you could do more or less the same thing without the layered images and just code everything into the screen. It's RenPy, so there's a million ways to do stuff.

You also talk about imagebuttons being on "top". If I recall correctly, when two imagebuttons overlap, the one added to the screen last is on top.
Though I would also point out that if you're dealing with things like t-shirts and bras - you could simple not show the bra image (and imagebutton) when the t-shirt is shown. Same for panties and jeans.
 
Last edited:
  • Like
Reactions: anne O'nymous

aPieceOfTissue

Newbie
Game Developer
Jan 22, 2019
40
86
Having another problem again, I manage to set up a screen with image button but I can't get it working:

Code:
screen girl_cloth_remove():

        default girl_undress = 0
        default girl_top = 0
        default girl_bottom = 0
        default girl_under = False

       # Undress top
      
        if girl_top == 0:
            imagebutton:
                idle "top_1_idle.png"
                hover "top_1_hover.png"
                action girl_top + 1

        if girl_top == 1:
            imagebutton:
                idle "top_2_idle.png"
                hover "top_2_hover.png"
                action girl_top + 1, girl_undress + 1

        # Undress bottom
        
        if Laura_bottom == 0:
            imagebutton:
                idle "bottom_1_idle.png"
                hover "bottom_1_hover.png"
                action girl_bottom + 1

        if girl_bottom == 1:
            $ girl_under + 1
            imagebutton:
                idle "bottom_2_idle.png"
                hover "bottom_2_hover.png"
                action girl_bottom + 1, girl_undress + 1

        # Undress underwear
        if girl_under = 1:
            imagebutton:
                idle "underwear_idle.png"
                hover "underwear_hover.png"
                action girl_under + 1, girl_undress + 1

       #Moving on
      
        if girl_undress == 3:
            pass
    call screen girl_cloth_remove
I can still start the game but it crashes as I click on any clothes.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,608
2,256
You're on the right path, as far as I can tell.

I think you're missing that RenPy is a mix of potentially 3+ separate languages that work together to create a game.

In this case, while in the main script you might code $ girl_undress += 1... the screen language is almost a completely different language and you'd alter the value of variables in a different way.

Curiously, either deliberately or not, you're using default in a way I hadn't intended... but in a way that actually works really well in this example.

Let's slightly rewrite the code you've provided...

If I'm honest, I'm not really following how you are using to _top, _bottom and underwear variables.
I would code the underwear first, so that if the top or bottom images are shown, the underwear buttons will be under them.
But maybe I'm misunderstanding what you're aiming for.

Thinking about it, the t-shirt might be top#0 and the bra be top#1. With the jeans being bottom#0 and the panties being bottom#1. At which point, I wonder what all those other variables are for. Hopefully you can recognize enough of my code to adapt it to what you actually want.

For the moment, I'm going to assume the tops and bottoms come off in two stages and THEN the underwear comes off. But I also think I'm wrong about that. As I say, it's not entirely clear from your code.

You also can't just exit from a screen without the player triggering an action somehow.
In my first example, I'm linking that to the player clicking on the final piece of clothing (the underwear).
In my second example, I'm going to show an extra "exit" button after the underwear has been removed.

First example using screen variables (only available within the screen)
and not using a count of the number of pieces of clothing removed...

Python:
# this screen assumes clicking on the underwear will end the screen.

screen girl_cloth_remove():

        default girl_top = 0
        default girl_bottom = 0


        # Undress underwear

        if girl_top == 2 and girl_bottom == 2: # only let the player interact with the underwear after the top and bottoms have been removed.
            imagebutton:
                auto "underwear_%s.png"
                action Return()                # this could be an action Jump("label_name") instead.
        else:
            imagebutton:
                idle "underwear_idle.png"
                action NullAction()            # otherwise, do nothing.
   

       # Undress top

        if girl_top == 0:
            imagebutton:
                auto "top_1_%s.png"
                action SetScreenVariable("girl_top", girl_top + 1)

        if girl_top == 1:
            imagebutton:
                auto "top_2_%s.png"
                action SetScreenVariable("girl_top", girl_top + 1)

        # Undress bottom

        if girl_bottom == 0:
            imagebutton:
                auto "bottom_1_%s.png"
                action SetScreenVariable("girl_bottom", girl_bottom + 1)

        if girl_bottom == 1:
            imagebutton:
                auto "bottom_2_%s.png"
                action SetScreenVariable("girl_bottom", girl_bottom + 1)


label start:

    scene black with fade
       
    call screen girl_cloth_remove

    "*** THE END ***"
    return

I think this code will work. But I haven't tested it.
I've swapped most of your idle/hover lines for auto. %s will automatically be replaced with the words "idle" or "hover" or whatever, if matching images exist.

I know the variable name has to be put in quotes for the first part of , but I'm kinda making an assumption about the other half of the statement.

I'm not entirely sure why you have 2 images for tops and 2 images for bottoms... but I don't need to know.
Because of the way I've written it, those other two variables aren't needed.


Now what I'd see as the alternative, using "normal" variables (available everywhere in the game's script)
and using a count of the number of pieces of clothing removed to decide whether to show an "Exit" button or not...
I'm also changing the underwear imagebutton so it is dependant on the removal of 2 items already. This could easily be the wrong way to do this, especially if a bra or panties suddenly appears from nowhere.
Doing it anyway, just to show the alternative way of coding things.



Python:
default girl_undress = 0
default girl_top = 0
default girl_bottom = 0

# this screen shows an exit button after the underwear is removed.

screen girl_cloth_remove():

       # Undress top

        if girl_top == 0:
            imagebutton:
                auto "top_1_%s.png"
                action SetVariable("girl_top", girl_top + 1)

        if girl_top == 1:
            imagebutton:
                auto "top_2_%s.png"
                action [ SetVariable("girl_top", girl_top + 1), SetVariable("girl_undress", girl_undress + 1) ]

        # Undress bottom

        if girl_bottom == 0:
            imagebutton:
                auto "bottom_1_%s.png"
                action SetVariable("girl_bottom", girl_bottom + 1)

        if girl_bottom == 1:
            imagebutton:
                auto "bottom_2_%s.png"
                action [ SetVariable("girl_bottom", girl_bottom + 1), SetVariable("girl_undress", girl_undress + 1) ]

        # Undress underwear

        if girl_undress == 2:                  # only show underwear after top and bottoms have been removed
            imagebutton:
                auto "underwear_%s.png"
                action SetVariable("girl_undress", girl_undress + 1)


        if girl_undress == 3:                  # only shown after underwear removed.
            textbutton "Exit":
                xalign 0.9
                yalign 0.8
                action Jump("finished_with_the_screen")

label start:

    scene black with fade
       

label show_the_screen_again:

    call screen girl_cloth_remove
    jump show_the_screen_again

label finished_with_the_sceen:

    "*** THE END ***"
    return

Again... untested.

Note that the variables are now outside the screen and part of the main script instead. Meaning their values can be checked after the screen has ended. Probably not needed here, but perhaps for other things.
Because the variables are no longer part of the screen, we use instead. This would be the way most people would do it, but only because most people aren't aware that screen variables are a thing.

The other new concept there is doing more than 1 action. In screen language, you do this by including a list of actions. Lists in python are represented by square brackets [ ] and separating each with a comma.

I doubt either of these solutions are exactly what you want. But hopefully, there's enough there that you figure out which bits fit your solution and which don't. At least so you can get to a point where the game will actually start.


Edit: The more I look at my code, the most I think it's wrong... and a therefore is a good example of why you need to test things.

I'm leaving it here rather than deleting the post because it shows the programming process. Do something, fuck it up, attempt to fix it, rinse and repeat until it works or you convince the client their specification was wrong.

If I'm remembering things correctly, any action will end the screen. So just setting variables is not enough.

It might be enough to immediately re-invoke the screen by including a list of actions, where the final action is ... and it triggers the same screen again. But then I'd be unsure if the screen variables would keep their same values the 2nd/3rd/etc times the screen is reshown... if you tried option #1.
Alternatively, write it so that you have label #1 .... call screen ... jump label #1 as a closed loop, then have the final action within the screen be jump label#2. I've adjusted my 2nd example to be something like that.
Some testing required me thinks.

And in case you're thinking of using python command directly within the screen... be careful. The that the screen may actually be run multiple times, even if the player only sees it appear once. I think this is because of the way RenPy handle caching of future events. The end result is that you add a line that does a = a + 1... and you think the answer should be 2... and it ends up being 78.
 
Last edited:

aPieceOfTissue

Newbie
Game Developer
Jan 22, 2019
40
86
I made it! Thank you so much for your help 79flavors . Here's how I do it:

Python:
label Clothes:
 
    #Dialogs here(before clothes remove)

    call GirlClothRemove

    #More dialogs here(after clothes remove)
    return

label GirlClothRemove:
    default girl_undress = 0
    default girl_top = 0
    default girl_bottom = 0
    default girl_under = 0

    call screen girl_cloth_remove

screen girl_cloth_remove:

    # Undress top
    if girl_top == 0:
        imagebutton:
            auto "girl_top_1_%s.png"
            action [ SetVariable("girl_top", girl_top + 1) ]
    if girl_top == 1:
        imagebutton:
            auto "girl_top_2_%s.png"
            action [ SetVariable("girl_top", girl_top + 1), SetVariable("girl_undress", girl_undress + 1) ]

    # Undress bottom
    if girl_bottom == 0:
        imagebutton:
            auto "girl_bottom_1_%s.png"
            action [ SetVariable("girl_bottom", girl_bottom + 1), SetVariable("girl_under", girl_under + 1) ]

    if girl_bottom == 1:
        imagebutton:
            auto "girl_bottom_2_%s.png"
            action [ SetVariable("girl_bottom", girl_bottom + 1), SetVariable("girl_undress", girl_undress + 1) ]

        # Undress underwear
    if girl_under == 1:
        imagebutton:
            auto "girl_underwear_%s.png"
            action [ SetVariable("girl_under", girl_under + 1), SetVariable("girl_undress", girl_undress + 1) ]

    if girl_undress == 3:
        textbutton "Exit":
            action [ SetVariable("girl_undress", girl_undress == 0), SetVariable("girl_top", girl_top == 0), SetVariable("girl_bottom", girl_bottom == 0), SetVariable("girl_under", girl_under == 0) ], Jump("GirlClothRemove2")


label GirlClothRemove2:
    #girl fully undressed now
    return
The reason for me having 2 images for tops and bottom is to showcase different stages of undressing, like "girl_top_1_%s.png" means the T-shirt is still on and "girl_top_2_%s.png" means the T-shirt is rolled up now.

Anyway, a huge thanks to you for helping me out and giving such a detailed instruction.