So, what this script does, assuming you have all elements (body, clothes and expressions) chopped up in separate pictures, is:
1. automate the linking of all displayables, so you don't have to write a single image = statement on your own
2. create dynamic composites out of all the possible combinations, so you just have to show your character and then control what is displayed through variables
Requirements
The code (of course):
Code: Select all
# ================================================================================
# Dynamic Paper Dolls 1.00
# Written by Moonpearl
# http://moonpearl-gm.blogspot.fr/
# --------------------------------------------------------------------------------
# A script for RenPy https://www.renpy.org/
# --------------------------------------------------------------------------------
# This piece of software is distributed under the terms of the Creative Commons
# Attribution 4.0 International (CC BY 4.0) license
# https://creativecommons.org/licenses/by/4.0/
# ================================================================================
# Snippet for getting .png image dimensions without using an external library
# Written by Corey Goldberg
# http://coreygoldberg.blogspot.fr/2013/01/python-verify-png-file-and-get-image.html
init python:
import struct
def get_image_info(data):
# if is_png(data):
w, h = struct.unpack('>LL', data[16:24])
width = int(w)
height = int(h)
# else:
# raise Exception('not a png image')
return width, height
# Doesn't work properly for some reason, so not using it but kept it here for reference
def is_png(data):
return (data[:8] == '\x89PNG\r\n\x1a\n' and data[12:16] == 'IHDR')
class DynamicImage2(DynamicImage):
def __init__(self, switch, child):
super(DynamicImage2, self).__init__(child)
self.switch = switch
def render(self, width, height, st, at):
if not eval(self.switch):
return renpy.Render(0, 0)
return super(DynamicImage2, self).render(width, height, st, at)
init:
# Define your poses here
define POSES = ("facing", "side")
# Define your characters here
define eileen = Character("Eileen")
# List all characters here
define paperdoll_characters = (eileen,)
# This creates the dynamic displayables for all of your characters
python:
for character in paperdoll_characters:
# Initializes the display control for each character
character.outfit = ""
character.expr = ""
name = character.name.lower()
for pose in POSES:
# Defines the displayables for each pose
basename = name + "-" + pose
renpy.image(basename + "-base", Image("{n}/{p}/base.png".format(n = name, p = pose)))
renpy.image(basename + "-outfit", DynamicImage2(name + ".outfit", "{n}/{p}/outfit/[{n}.outfit].png".format(n = name, p = pose)))
renpy.image(basename + "-expr", DynamicImage2(name + ".expr", "{n}/{p}/expr/[{n}.expr].png".format(n = name, p = pose)))
# Get the base image size
with open(renpy.os.path.join(renpy.config.basedir, "game\\images\\{n}\\{p}\\base.png".format(n = name, p = pose)), 'rb') as f:
data = f.read()
width, height = get_image_info(data)
# Create a composite out of the dynamic displayables
renpy.image(name + " " + pose,
LiveComposite(
(width, height),
(0, 0), basename + "-base",
(0, 0), basename + "-outfit",
(0, 0), basename + "-expr")
)
For each character, your folder structure should look like the following, assuming they all have 2 poses (facing and side) as defined in the script:
Code: Select all
[images]
[eileen]
[facing]
[outfit]
uniform.png
casual.png
swimsuit.png
[expression]
happy.png
sad.png
base.png
[side]
[outfit]
uniform.png
casual.png
swimsuit.png
[expression]
happy.png
sad.png
base.png
From there you just have to invoke the show statement for your character to assume a pose, and you control their outfit and facial expression through the character.outfit and the character.expr variables. You can set either back to "" or 0 to hide the clothing or the facial expression.
Example:
Code: Select all
label start:
show eileen side
$ eileen.outfit = "uniform"
eileen "Hello there!"
show eileen facing
$ eileen.expr = "happy"
eileen "I'm very happy to see you!"
$ eileen.expr = ""
eileen "So what do you want to do today?"