Hi all, I'm currently working on my first Ren'Py game, I first tried Tyranobuilder but after my UI drastically and annoyingly changed after an update I decided the engine wasn't too stable and switched to Ren'Py. As you can imagine, I'm a noob when it comes to coding, my main focus is art and story.
So I have these sprites:
(annnnd I've noticed some things I need to clean up)
As you can see my character has various different states:
- Braided vs. loose hair
- Sweater vs. Nightgown
- Beatup vs. Alright
Now based on how the image's layers originally work, I made four bases:
- Sweater with Braids
- Sweater with Loose Hair
- and the same with the Nightgown
And I cut up all eyebrows, eyes, and mouths based on this tutorial:
https://www.youtube.com/embed/08HKfXMr1kY
How do I go about switching between the four different bases? I can't just have two true or false statements about the same body part, right?
Plus, how do I go about switching between the bruised eye and the non-bruised eye most efficiently? Do I make individual folders for "HappyBruised" "SideglanceBruised", etc. etc?
I have a bruised version of every kind of eye expression, so if they could remain in the same folder that'd be great. Plus my other issue is that in this tutorial, the blink animation is just one frame and the blink is outside of the expression folders. My blinks are custom for each expression and I also have a longer eyeroll animation.
Implementing all of this in code would cost a lot of time and I'm starting to wonder if .webm videos would be quicker. But if I were to use .webms I'm worried that it would take up more space, plus I'm a bit worried that if I were to use webms the talking wouldn't stop correctly as opposed to this method?
Thank you in advance.
Optimal Implementation of Animated Character Sprites
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Re: Optimal Implementation of Animated Character Sprites
Amazing artwork!
There are different ways of doing it, the easiest of which is probably to use LiveComposite Dynamic Images. Unfortunately this isn't in the documentation yet but in the changelog: https://www.renpy.org/doc/html/changelo ... mic-images
Dynamic images are basically images with filenames that contain variables. LiveComposite can put multiple filenames (with variables) into a single image.
So you'll need some variable names specified for the character's different states:
hair = "braided" / "loose"
bruised = "bruised" / "normal"
mood = "happy" / "sad" / "angry"
clothing = "gown" / "sweater"
etc.
It's up to you whether you sort them into folders or not. I'm going to assume you have a folder for each of the layers.
If you're doing this to multiple characters, then you're best making them object attributes, but we can come back to that later if you need help with that.
Now your LiveComposite can look something like this:
With this setup, you can be extremely lazy and only ever show 1 version of your character image, and the variables will decide what your character looks like. There're also variations on how to animate the blinking and talking using separate animated layers - however it's a bit more complicated to do variation of bruised / non-bruised eyes versions with ConditionSwitches I think. So I've gone for the simplest approach. Perhaps start here and see if you need more a complex solution?
There are different ways of doing it, the easiest of which is probably to use LiveComposite Dynamic Images. Unfortunately this isn't in the documentation yet but in the changelog: https://www.renpy.org/doc/html/changelo ... mic-images
Dynamic images are basically images with filenames that contain variables. LiveComposite can put multiple filenames (with variables) into a single image.
So you'll need some variable names specified for the character's different states:
hair = "braided" / "loose"
bruised = "bruised" / "normal"
mood = "happy" / "sad" / "angry"
clothing = "gown" / "sweater"
etc.
It's up to you whether you sort them into folders or not. I'm going to assume you have a folder for each of the layers.
If you're doing this to multiple characters, then you're best making them object attributes, but we can come back to that later if you need help with that.
Now your LiveComposite can look something like this:
Code: Select all
# this will make Ren'py load the "speaking" version of your image when character is talking
config.speaking_attribute = "speaking"
image eileen = LiveComposite(
(300, 600), # (width, height)
(0, 0), "base/[clothing].png", # keep at (0, 0) if all your images are the same dimensions, it's the left top coordinate otherwise.
(0, 0), "face/[mood]-[bruised].png", # or gif if eye blinks are incorporated?
(0, 0), "hair/[hair].png",
)
# speaking version of the image
image eileen speaking = LiveComposite(
(300, 600), # (width, height)
(0, 0), "base/[clothing].png", # keep at (0, 0) if all your images are the same dimensions, it's the left top coordinate otherwise.
(0, 0), "face/speaking-[mood]-[bruised].gif",
(0, 0), "hair/[hair].png",
)
Re: Optimal Implementation of Animated Character Sprites
Thank you very much!
The hair and clothes are both on the base, so there are four bases.
Luckily all my other characters wear masks so I won't have to deal with inputting animations. (Unless I end up adding animations anyway lol)
I adjusted the code a bit. Originally I just put all the different types of mouths, eyes and eyebrows in folders rather than putting the expressions together. So I separated them based on that.
Some questions about this:
- 1. Are the bruised/speaking variable in each others way? Do they annul each other and how can I make sure that they won't?
- 2. I had an error starting the game up with "##config.speaking_attribute = "speaking", even though I hadn't declared that my character should be speaking in the script? Do I need to add a "$ speaking = False"?
- 3. I thought .gifs didn't work? If they did it would be very convenient for the eyes and mouth.
- 4. Concerning the eyes in particular, I have different animations for the eyes with a different amount of frames, so one has 3 images, it goes from 1 to 3 and 3 to 1. And I have one that consists out of 4 images. Not just that, I also have an eyeroll animation of 11 frames. I could cut it out altogether if coding it will be too much of a pain though. Following the tutorial that I watched, I'm not sure how to properly implement that, seeing as it deals with a constant amount of frames for the eyes.
-5. Scaling is kind of an issue, my portrait is too big, I made it wanting it to be big and wanting to scale it down how do I do this in livecomposite? Or do I need to do this in a separate line?
- 6. have a question about the width/height in this line:
Rather than it being width and height it seems to be about the positioning of the image? (xalign 1.0, yalign 1.0) gives a syntax error. I'd like to pin my height at a certain y-position, have it raise slightly when the character is talking, and move it to the side when another character is on screen manually later. How can I do this?
I hope this isn't too much and I'm not asking dumb things haha orz. Either way thank you very much for your time and quick reply, appreciate it!
The hair and clothes are both on the base, so there are four bases.
Luckily all my other characters wear masks so I won't have to deal with inputting animations. (Unless I end up adding animations anyway lol)
I adjusted the code a bit. Originally I just put all the different types of mouths, eyes and eyebrows in folders rather than putting the expressions together. So I separated them based on that.
Code: Select all
# this will make Ren'py load the "speaking" version of your image when character is talking
##config.speaking_attribute = "speaking"
##config.bruised_attribute = "bruised"
default iris_clothing = "SweaterBraids"
default iris_mood = "NeutralBig" #The Moods are: Angry, Calm, Eyeroll, Glance, Happy, HappyClosed, Neutral, NeutralBig, Nostalgic, Sad, Shock, Smug, Surprise, Thinking)
image iris = LiveComposite(
(530, 630), # (width, height)
(0, 0), "Iris/Base/[iris_clothing].png", # keep at (0, 0) if all your images are the same dimensions, it's the left top coordinate otherwise.
(0, 0), "Iris/Eyebrows/[iris_mood]/eyebrows.png", # or gif if eye blinks are incorporated?,
(0,0), "Iris/Eyes/Normal/[iris_mood]/eyes.png", #or gif if eye blinks are incorporated?,
(0,0), "Iris/Mouths/[iris_mood]/mouth.png"
)
# speaking version of the image
image iris speaking = LiveComposite(
(530, 630), # (width, height)
(0, 0), "Iris/Base/[iris_clothing].png", # keep at (0, 0) if all your images are the same dimensions, it's the left top coordinate otherwise.
(0, 0), "Iris/Eyebrows/[iris_mood]/eyebrows.png", # or gif if eye blinks are incorporated?,
(0,0), "Iris/Eyes/Normal/[iris_mood]/eyes.png", #or gif if eye blinks are incorporated?,
(0,0), "Iris/Mouths/[iris_mood]/speaking-mouth.png"
)
# bruised version of the image
image iris bruised = LiveComposite(
(530, 630), # (width, height)
(0, 0), "Iris/Base/[iris_clothing].png", # keep at (0, 0) if all your images are the same dimensions, it's the left top coordinate otherwise.
(0, 0), "Iris/Eyebrows/[iris_mood]/eyebrows.png", # or gif if eye blinks are incorporated?,
(0,0), "Iris/Eyes/Bruised/[iris_mood]/eyes.png", #or gif if eye blinks are incorporated?,
(0,0), "Iris/Mouths/[iris_mood]/mouth.png"
)
- 1. Are the bruised/speaking variable in each others way? Do they annul each other and how can I make sure that they won't?
- 2. I had an error starting the game up with "##config.speaking_attribute = "speaking", even though I hadn't declared that my character should be speaking in the script? Do I need to add a "$ speaking = False"?
- 3. I thought .gifs didn't work? If they did it would be very convenient for the eyes and mouth.
- 4. Concerning the eyes in particular, I have different animations for the eyes with a different amount of frames, so one has 3 images, it goes from 1 to 3 and 3 to 1. And I have one that consists out of 4 images. Not just that, I also have an eyeroll animation of 11 frames. I could cut it out altogether if coding it will be too much of a pain though. Following the tutorial that I watched, I'm not sure how to properly implement that, seeing as it deals with a constant amount of frames for the eyes.
-5. Scaling is kind of an issue, my portrait is too big, I made it wanting it to be big and wanting to scale it down how do I do this in livecomposite? Or do I need to do this in a separate line?
- 6. have a question about the width/height in this line:
Code: Select all
LiveComposite(
(530, 630), # (width, height)
I hope this isn't too much and I'm not asking dumb things haha orz. Either way thank you very much for your time and quick reply, appreciate it!
Re: Optimal Implementation of Animated Character Sprites
The approach I went for was to make bruised a variable, so that if you show iris - it automatically knows whether to show the bruised or unbruised version. I haven't played with the speaking variant with different images, but I expect if you have an iris bruised speaking image - then they won't conflict. Personally I'd do:- 1. Are the bruised/speaking variable in each others way? Do they annul each other and how can I make sure that they won't?
Code: Select all
image iris bruised = LiveComposite(
(530, 630), # (width, height)
(0, 0), "Iris/Base/[iris_clothing].png",
(0, 0), "Iris/Eyebrows/[iris_mood]/eyebrows.png",
(0,0), "Iris/Eyes/[iris_bruised]/[iris_mood]/eyes.png",
(0,0), "Iris/Mouths/[iris_mood]/mouth.png"
)
Apologies I missed the define keyword:- 2. I had an error starting the game up with "##config.speaking_attribute = "speaking", even though I hadn't declared that my character should be speaking in the script? Do I need to add a "$ speaking = False"?
Code: Select all
define config.speaking_attribute = "speaking"
Ah, my bad. I thought it does when I glimpsed the video you linked. Ignore that then.- 3. I thought .gifs didn't work? If they did it would be very convenient for the eyes and mouth.
This is a bit beyond me, but looks like you can do it by creating images that are animated for the eyes, then reference them in the LiveComposite. If I just do the eyes for example:- 4. Concerning the eyes in particular, I have different animations for the eyes with a different amount of frames, so one has 3 images, it goes from 1 to 3 and 3 to 1. And I have one that consists out of 4 images. Not just that, I also have an eyeroll animation of 11 frames. I could cut it out altogether if coding it will be too much of a pain though. Following the tutorial that I watched, I'm not sure how to properly implement that, seeing as it deals with a constant amount of frames for the eyes.
Code: Select all
image iris eyes:
"Iris/Eyes/[iris_bruised]/[iris_mood]/eyes.png"
choice:
4.5
choice:
3.5
choice:
1.5
"Iris/Eyes/[iris_bruised]/[iris_mood]/eyes_closed.png"
.25
repeat
image iris = LiveComposite(
(530, 630), # (width, height)
(0, 0), "Iris/Base/[iris_clothing].png",
(0, 0), "Iris/Eyebrows/[iris_mood]/eyebrows.png",
(0,0), "iris eyes",
(0,0), "Iris/Mouths/[iris_mood]/mouth.png"
)
Easy, you break down the image declaration:-5. Scaling is kind of an issue, my portrait is too big, I made it wanting it to be big and wanting to scale it down how do I do this in livecomposite? Or do I need to do this in a separate line?
Code: Select all
image iris:
LiveComposite(all the code inside)
zoom 0.75
You'd do this with transforms. For when the character is talking, you'd add the transform to the speaking version of the image, which you may need someone to confirm. I think you can do it this way:- 6. have a question about the width/height in this line:Rather than it being width and height it seems to be about the positioning of the image? (xalign 1.0, yalign 1.0) gives a syntax error. I'd like to pin my height at a certain y-position, have it raise slightly when the character is talking, and move it to the side when another character is on screen manually later. How can I do this?Code: Select all
LiveComposite( (530, 630), # (width, height)
Code: Select all
transform talking:
yalign 0.9 # or play with ypos and yanchor
image iris speaking:
At(LiveComposite(livecomposite codes here),talking) # note no quotes around talking
Who is online
Users browsing this forum: Google [Bot]