The answer to that question is almost always "Yes". Frequently "Yes, but...".
One thing I need to correct pretty quickly though is that this is
call screen
, not
call
.
call
is a completely different RenPy/python statement and it behaves very differently at first glance. Those devs that learn how
call
works before they come across
call screen
often fall into the trap of assuming one behaves like the other, and get confused as a result
(I certainly did for a while). I don't believe that's the case here with you... I'm just covering all the angles.
Yup. Easily.
Though "easily" is relative.
obsessionau has already offered you one solution. As should be evident at this point, there are a lot more possibilities.
For example, I personally would use
action Jump("girl-label")
or perhaps
action Return("girl_name")
. I might also include code so that the list of girls still works, even if you haven't met/unlocked the girl yet.
Personally I don't like the use of
show screen
and the use of
label storyloop
, as doing it this way causes no end of problems for people
(like me) who use the "auto advance" functionality of RenPy. It relies on the
pause
stopping the game continuing so the player can pick a girl - but the
[auto]
quick_menu button craps all over that.
Almost certainly. I personally prefer
imagebutton
over something like
imagemap
+
hotspot
- mainly because
hotspot
can only create rectangular/square clickable areas. Though that could actually be appropriate here.
Then beyond that are the "artsy" aspects. Making it prettier than just a series of rectangular images. It could be made to look like a mobile phone screen for example or a diary or "little black book". Again, personally I have all the artistic abilities of a lump of coal, so I'd probably only go as far as making the images circular rather than square.
Taking
obsessionau's code as my starting point and calling my girls "Amber", "Bella", "Chloe", "Dawn", "Emma" and "Fiona".
First, a version of the code that uses
action Jump()
...
Python:
default amber_available = False
default bella_available = False
default chloe_available = False
default dawn_available = False
default emma_available = False
default fiona_available = False
label start:
scene black with fade
"*** THE START ***"
$ amber_available = True
$ emma_available = True
label storyloop:
scene room with fade
call screen displayGirls
label the_end:
scene black with fade
"*** THE END ***"
return
label ambers_story:
"*** BLAH, BLAH, Amber ***"
jump storyloop
label bellas_story:
"*** BLAH, BLAH, Bella ***"
jump storyloop
label chloes_story:
"*** BLAH, BLAH, Chloe ***"
jump storyloop
label dawns_story:
"*** BLAH, BLAH, Dawn ***"
jump storyloop
label emmas_story:
"*** BLAH, BLAH, Emma ***"
jump storyloop
label fionas_story:
"*** BLAH, BLAH, Fiona ***"
jump storyloop
screen displayGirls():
zorder 1
modal True
vbox:
xpos 650
ypos 330
spacing 10
hbox:
spacing 10
if amber_available:
imagebutton:
background "amber_portrait.png"
idle "amber_portrait.png"
hover "hilight.png"
action Jump("ambers_story")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
if bella_available:
imagebutton:
background "bella_portrait.png"
idle "bella_portrait.png"
hover "hilight.png"
action Jump("bellas_story")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
if chloe_available:
imagebutton:
background "chloe_portrait.png"
idle "chloe_portrait.png"
hover "hilight.png"
action Jump("chloes_story")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
hbox:
spacing 10
if amber_available:
imagebutton:
background "dawn_portrait.png"
idle "dawn_portrait.png"
hover "hilight.png"
action Jump("dawns_story")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
if emma_available:
imagebutton:
background "emma_portrait.png"
idle "emma_portrait.png"
hover "hilight.png"
action Jump("emmas_story")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
if fiona_available:
imagebutton:
background "fiona_portrait.png"
idle "fiona_portrait.png"
hover "hilight.png"
action Jump("fionas_story")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
textbutton "[ Exit ]":
xalign 0.5
action Jump("the_end")
Please don't let the length of my example overwhelm you. This is more or less the same as the other code - except I've got checks in to see if the girl is available and to show a different image if she's not. I've also spread the parameters downwards rather than horizontally - if only to show that it can be done that way.
I've also added
modal True
, which force RenPy to ignore all clickable areas that are not part of this
screen
. This screen becomes the focus of the player choices and the player is forced to interact with this screen before continuing.
Now the limitation of this design is that the girl selection menu can only be used to jump to those specific labels. It isn't very flexible as a solution.
Enter
action Return()
stage right...
Python:
default amber_available = False
default bella_available = False
default chloe_available = False
default dawn_available = False
default emma_available = False
default fiona_available = False
label start:
scene black with fade
"*** THE START ***"
$ amber_available = True
$ emma_available = True
label storyloop:
scene room with fade
call screen displayGirls
if _return == "amber":
jump ambers_story
elif _return == "bella":
jump bellas_story
elif _return == "chloe":
jump chloes_story
elif _return == "dawn":
jump dawns_story
elif _return == "emma":
jump emmas_story
elif _return == "fiona":
jump fionas_story
label the_end:
scene black with fade
"*** THE END ***"
return
label ambers_story:
"*** BLAH, BLAH, Amber ***"
jump storyloop
label bellas_story:
"*** BLAH, BLAH, Bella ***"
jump storyloop
label chloes_story:
"*** BLAH, BLAH, Chloe ***"
jump storyloop
label dawns_story:
"*** BLAH, BLAH, Dawn ***"
jump storyloop
label emmas_story:
"*** BLAH, BLAH, Emma ***"
jump storyloop
label fionas_story:
"*** BLAH, BLAH, Fiona ***"
jump storyloop
screen displayGirls():
zorder 1
modal True
vbox:
xpos 650
ypos 330
spacing 10
hbox:
spacing 10
if amber_available:
imagebutton:
background "amber_portrait.png"
idle "amber_portrait.png"
hover "hilight.png"
action Return("amber")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
if bella_available:
imagebutton:
background "bella_portrait.png"
idle "bella_portrait.png"
hover "hilight.png"
action Return("bella")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
if chloe_available:
imagebutton:
background "chloe_portrait.png"
idle "chloe_portrait.png"
hover "hilight.png"
action Return("chloe")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
hbox:
spacing 10
if amber_available:
imagebutton:
background "dawn_portrait.png"
idle "dawn_portrait.png"
hover "hilight.png"
action Return("dawn")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
if emma_available:
imagebutton:
background "emma_portrait.png"
idle "emma_portrait.png"
hover "hilight.png"
action Return("emma")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
if fiona_available:
imagebutton:
background "fiona_portrait.png"
idle "fiona_portrait.png"
hover "hilight.png"
action Return("fiona")
else:
imagebutton:
idle "questionmark_portrait.png"
action NullAction()
textbutton "[ Exit ]":
xalign 0.5
action Return("the_end")
At first glance, these examples are almost identical
(deliberately on my part), however the second one is much more flexible. As
call screen displayGirls
can be used and reused in different ways throughout the game. I might even go so far as to rename the screen
screen girlChooser()
I'm effectively using
action Return()
to return a string back to the game. That string is stored in a reserved variable called
_return
and it's that I check when I return from the
call screen
.
This solution isn't no better or worse than any other solution. Obviously, I prefer it... but then I would, wouldn't I?
Honestly, this is not how I would actually end up writing it right now. I recently discovered Lists, Dicts and other array type variables. I'd probably have a custom
Class
to store the list of girls names, the filename of their image and whether they have been unlocked or not yet. Then I'd remove most of the
screen
code and add a loop to extract the information from my custom List to build the screen dynamically. It's all just about keeping things as simple as possible, depending on what you already know.
Hope this helps. If only to compare with the other solutions offered.