• Search is back up, but the index is being rebuilt, there may still be some minor problems until this is complete.

Ren'Py What is the EXACT script for an imagebutton screen and WHERE do I put it?

KinksterKitty

Member
Jul 28, 2017
146
144
So, in my Ren'Py Visual Novel, I have an element of walking in it. Think of it as a maze.

So it would be like this:

[Text+Images] then... [Maze] Followed by... [Text+Images] and then [Maze]

Now, I thought this would be a walk in the park, but of course it wasn't (Silly me :D)

First I started trying with a simple screen with Image Buttons, but oh hohoho! Was I wrong!

All I want to do, is the text to transition to a corridor. In said corridor there is an arrow. When you press that arrow, you go to the next room. Thats it.

Where can I find a code for something like that? And where do I put it? Do I put the code in SCRIPT, OPTIONS, GUI or somewhere else?

The imagebutton guide on the RenPy forum does not help, as it does not tell me WHERE I am supposed to put the code. Further more, the Renpy example is for replacing the main menu, which I do not want to do. I, again, just want a corridor with an arrow that transitions to the next room.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
I'm not entirely sure I'm following your "text transitions to a corridor"... but let me have a crack at it.

Okay... first things first, RenPy will cope if you put your bits of code anywhere. The default names are just that... defaults. You could rename script.rpy to wibble.rpy and RenPy wouldn't care. It scoots through all *.rpy and *.rpyc files at the start (even the ones stored inside an .RPA archive) and processes the contents, not based on the file name.

All that said, conventions exist for a reason... and so it's easier to keep those script.rpy, options.rpy, etc. files... because they make sense.

Normally your imagebutton: would be part of a screen definition and that would be stored within the screens.rpy file.
You'd build up a screen with a background image, overlaid with images for anything you want to click on (these are your idle images) and a second version of those same "buttons" that is highlighted in some way (your hover image).

Both images are a format that support transparency (PNG or WEBP generally). Anything that isn't transparent become clickable. Anything that is transparent (0% alpha) isn't. This is controlled by the focus_mask parameter.

I usually make the imagebutton: idle and hover images the same size as the background image with lots of transparent area - since it means I'm doing all the alignment and positioning in something like GIMP or Photoshop and not within RenPy code.
But if you want to use smaller images the same size as your buttons/arrows and position them with pos=(x,y) or xpos=x, ypos=y that works too.

A neat UI trick is the make the hover image slightly bigger than the idle image... perhaps with a sort of glowing edge or halo. So when the imagebutton: idle image captures your mouse cursor and activates the hover image - it takes a little more effort to move the mouse away from the button.

I have an example of what I'm talking about here : https://f95zone.to/threads/finding-...-point-click-game-on-renpy.25325/post-1565577

Maybe scroll up a few posts too. Rich's post includes actual code examples and was the basis for my own post.

So if you had a corridor with 4 arrows... You'd start with a background image, then 1x idle and 1x hover image for each arrow. For a total of 9 images and 4x imagebutton: definitions (one for each arrow). Each imagebutton: would have an associated label that the program jumps to when the arrow is pressed.

So now we're back to the code...

You reach a point in your program where you've displayed some text and now want the player to pick an arrow. So you do a call screen {screen-name} probably in your script.rpy. It shows all the elements of your screen... including the background image and the four clickable arrows.

You might want to even show the background image for the corridor, display some lines of dialogue before actually calling the screen to show the arrows and let the player pick their destination.

When the player clicks an arrow, the program jumps to whatever line of code you've specified in the screen definition. From there - it's up to you. Show new pictures. Display new dialogue... Whatever. Including calling another screen with more clickable areas.

Most of the stuff that will be going on will be within your script.rpy file, except the actual definition of the screen and it's clickable areas (and where those clickable spots jump to within your code).

Obviously, I've talked about 4 arrows. It could be one. It could be a vase or a light switch or a person or a doorway. It's purely about your imagination.

As I've said in the other post I linked... I found a good example to look at was , which you'll need to unpack using a tool like . Thankfully it's use of imagebuttons (for buildings in this case) is really near the beginning of the game... so you can play it a bit... see how it works from a user standpoint... and then use UnRen to pick apart how it's actually doing things and the images it's stitching together to make things clickable.

The code I personally wrote eventually ended up in Cuntswell Academy. That's not right at the beginning of the gameplay, but the actually code is probably a bit simpler to pick apart (in my opinion). Obviously any game with irregular shapes as clickable areas is probably doing more or less the same thing.
 

KinksterKitty

Member
Jul 28, 2017
146
144
I'm not entirely sure I'm following your "text transitions to a corridor"... but let me have a crack at it.

Okay... first things first, RenPy will cope if you put your bits of code anywhere. The default names are just that... defaults. You could rename script.rpy to wibble.rpy and RenPy wouldn't care. It scoots through all *.rpy and *.rpyc files at the start (even the ones stored inside an .RPA archive) and processes the contents, not based on the file name.

All that said, conventions exist for a reason... and so it's easier to keep those script.rpy, options.rpy, etc. files... because they make sense.

Normally your imagebutton: would be part of a screen definition and that would be stored within the screens.rpy file.
You'd build up a screen with a background image, overlaid with images for anything you want to click on (these are your idle images) and a second version of those same "buttons" that is highlighted in some way (your hover image).

Both images are a format that support transparency (PNG or WEBP generally). Anything that isn't transparent become clickable. Anything that is transparent (0% alpha) isn't. This is controlled by the focus_mask parameter.

I usually make the imagebutton: idle and hover images the same size as the background image with lots of transparent area - since it means I'm doing all the alignment and positioning in something like GIMP or Photoshop and not within RenPy code.
But if you want to use smaller images the same size as your buttons/arrows and position them with pos=(x,y) or xpos=x, ypos=y that works too.

A neat UI trick is the make the hover image slightly bigger than the idle image... perhaps with a sort of glowing edge or halo. So when the imagebutton: idle image captures your mouse cursor and activates the hover image - it takes a little more effort to move the mouse away from the button.

I have an example of what I'm talking about here : https://f95zone.to/threads/finding-...-point-click-game-on-renpy.25325/post-1565577

Maybe scroll up a few posts too. Rich's post includes actual code examples and was the basis for my own post.

So if you had a corridor with 4 arrows... You'd start with a background image, then 1x idle and 1x hover image for each arrow. For a total of 9 images and 4x imagebutton: definitions (one for each arrow). Each imagebutton: would have an associated label that the program jumps to when the arrow is pressed.

So now we're back to the code...

You reach a point in your program where you've displayed some text and now want the player to pick an arrow. So you do a call screen {screen-name} probably in your script.rpy. It shows all the elements of your screen... including the background image and the four clickable arrows.

You might want to even show the background image for the corridor, display some lines of dialogue before actually calling the screen to show the arrows and let the player pick their destination.

When the player clicks an arrow, the program jumps to whatever line of code you've specified in the screen definition. From there - it's up to you. Show new pictures. Display new dialogue... Whatever. Including calling another screen with more clickable areas.

Most of the stuff that will be going on will be within your script.rpy file, except the actual definition of the screen and it's clickable areas (and where those clickable spots jump to within your code).

Obviously, I've talked about 4 arrows. It could be one. It could be a vase or a light switch or a person or a doorway. It's purely about your imagination.

As I've said in the other post I linked... I found a good example to look at was , which you'll need to unpack using a tool like . Thankfully it's use of imagebuttons (for buildings in this case) is really near the beginning of the game... so you can play it a bit... see how it works from a user standpoint... and then use UnRen to pick apart how it's actually doing things and the images it's stitching together to make things clickable.

The code I personally wrote eventually ended up in Cuntswell Academy. That's not right at the beginning of the gameplay, but the actually code is probably a bit simpler to pick apart (in my opinion). Obviously any game with irregular shapes as clickable areas is probably doing more or less the same thing.
Thanks for the help.

Now, if we look at your example in the thread you gave me:


screen sc_party_livingroom():
modal True

add bg_party_livingroom

imagebutton auto "bt_party_livingroom_girls_%s.png":
focus_mask True
action Jump ("intro_talk_to_girls")



Where in the script would I put this? Would it look something like this:

#label start (ThiS STarTs THe GAm3)

"Duck" "I am the overlord of the realm known as Detroit"

"NonDuck" "Prove it by solving my ducking maze"

screen duckmaze1():
modal True

add duckmaze1

imagebutton auto "arrowDOWN":
focus_mask True
action Jump ("duckmaze2")

"NonDuck" "Fool! You have solved my maze!"


I also notice everyone puts in percentages in their file names, why?
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
I also notice everyone puts in percentages in their file names, why?
That's actually the quickest to answer... so I'll do that and come back to the actual code later.

The %s is linked to the auto option.
Essentially what it does is look for matching images files by putting "idle" and "hover" into the filename for you. If it finds a matching filename for each of the various combinations it thinks you could use, it expands the definition to use it.

So imagebutton auto "bt_party_livingroom_girls_%s.png" matched filenames for:
  • bt_party_livingroom_girls_idle.png
  • bt_party_livingroom_girls_hover.png
and when it finds a matching filename... you end up with a idle and hover definition.

The alternative is doing it longhand and ending up with something like:

Python:
screen sc_party_livingroom():
    modal True

    add bg_party_livingroom

    imagebutton:
        idle "bt_party_livingroom_girls_idle.png"
        hover "bt_party_livingroom_girls_hover.png"
        focus_mask True
        action Jump ("intro_talk_to_girls")
(I'm not 100% on that code... but it's probably close enough for my example.)

As you can see... you end up having to define an image for each state. In this case, idle and hover.

But there are lots of other states that an imagebutton can use...
idle, hover, insensitive, selected_idle and selected_hover.

Typing up 2 lines for idle and hover might not be too much of a pain in the arse. But if you chose to use all 5... that's a lot of extra typing. Hence the %s substitution.

For reference, selected_idle and selected_hover are handy if you're primarily targeting an android or other smartphone/tablet device. Where you want to highlight the button when the player clicks on it - because tablet devices tend not to have a cursor... so the hover image isn't automatically something the player would see. insensitive... fuck knows.
 
Last edited:

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,581
2,219
Very, very rough version of what you've quoted...

This will use 3 images.
  • duckmaze1.jpg
  • arrowDOWN_idle.png
  • arrowDOWN_hover.png

Python:
(screens.rpy)

screen duckmaze1():
    modal True

    add duckmaze1.jpg

    imagebutton auto "arrowDOWN_%s.png":
        focus_mask True
        action Jump ("duckmaze2")
(not sure the .jpg and .png parts of the filename are actually needed)


Python:
(script.rpy)

default duck_name = "Duck"
default nonduck_name = "Non Duck"

define duck = Character("[duck_name]", color="#F2F5A9")
define nonduck = Character("[nonduck_name]", color="#FF0080")

label start: # (ThiS STarTs THe GAm3)

    scene black with fade
    duck "I am the overlord of the realm known as Detroit"

    scene duckmaze with dissolve
    nonduck "Prove it by solving my ducking maze"

    call screen duckmaze1

    nonduck "You failed!"
    jump theend

label duckmaze2:

    nonduck "Fool! You have solved my maze!"

    $ duck_name = "Detroit Overlord"
    duck "See... I told you!"

    jump theend

label theend:

    "<<< THE END >>>"

    return
I've typed that up freehand, without testing it in RenPy. It probably doesn't work and might need a little tweaking.
But I hope it gets across the various elements and how they're used.

Edit: I don't think it's possible to reach the "You failed!" as things stand. So if you're thinking "that makes no sense"... you'd be right.

The reason I've made the duck and nonduck names variables is that I'm starting to get into the habit of coding things so that the player can change the names if they want to. Maybe I don't give the option, but the code allows for it. I've updated my example to make use of it doing something similar to that.
 
Last edited: