Sprite face changer example

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Post Reply
Message
Author
User avatar
KlastHalc
Newbie
Posts: 2
Joined: Sun Aug 20, 2023 8:52 am
itch: klast-halc
Location: Japan
Contact:

Sprite face changer example

#1 Post by KlastHalc »

Hello everyone.
I would like to post a sample script I wrote for my game.

This is an face change room. You can change the face of sprites on the game window. It may be for your development helper, your game's extra room , and so on.

This sample is Layeredimage (with auto) based.
It may look similar to Dress up Game Demo in LayeredImage Tutorial ( viewtopic.php?f=51&t=50764 ), but there is a difference. Adding another facial image during game development does not require any changes to the script. Buttons are automatically created referencing images stored in a specific folder.
(LayeredImage Tutorial is very nice, thank you to the developer!)

About init python block:
The user needs to set the sprite directory and part classification according to the sprite.
In development mode, this script searches for images by os.listdir and creates a list. If not, load the existing list.
screenshots.gif
You can download the sample game and script from itch.io:
https://klast-halc.itch.io/sprite-face-changer

Example of implementation in another game (movie):
https://youtu.be/YpwlyS1KjjY?si=B6ALw2b0Y4hF6wTc

I'm sorry if there are any problems with the script or if there is already a better script with the same functionality.

Code: Select all


image bg black = Solid("#303234")


#### Sprite Changer ##################################################################

# This sample script uses the layer image function. If you are unfamiliar with it, please check how to use it.

# Show Sprite Changer
label sprite_changer:

    $ quick_menu = False

    scene bg black
    with dissolve

    show screen sprite_changer()
    with dissolve

    pause



#  Hide Sprite Changer and return to MainMenu
label sprite_changer_return:

    hide screen sprite_changer
    scene bg black
    with dissolve

    return



### Sprite Setting
# (Caution) If you use "always" in layeredimage, you may need to customize the scripts contained in "init python" or "screen".
layeredimage jun:
    group body:    # Body
        attribute b0default default
    group eye auto:    # Eyes
        attribute e0default default
    group mouth auto:    # Mouth
        attribute m0default default
    group hair auto:    # Hair
        attribute h0default default

layeredimage nor:
    group body:    # Body
        attribute b0default default
    group eye auto:    # Eyes
        attribute e0default default
    group mouth auto:    # Mouth
        attribute m0default default
    group hair auto:    # Hair
        attribute h0default default



### Preparation of variables
init python:

    import pickle

    character_name_list = ["jun", "nor"]
    character_name_show = ["Jun", "Nor"]
    character_color = ["#bbccdd", "#ddccbb"]
    character_intro = []
    character_intro.append("A boring boy.")
    character_intro.append("A powerful girl.")

    # Part list: refer to the layeredimage defined above
    # If you change these, please change idx_xxxx below also.
    parts_name_list = ["body", "eye", "mouth", "hair"] # same as a part of file names.
    parts_name_show = ["BODY", "EYE", "MOUTH", "HAIR"] # show these text on the screen.

    # Sprite directory
    path_sprite = config.gamedir + "/images/sprite"
    # Path to save the list
    path_img_list_dump = config.gamedir + "/stripe_list.txt"

    # Generate the list of all characters and faces.
    # This work only under the developper mode. The list is saved in "path_img_list_dump".
    if config.developer:
        # Generate the list
        file_all = os.listdir(path_sprite)
        img_pickup = []
        for i in range(0, len(character_name_list)):
            img_pickup_tmp = []
            for i in range(0, len(parts_name_list)):
                img_pickup_tmp.append([])
            img_pickup.append(img_pickup_tmp)

        for i in file_all:
            if ".png" in i:
                tmp_split = i.split("_")
                if len(tmp_split) == 3:
                    chara_idx = character_name_list.index(tmp_split[0])
                    parts_idx = parts_name_list.index(tmp_split[1])
                    img_pickup[chara_idx][parts_idx].append(tmp_split[2].replace(".png", ""))

        with open(path_img_list_dump, mode="wb") as f_img_pickup:
            pickle.dump(img_pickup, f_img_pickup)

    else:
        # Load the list
        with open(path_img_list_dump, 'rb') as f_img_pickup:
            img_pickup = pickle.load(f_img_pickup)



screen sprite_changer():
    modal True

    default idx_chara = 0
    # Please define idx_xxxx consistent with "parts_name_list". Please be careful of typo.
    # These will be used at [!!!] parts. Please change them if you need.
    default idx_body = 0
    default idx_eye = 0
    default idx_mouth = 0
    default idx_hair = 0

    add "gui/nvl.png"


    # Character select buttons
    frame:
        xanchor 0.0 xpos 80
        yanchor 0.0 ypos 80

        vbox:
            label "NAME"

            for i in range(0, len(character_name_list)):
                textbutton str(character_name_show[i])

                    # [!!!]
                    action [SelectedIf(SetScreenVariable("idx_chara", i)), \
                    SetScreenVariable("idx_body", 0), \
                    SetScreenVariable("idx_eye", 0), \
                    SetScreenVariable("idx_mouth", 0), \
                    SetScreenVariable("idx_hair", 0)]

            null height 20

            textbutton "RETURN" action Jump("sprite_changer_return")


    # Face select buttons
    frame:
        xanchor 0.0 xpos 80
        yanchor 1.0 ypos 720-80

        hbox:
            spacing 4
            for h in range(0, len(img_pickup[idx_chara])):
                vbox:
                    label str(parts_name_show[h])
                    for i in range(0, len(img_pickup[idx_chara][h])):
                        textbutton str(img_pickup[idx_chara][h][i]) action SetScreenVariable("idx_"+parts_name_list[h], i) # [!!!]


    # Set which face will be shown.
    python:
        tmp_img_str = character_name_list[idx_chara]
        tmp_img_str = tmp_img_str + " " + img_pickup[idx_chara][0][idx_body]
        tmp_img_str = tmp_img_str + " " + img_pickup[idx_chara][1][idx_eye]
        tmp_img_str = tmp_img_str + " " + img_pickup[idx_chara][2][idx_mouth]
        tmp_img_str = tmp_img_str + " " + img_pickup[idx_chara][3][idx_hair]


    # Sprite
    add tmp_img_str xalign 0.9


    # Charactor introduction
    vbox:
        xanchor 0.0 xpos 280
        yanchor 0.0 ypos 100
        xsize 420
        spacing 10

        text character_name_show[idx_chara]:
            size 28
            color character_color[idx_chara]

        text character_intro[idx_chara]
        


Post Reply

Who is online

Users browsing this forum: Bing [Bot]