Skip to content
Feniks Development
  • Start Here
  • Glossary
  • Tools
  • Resources
  • What’s New
  • About
  • Contact
Toggle the button to expand or collapse the Menu

EasyBlink Class

  1. Home>
  2. Feniks Tools>
  3. EasyBlink Class

Easy Blinking

  • EasyBlink Class
  • EasyBlink Examples

Controller Support Expansion

  • What is the Controller Support Expansion?
  • How do I…? + Common Issues
  • Controller Viewport
  • Controller Bar
  • Virtual Cursor
  • Virtual Keyboard
  • StickEvent
  • KeyController and focused_on
  • FocusDisplayable
  • Remapping Controls
  • Controller and Keyboard Icons
  • Configuration Variables
  • Screen Actions and Values
  • Helper Functions and Classes
  • Engine Override Notes

Sound Disabler and Captions Tool

  • Disabling Sounds and Sound Categorization
View Categories
  • Home
  • Feniks Tools
  • Easy Blinking
  • EasyBlink Class

EasyBlink Class

7 min read

Easy Blinking for Ren’Py includes several features to make blinking as simple as possible in Ren’Py. Pick up the tool from itch.io if you haven’t already:

Contents hide
EasyBlink Attributes
path
img
blink_framerate
blink_repeat
double_blink_pct
numbered
start_no_num
mid_eye_frames
automatic_blink_frames
reverse
loop_start_frame
transitions
block_during_transition
sequence
Preference Variables

EasyBlink Attributes

The EasyBlink class has several attributes you can customize to suit how your blinking works.

path

The path where the eye images are found, so the image path can be put together with path + image names. It should include the substitution {img} which will be replaced with the image name. e.g. "characters/eileen/{img}.webp"

If numbered=True, it should also include a {num} substitution, which will be replaced with the number of the image. e.g. "characters/eileen/{img}{num}.webp". If it doesn’t include the {img} substitution, it must be a direct image path on its own.

It is also possible for the path to be any kind of Displayable, in which case the mid_eye_frames are expected to be displayables or direct image paths, and you cannot use numbered=True.

e.g. path="eileen_eyes_{img}"

img

This is a string which is substituted into the path‘s {img} format. In most cases, this is the name of an eye attribute in a layered image e.g. happy_e which, if given a path of eileen_eyes_{img} would result in the final image eileen_eyes_happy_e.

e.g. img="sad_e"

blink_framerate

The length of time between each blink frame. You can do 1.0/60.0 if you want this to be 60fps, for example. This can also be a list of times, which should be the same length as the number of frames your blink animation has.

e.g. blink_framerate = 0.04

e.g. blink_framerate = [0.04, 0.02, 0.02, 0.04]

blink_repeat

How many seconds to wait before blinking again, in the format: (min time, max time)

e.g. blink_repeat = (1.8, 4.5)

double_blink_pct

How often the character should blink twice in quick succession. 0.1 is 10%. If this is 0.0 then the character will never blink twice in a row.

e.g. double_blink_pct = 0.1

numbered

If True, the sequence of eye images is expected to be numbered. e.g. “happy_eyes0.webp”, “happy_eyes1.webp”, “happy_eyes2.webp” etc. It will keep looking for images until it can’t find any more. Note that the path should have a {num} substitution in it if using this.

e.g. numbered = False

start_no_num

If True, and numbered=True, then the first image in a numbered sequence will not have any number in it i.e. it will go: “happy_eyes.webp”, “happy_eyes1.webp”, “happy_eyes2.webp” etc.

e.g. start_no_num = False

mid_eye_frames

The naming convention of additional eye images. Used only if numbered=False. So, if this was ["half_closed", "closed"] then a path of "eileen/{img}_eyes.webp" and an img of "happy" would look for:

“eileen/happy_eyes.webp”, “eileen/half_closed_eyes.webp”, “eileen/closed_eyes.webp”

If the path doesn’t have an {img} substitution, then these should be direct image paths like ["eileen/half_closed_eyes.webp", "eileen/closed_eyes.webp"]

e.g. mid_eye_frames = ["closed"]

automatic_blink_frames

If not empty, this is a list of yzoom numbers to use for automatically generated blink frames. This works by squishing the open eye frame. For this to work, the image should have all transparency below the eyes trimmed away, so that the bottom of the eye illustration is at the bottom of the image. This image will be squished down starting from the top, so the bottom always stays in the same place. It does not look good for all eye images. Looks best if the character is facing the viewer or close to it.

A gif demonstrating automatic blink frames.
Agustina sprite by DejiNyucu on itch.io.

The eye image for the above effect looks like so:

An image of eyes looking to the side. There is no transparent space below the bottom of the eye.

Notice how there is no transparent space below the eyes.

e.g. automatic_blink_frames = [0.9, 0.8]

e.g. automatic_blink_frames = [ ]

reverse

If True, the animation will play in reverse after it’s done e.g. going from happy_eyes0 -> happy_eyes1 -> happy_eyes2 -> happy_eyes1 -> happy_eyes0

Otherwise it would go happy_eyes0 -> happy_eyes1 -> happy_eyes2 -> happy_eyes0

If you have a loop_start_frame (see below), then only frames starting from the start_frame are reversed (i.e. it does not reverse the “startup animation” frames).

e.g. reverse = False

loop_start_frame

This is the frame the animation should begin on when looping. For most cases this will be 0 (the first frame), but if you have 3 frames of “startup” before it starts looping, then you would set this to 3. Note that if reverse=True, the non-looping frames won’t be reversed. So, if frames 0, 1, 2 were “startup” and frames 3, 4, 5 were the loop, then it would play out as 0, 1, 2, 3, 4, 5, 4, 3, 4, 5, 4, 3 etc.

e.g. loop_start_frame = 0

transitions

This is the transition, or a list of such transitions, which should be used when switching between blink frames, or None for no transition. If it’s a list of transitions, it should be the same length as the number of blink images, *or* one less than the number of blink images if you’d like reverse=True to handle the transitions.

In the case that reverse=True, a list of transitions is reversed as follows: Say you have frames 0, 1, 2, 3, which will be reversed to get a full looping sequence of 0, 1, 2, 3, 2, 1, 0. Say your transitions are A, B, C – there are 3 of them because there are 4 total frames before they get reversed, so you need 3 transitions. reverse=True will set up the order to be 0 -> A -> 1 -> B -> 2 -> C -> 3 -> C -> 2 -> B -> 1 -> A -> 0, or in short, 0-A-1-B-2-C-3-C-2-B-1-A-0. You can see that the transition from 0->1 uses A, and so does the transition from 1->0.

e.g. transitions = Dissolve(0.1)

e.g. transitions = [Dissolve(0.2), Dissolve(0.25), Dissolve(0.2), None, None]

block_during_transition

Determines whether the game should block eye blinking while a transition is occurring. Note that this does not include transitions between eye images (as specified using transitions above); only transitions which are used for show statements and similar. If True, eyes will be shown in their open state only until the transition is completed.

e.g. block_during_transition = True

sequence

sequence provides an alternative way of providing information on transitions, blink_framerate, and mid_blink_frames to EasyBlink. It takes a list, which should have information in one of the following formats:

  • (img, framerate, transition) – This is a tuple with three items. The first is the image to use for this frame, the second is how long to hold on that frame for, and the third is the transition to use when transitioning to the next image.
    • e.g. sequence=[("open", 0.04, Dissolve(0.1)), ("semi", 0.04, Dissolve(0.1)), ("closed", 0.04, Dissolve(0.1))]
  • (img, framerate) – This is a tuple with two items. Like before, the first item is the image to use for this frame, and the second is how long to hold that frame for. The transition is assumed to be None.
    • e.g. sequence=[("agustina_cry0", 0.1), ("agustina_cry1", 0.1), ("agustina_cry2", 0.1)]
  • img – You can also just provide an image name, or optionally a list of numbers which will be used for automatic_blink_frames
    • e.g. sequence=["agustina_eyes_happy", [0.85], "agustina_eyes_closed"]
    • This will create a sequence where the second frame is the frame before it (“agustina_eyes_happy”) squished to 85% of its original height.

Note that you can mix and match these formats; for example, the following is valid:

e.g. sequence=[("normal", 0.1, Dissolve(0.1)), ("surprised", 0.2, Dissolve(0.1)), "normal", "side", [0.85], "closed"]

If you don’t provide a framerate for a given frame, it will be taken from blink_framerate, and if you don’t provide a transition, it will be taken from transitions. Note that if you supply sequence, then the value of img will be ignored – you should include it as the first item in the sequence.

Preference Variables

Easy Blinking also takes the following persistent variable into account:

default persistent.blinking_on = True

This is a persistent variable which determines whether blinking is on or off. You can adjust it as part of an animation or accessibility toggle. e.g.

textbutton "Toggle Blink Animations" action ToggleField(persistent, "blinking_on")
Updated on March 11, 2024
EasyBlink Examples

Leave a Reply Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© Copyright – Feniks with OceanWP
Close Menu