Page 1 of 1

How To Doll in Renpy, with attributes, clothes, animation and blinking

Posted: Thu Aug 31, 2017 8:17 pm
by CorruptedPants
I recently spent quite a bit of time trying to figure out "how2doll" in renpy.

"To Doll" means, you have a character and you can dress it up, or undress, change clothes, alternate facial expressions and hand gestures while only deriving from a set of components instead of providing an individual file for each possible composition. After I figured things out, the question of how it was done came up repeatedly, and I decided I write a quick example game just to show the basics for future reference. I also added blinking and animation mechanics to show how these concepts interact with each other.

How To Doll 1.0
Dropbox
MEGA

screenshot0001.png
screenshot0002.png
dollpics.png

Code: Select all

# How to make dolls with variables and image attributes
# using image attributes ("show eileen happy")
# and variables ("eileeniswearingclothes")
#
# Your best friends here are
# LiveComposite (Take multiple displayables and combine them into one)
# ConditionSwitch (evaluate variables and
#    display a picture based on the first one thats true)
# Transform (To zoom and position a doll in & out so it fits the scene just right)


image eileenhead:  # Now with blinking
    LiveComposite (
      (360,720), #assuming your dolls have a 360x720 format)
      (0,0), "eileen_head_base.png", # Assuming you have a "base head"
      (0,0), "eileen_neutral_face.png" # and you just impose a face on it
    )
    pause 4.0 # This is ATL. For 4 seconds, show the basic head...
    LiveComposite (
      (360,720),
      (0,0), "eileen_head_base.png",
      (0,0), "eileen_neutral_face_blink.png" # then blink for 0.1 seconds
    )
    pause 0.1
    repeat     # and repeat

image eileenhead happy:
    LiveComposite (
      (360,720),
      (0,0), "eileen_head_base.png",
      (0,0), "eileen_happy_face.png"
    )

image eileenbody:
    LiveComposite (
      (360,720),
      (0,0), "eileen_body_base.png",  #
      (0,0), ConditionSwitch ( # evaluates expressions
          "store.eileeniswearingclothes == True", "eileen_body_clothes.png",
          "True", Null()     # if eileen is not wearing clothes according to the
          )                # global, don't show anything additional.
      )                    # ConditionSwitch requires ONE of the conditions to
                          # always turn out true, so it's a good idea to have
                        # a "True", Null() at the end. Otherwise you get the
                        # most useless error message in all of ren'py

image eileenbody armsflailing: # Now with animation!
    LiveComposite (
        (360,720),
        (0,0), "eileen_body_base_armsflailing.png",  #
        (0,0), ConditionSwitch ( # evaluates expressions
            "store.eileeniswearingclothes == True", "eileen_body_clothes_armsflailing.png",
            "True", Null()     # see above
            ),
        )
    pause 0.4
    LiveComposite (
        (360,720),
        (0,0), "eileen_body_base_armsflailing2.png",  #
        (0,0), ConditionSwitch ( # evaluates expressions
            "store.eileeniswearingclothes == True", "eileen_body_clothes_armsflailing2.png",
            "True", Null()     # see above
            ),
        )
    pause 0.4
    repeat

image eileen: # neutral, boring eileen
    LiveComposite (
        (360,720),
        (0,0), "eileenhead", #neutral expression on face
        (0,0), "eileenbody"
        )


image eileen happy:
    LiveComposite (
        (360,720),
        (0,0), "eileenhead happy",
        (0,0), "eileenbody" # still no arms flailing
        )

image eileen superhappy:
    LiveComposite (
        (360,720),
        (0,0), "eileenhead happy",
        (0,0), "eileenbody armsflailing" # now she flails
        )

image eileen sarcastic:  # neutral face but arms flailing?
    LiveComposite (
        (360,720),
        (0,0), "eileenhead", #neutral expression on face
        (0,0), "eileenbody armsflailing" # now she flails
        )

image bg tokenbackground:
    "tokenbackground.jpg"
    zoom 2.0

transform halfright: # Halfright is zoomed out, making the doll smaller
    xpos 0.7
    xanchor 0.5
    zoom 0.7

transform fullcenter: # coming closer
    xpos 0.5
    xanchor 0.5
    zoom 1.0

transform wayclose: # zooming all the way in
    xpos 0.5
    xanchor 0.5
    zoom 1.5

define e = Character('Eileen', color="#c8ffc8")
label start:
    scene bg tokenbackground
    $ eileeniswearingclothes = True
    show eileen at halfright
    e "I guess I am feeling very neutral right now"
    e "Watch it for a bit, I'm actually blinking sometimes"
    show eileen superhappy at fullcenter with move
    e "ok now I am excited or something!"
    $ eileeniswearingclothes = False
    e "LETS GET NAKED YAAAY"
    show eileen sarcastic at wayclose
    e "You don't look as impressed as I hoped"

Re: How To Doll in Renpy, with attributes, clothes, animation and blinking

Posted: Fri Sep 01, 2017 1:54 am
by Taleweaver
Moved to the Cookbook.

Re: How To Doll in Renpy, with attributes, clothes, animation and blinking

Posted: Sun Sep 03, 2017 1:41 am
by polisummer
Great work! This really helps a lot for characters changing clothes based on game events.

Re: How To Doll in Renpy, with attributes, clothes, animation and blinking

Posted: Mon Oct 02, 2017 11:45 am
by OokamiKasumi
This is friggin' brilliant!
-- I wish I'd had this tutorial back when I was creating my Prince Ivan game. I had to figure it all out the hard way, and I never did get how to add ATL movement to LiveComposite.

Re: How To Doll in Renpy, with attributes, clothes, animation and blinking

Posted: Wed May 16, 2018 5:54 pm
by bosinpai
Looks like the upcoming Ren'Py will come with a new built-in feature for this :)
https://www.renpy.org/dev-doc/html/layeredimage.html

ConditionSwitch has a limitation: it can't be used along with transitions:
https://www.renpy.org/doc/html/displaya ... splayables
For completeness, this StateMachineDisplayable extension was addressing just that:
https://cute-demon-crashers.readthedocs ... phics.html
Hopefully, Layered Images will help.