# Renpy Learning
## Screen Demo
### Simple Stats Screen
```python=3.8
default player_hp = 15
default player_hp_max = 42
default eileen_hp = 100
default eileen_hp_max = 100
default player_lv = 4
default eileen_lv = 99
screen single_stat(name, hp, hp_max, lv, xalign):
frame:
xalign xalign
vbox:
spacing 5
hbox:
text "[name!t]" min_width 220
text _(" Lv. [lv]")
hbox:
text _("HP"):
min_width 40
yalign 0.5
bar:
value AnimatedValue(hp, hp_max, 1.0)
xmaximum 180
ysize 26
text " [hp]/[hp_max]":
yalign 0.5
screen stats():
use single_stat(_("Player"), player_hp, player_hp_max, player_lv, 0.0)
use single_stat(_("Eileen"), eileen_hp, eileen_hp_max, eileen_lv, 1.0)
label: screens_demo:
$ player_hp = 15
show screen stats
with dissolve
e "This will show the stat screen"
$ player_hp = 42
e "This will change the screen with dissolve effect"
```
The screen will dynamically change if variables are changed Unitill `hide screen`

### More complicated Screen
```python=3.8
define day_periods = [ _('Morning'), _('Afternoon'), _('Evening') ]
define day_choices = [ _('Study'), _('Exercise'), _('Eat'), _('Drink'), _('Be Merry') ]
default day_plan = {
'Morning' : 'Eat',
'Afternoon' : 'Drink',
'Evening' : 'Be Merry'
}
default stat_strength = 10
default stat_intelligence = 25
default stat_moxie = 100
default stat_chutzpah = 75
style stat_text is default:
min_width 200
text_align 1.0
yalign 0.5
style stat_hbox is hbox:
spacing 10
style stat_vbox:
spacing 5
screen day_planner():
vbox: # Root Vbox
spacing 5
frame:
style_prefix "stat"
xpadding 100
xfill True
vbox:
hbox:
text _("Strength")
bar value StaticValue(stat_strength, 100)
hbox:
text _("Intelligence")
bar value StaticValue(stat_strength, 100)
hbox:
text _("Moxie")
bar value StaticValue(stat_strength, 100)
hbox:
text _("Chutzpah")
bar value StaticValue(stat_strength, 100)
# A grid of three frames, one for each of the periods in the day.
grid 3 1:
spacing 5
xfill True
for p in day_periods:
frame:
xfill True
vbox:
label p
null height 5
for i in day_choices:
textbutton i action SetDict(day_plan, p, i)
# This is a grid containing two empty space and the done button,
# so everything lines up.
grid 3 1:
xfill True
spacing 5
null
frame:
textbutton _("Done"):
action Return(True)
xfill True
text_xalign 0.5
null
label: screens_demo2:
show screen day_planner
with dissolve
e "Show the screen with dissolve"
hide screen day_planner
with dissolve
e "hide with dissolve"
```

### Show Screen
1. Screen will remain shown until hidden
2. A screen will be hidden when a call returns (Like the following)
```python=
screen simple_screen():
frame:
xalign 0.5 ypos 50
vbox:
text _("This is a screen.")
textbutton _("Okay"):
action Return(True)
call screen simple_screen()
```

### Parameters into Screen
```python=
screen parameter_screen(message, okay=Return(True), cancel=Return(False)):
frame:
xalign 0.5 ypos 50
vbox:
text "[message!t]"
textbutton _("Okay"):
action okay
textbutton _("Cancel"):
action cancel
show screen parameter_screen(_("Hello, world."), cancel=Notify(_("You can't cancel this."))) # pass two functions into a screen
with dissolve
```

## Screen Properties
### modal
`modal True` prevent interaction to anything behind this screen(even the conversation)
### tag
To prevent two screen showing together on the screen, use same tag name on both screen (kind of like mutex)
### zorder
Controls the order of the screen(on z-axis)
default zorder is 0, later come will shown in the front
### variant
`variant "small"` Determines which type of device will this screen be shown
### style_prefix
`style_prefix "red"` Any style defination with name ""red_xx" will be applied to this screen
### Python in screen
Same as script, use `$` as sigle line indicator and `python:` for multi-line.
`"[varname]"` to show variables in strings
python inside screen cannot have side-effects since those code will be run during screen prediction
### Use another screen in a screen
```python=
screen using_stats():
frame:
xalign 0.5 ypos 50
vbox:
use stat(_("Health"), 90) # uses stat screen defined below
null height 15
use stat(_("Magic"), 42)
screen stat(name, amount):
text name xalign 0.5
bar value StaticValue(amount, 100) xalign 0.5 xsize 250
```
### transclude
Pass child of the use statement into the position of `tranclude`
```python=
screen transclusion_example():
use boilerplate(): # All child of this line will be passed to transclude
text _("There's not much left to see.")
screen boilerplate():
frame:
xalign 0.5 ypos 50
vbox:
transclude # this line will be replaced by previous codes
```
## Screen Displayables
### Position properities
All Displayable supports position properities like align, anchor, pos, etc.
### transform
keyword `at` is used for a transform:
```python=
screen at_example():
frame:
xalign 0.5 ypos 50
text _("And the world turned upside down..."):
at rotated
transform rotated:
rotate 180 rotate_pad False
```
### style
all displayables can have a style tag:
```python=
style green_text:
color "#c8ffc8"
text _("Flight pressure in tanks.") style "green_text" # oneliner way
text _("Same Style, different code style."):
style "green_text"
```
style_prefix can set all styles of children:
```python=
screen style_prefix_example():
frame:
xalign 0.5 ypos 50
vbox:
vbox:
style_prefix "green"
text _("Flight pressure in tanks.")
text _("On internal power.")
```
### images
if image is in the image directory, can use name to refer.
```python=
add "logo base"
```
Can also use relative path to project root:
```python=
add "images/logo base.png"
```
Solid and other displayables can also be treated as an image
```python=
add Solid("#0000ff", xsize=234, ysize=360)
```
add statement also accepts transform properitites:
```python=
add "logo base" zoom 0.7 rotate 43.21
```
For more complex transform:
```python=
screen add_at_transform_example():
frame:
xalign 0.5 ypos 50
add "logo base" at unrotate
transform unrotate:
zoom 0.7 rotate 43.21
linear 1.0 rotate 0
```
### Text
represented by keyword `text`
in addition to common displayalbes properties, it also takes text style properties.
use `[variable]` to represent variables, and use {tag}word{/tag} to do inline styling
### Boxes and other layouts
Layout displayables: Takes its children and lay them out accordingly:
examples: `hbox`,`vbox`,`grid <x> <y>`
```python=
screen hbox_example():
frame:
xalign 0.5 ypos 50
hbox: # this is a layout displayable
spacing 10
text "1"
text "2"
```
`grid`: keyword `transpose True` can fill top-to-bottom instead of left-to-right
`has <keyword> <style>`: for all children of current layer, if they have keyword `<keyword>` in them, the style `<style>` will be applied.
### Windows and Frames
window are for dialogues and frames are for interactive elements
### Buttons
```python=
screen button_example():
frame:
xalign 0.5 ypos 50
button:
action Notify(_("You clicked the button."))
hovered Notify(_("You hovered the button."))
unhovered Notify(_("You unhovered the button."))
text _("Click me.") style "button_text"
```
Example of Button interaction:
```python=
screen button_heal_example():
default health = 42
frame:
xalign 0.5 ypos 50
button:
action SetScreenVariable("health", 100)
hbox:
spacing 10
text _("Heal") style "button_text" yalign 0.5
bar value AnimatedValue(health, 100, 1.0) yalign 0.5 xsize 200
```
### Bar
```python=
bar value StaticValue(66, 100) # two displyables
bar value AnimatedValue(n, 100, 0.5) style "bar"
bar value ScreenVariableValue("n", 100) style "slider" # two sliders
bar value ScreenVariableValue("n", 100) style "scrollbar"
# Vertical ones
bar value AnimatedValue(n, 100, 0.5) style "bar"
bar value ScreenVariableValue("n", 100) style "vslider" # vertials here
bar value ScreenVariableValue("n", 100) style "vscrollbar"
```
### viewport
Displays larger than screen
```python=
screen viewport_screen():
viewport:
xalign 0.5 ypos 50 xysize (700, 300)
xinitial 0.5 # initial position of scrollbar
yinitial 1.0
scrollbars "both"
spacing 5
draggable True
mousewheel True
arrowkeys True
add "bg band"
```
### imagemap
shows interactive parts with images stacked together.
Here is a simple example of what image to stack on at different actions
```python=
screen volume_imagemap_example():
imagemap:
xalign 0.5 ypos 50
idle "imagemap volume idle"
hover "imagemap volume hover"
selected_idle "imagemap volume selected_idle"
selected_hover "imagemap volume selected_hover"
insensitive "imagemap volume insensitive"
hotspot (237, 171, 126, 50) action Return(True)
hotbar (51, 96, 498, 52) value Preference("music volume")
```
An easier way to to have all the keywords in the image file so they can be searched automatically.
```python=
screen volume_imagemap_auto_example():
imagemap:
xalign 0.5 ypos 50
auto "imagemap volume %s"
hotspot (237, 171, 126, 50) action Return(True)
hotbar (51, 96, 498, 52) value Preference("music volume")
```
## Styles
### Basics
Style information come from four places:
- From displayable itself (all displayable can have style properities)
```python=
screen style1():
text _("This text is colored green."):
style "my_text" # <- Here
color "#c0ffc0" # <- Here
at examplepos
```
style properties with `text_` prefix will apply to text inside its scope
```python=
textbutton _("Danger"):
text_color "#c04040"
text_hover_color "#ff0000"
action Return(True)
```
- Argument of a image statement or character statement
```python=
image style2 = Text(_("This text is colored red."), color="#ffc0c0")
define egreen = Character("Eileen", who_color="#c8ffc8", who_bold=True, what_color="#c8ffc8")
```
- style statement. named style presets applied by reference
```python=
style blue_text:
color "#c0c0ff"
image style3 = Text(_("This text is colored blue."), style="blue_text")
```
If styles are not given, it will inherit from parent
Parent of a style is written as: `<xxx_parentName>`, and all style has a root inheritance of `default`
For example `blue_text` inherits from `text`, which inherits from `default`.
To assign parent, use `is` keyword:
```python=
style apple_text is text:
color "#c0c0ff"
```
Here is a way of apply apple_text on the `text` with style_prefix `apple`
```python=
text _("This text is colored green.") style_prefix "apple"
```
Here is a way to highlight selected button:
```python=
style styled_button_text: # keywords idle_, hover_, etc. will be handled for button coloring automaticlly
idle_color "#c0c0c0"
hover_color "#ffffff"
insensitive_color "#303030"
selected_idle_color "#e0e080"
selected_hover_color "#ffffc0"
screen style4():
default result = 1
frame:
style_prefix "styled"
xpadding 20
ypadding 20
at examplepos
vbox: # since styled contains button stats keyword, active key and inactive key will be colored in defined colors
textbutton "Button 1" action SetScreenVariable("result", 1) # on click result value will change
textbutton "Button 2" action SetScreenVariable("result", 2)
textbutton "Button 3" action None
show screen style4
with dissolve
```
### Position styles
- `xalign`, `yalign` align on screen
- `xmaximum`, `ymaximum` set max width and height, wrap too long ones
- `xsize`, `ysize` min and max are the same after this. (size is fixed)
- `area(<xpos>, <ypos>, <xsize>, <ysize>)` determin size and position
### Text styles
- inplicit style: a textbutton will have a style named `button_text` by default
- `bold True` set text to bold `italic True`, `underline True`, `strikethrough True`, `vertial True`
- `color #hexval` set color
- `first_indent <indent>` determine how for to indent the first line
- `font <font_name.ttf>` TruType and OpenType fonts are allowed
- `size` size of text
- `justify True` lining las character to the right, make spaces different length across lines
- `kerning -0.5` change char-to-char distances, negative make chars closer
- `line_leading <space_size>` put space before each line. `line_spacing <space_size>` put space between lines
- `outlines [(<width>, <color>, <xoffset>, <yoffset>)]` put outlines around text check [related document](https://www.renpy.org/doc/html/style_properties.html#style-property-outlines) for details
- `text_align <0-1>` align of text (on horizontal direction); 0.5 means centered. `yalign <0-1>` align on vertical direction
- `antialias False` default is true
- `adjust_spacing True` keep char relative spacing when window resized
- `layout nopreak` disable line breaks
### Window and Button Styles
Buttons are windows that are clickable
- pass style as parameter:
```python=
screen button(style):
default selected = "top"
frame:
xalign 0.5
ypos 50
background "#0004"
xsize 350
has vbox:
xalign 0.5
textbutton _("Top Choice"):
style style
action SetScreenVariable("selected", "top")
text_style "example_button_text"
textbutton _("Bottom Choice"):
style style
action SetScreenVariable("selected", "bottom")
text_style "example_button_text"
style example_button is default:
idle_background Frame("idle_background.png", 10, 10, tile=True)
hover_background Frame("hover_background.png", 10, 10, tile=True)
xalign 0.5
style example_button_text:
xalign 0.5
color "#404040"
hover_color "#4040c0"
show screen button('example_button')
```
1. For Text in button
- same as normal text style
2. For button itself
- `(idle|hover)_background <Frame>` apply background to button
- `xalign 0.5` center button
- `(left|right|top|bottom)_(padding|margin) <value>` or `(left_right)_padding <value>`, `(x|y)margin <value>` to set padding and margin for button
- `size_group <strName>` all window and button within same group have same size
- `(x|y)fill` Fill up space available by stretching background
- `(|selected_)foreground` provide a forground to button
- `(hover|activate)_sound` sound for button at different actions
- `focus_mask True` For partially transparent buttons, only non-transparent part of the button will be focused (by focus background image)
-
### bar styles
- A bar is made of a full image and an empty iamge.
- `bar_resizing True` resize the image and used instead of full size then crop
- `thumb <img>` show a indicator between full side and empty side
- `(left|right)_gutter <int>` area where thumb cannot be dragged into
- `bar_vertial True` vertical
### Grid Styles
- `hbox` and `vbox` present their child horizontally or vertically
- `(x|y)fill` same as button
- `first_spacing` spacing for the first element (for titling)
- `box_reverse` reverse order of elements
- `box_wrap` fill box till full then next row/column
- `(x|y)spacing` spacing for each element in table
- `fixed` fill all space it has, then show its children back to front
- `(x|y)fit` layout children of current fixed object, then fit itself to its children
- `order_reverse` show fron to back instead
```python=
screen fixed(style):
frame:
xalign 0.5
ypos 50
ypadding 20
xsize 500
ysize 400
frame:
style "empty"
background "#fff2"
fixed:
style style
add Transform("logo base", zoom=.9):
xpos 10
ypos 10
text "Ren'Py":
font "DejaVuSans.ttf"
xpos 150
ypos 220
size 80
outlines [ (2, "#333", 0, 0) ]
```
###