-
Notifications
You must be signed in to change notification settings - Fork 119
Developing Games Using Frogatto's Engine: Part 3
For chapters 3 to 5 of this tutorial, I've decided to do a series of videos demonstrating how to add walking, jumping, and crouching to Elisa. I recommend watching the videos in as high a resolution as you can. While the videos are from 2012, the transcription and code listings have had minor updates to make them compatible with Anura in 2018.
[0:00]
In this video, I'm going to take Elisa from this basic form I've left her with in the tutorial so far and show you how we can make her walk and jump and do some basic actions like that. So, what I've shown so far is we have her idle animation and we have so when you press the S button she swings her sword like that and then I made something where if you press the left arrow she slides along the ground. So, we're going to press ctrl-e and go into the editor and then we're going to press the code button to load up her code. (Note: You may need to click Elisa's icon, below @instance
, to see this.) And so we see here this is the code.
We see that the stand animation repeats. (on_end_stand_anim
and co.)
When we go into an attack animation, we go back into the stand animation. (on_end_attack_anim
)
When you press the tongue button (which is the s button) it starts into her attack animation.
In this on_process
, when we detect a press of the left control (the left arrow) it'll shift her x across by 2.
[1:00]
After, we have the definitions for the animations.
So, the first thing we want to do is we want to add a new animation. We have her stand animation, and we have her attack animation. We can see we have these animation preview widgets that come up when we click on either of the code blocks for the animations.
To make a walk animation, we'll base it off the stand animation. I'm going to select [all of the stand animation] and I'm going to copy it to make a walk animation. I'll paste it [below the stand animation] and change the name to walk
. Then, we want to select the walking [animation frames]. What's really nice about this interface is that I can just click [on the first frame of the walk animation, third from the top] and because it has the red rectangles in the image it automatically recognizes the walking animation.
Now, we can see it's walking here, but it's going in reverse because in our idle animation we wanted it to go forward and backwards. But that's not desirable for a walk animation, you just want it to cycle through. [2:00] I'm going to delete the reverse: true
flag. The speed is perhaps a little fast so let's change the situation here. Clicking on the duration value, we can drag it around a little to change how fast the animation plays. I like it at 6 I think.
[2:23] The walk animation now looks like this:
{
frames_per_row: 8,
id: "walk",
image: "characters/elisa-spritesheet1.png",
rect: [5,121,58,174],
solid_area: [22,10,38,50],
pad: 3,
duration: 6,
frames: 8,
accel_y: 80
},
So then, we want to make it so that she actually starts walking when we press the left control or the right control, the left arrow or the right arrow. What we want to do is, in on_process
, if we detect left or right being pressed then make us start walking.
on_process
is modified to this:
on_process: "if(ctrl_left or ctrl_right, set(x, x-2))",
And to start walking, [Elisa] has to be in her standing animation. There might be some other animations she could be in as well which would qualify her to start walking, which we could add later. [3:00]
on_process
is modified to this:
on_process: "if((ctrl_left or ctrl_right) and animation in ['stand'],
set(x, x-2))",
Later if there is some other animation we could add it to the list here.
And if this happens, we want to start her walking. Replace set(x, x-2)
with set(animation, 'walk')
. What we also want to do is set the facing correctly, so if left is pressed she faces to the left and if right is pressed she faces to the right.
on_process
is now:
on_process: "if((ctrl_left or ctrl_right) and animation in ['stand'],
[set(facing, if(ctrl_left, -1, 1)), set(animation, 'walk')])",
Let's try this out! … So we can see that she gets to the end of her walk animation and freezes. That's because her walk doesn't cycle. Her walk goes to the end of the walk animation and then just freezes there. [4:00] We need to put a handler for on_end_walk_anim
.
on_end_walk_anim: "set(animation, 'walk')",
So we did that, and it instantly takes effect.
Now, we don't have any exit condition for her walking. I just pressed the arrow button, I'm not holding it down, and she's just going to continue walking forever. While she's walking, we want to test if we're no longer holding the arrow button. We could do this in on_process
, but we want to use on_process_walk
which is triggered every cycle she's in her walk animation. Since that's a narrower criteria it'll be better to use.
[5:00]
Above on_end_walk_anim
, we add:
on_process_walk: "if(not (ctrl_left or ctrl_right), set(animation, 'stand'))",
Now, what we want to do—and this is a little bit subtle—if somebody started to press to the left and then they press to the right at the same time and then they let go of the left, Elisa would keep on walking to the left because that's what she started doing. So in on_process_walk
we want to set her facing. What we can do is move the facing code from on_process
and put it in on_process_walk
, like this:
on_process: "if((ctrl_left or ctrl_right) and animation in ['stand'],
[set(animation, 'walk')])",
on_process_walk: "if(not (ctrl_left or ctrl_right), set(animation, 'stand'),
set(facing, if(ctrl_left, -1, 1)))",
[6:00]
If we're not pressing control left or control right, then we go into stand, otherwise we make sure our facing is correct. … So let's try that out! Hold to the right, to the left, both, it works.
Of course, we want Elisa to actually move when she's walking. [7:00] The easiest way to do that is in her walk animation. In the animations, we previously gave a y acceleration (accel_y: 80
) to give her gravity. Let's give her an x acceleration to make her actually move. The x acceleration will have to be much greater actually to overcome friction.
Let's try adding accel_x: 1000,
above accel_y: 80,
in the walk animation.
As you can see, she actually flies very quickly off the screen – that's because she doesn't have a friction setting. But before we add friction let's go ahead and make our map a little bit larger so we can see what's going on.
[8:00]
Now, let's try that again. See how she just flies off the screen like crazy. We want to give Elisa a friction setting, which is a global setting. We'll add friction: 2000,
near the top of the file, below prototype: ["player_controlled"],
and above editor_info
. These are kind of arbitrary numbers you'll have to play with. They do have a meaning, but in the end you just kind of play with them.
You'll see Elisa will continue sliding when she's standing, which I'll explain in a minute. I think this walking speed is reasonable, so let's actually take care of marking her stop. The way that these accel settings work is if accel_x
is set to, say, 1000 that means that when she starts the walking animation she will have her x acceleration set to a thousand. This is the same as if we put an event handler that said on_begin_walk_anim: "set(accel_x, 1000 * facing)"
. This is kind of a convenience for that.
[9:00]
Because stand doesn't have an accel_x
setting, when Elisa enters her stand animation her x acceleration isn't affected at all. It just leaves it wherever it was. What we want to do is put something explicit in stand that says when she goes into standing then cut out her acceleration.
Adding accel_x: 0,
to Elisa's stand animation, we can see that works nicely.
Let's see how this works with her attacking. Right now, if you attack while you're moving, she kind of continues to slide along. We could nerf that if we wanted by doing the same accel_x: 0
trick as we did with stand in attack. However, if we try that out, although it's slightly more realistic I think it's awkward for a game to do that. I think it will make the game feel better if she can just walk and continue slashing away. [10:00] So I'm just going to keep the sliding behaviour.
I think with her walk, we want to take the acceleration up a little more. Let's take it up to, say, 1200. I think I like that.
Next up: Jumping!
[10:50]
Next up: Developing-Games-Using-Frogatto's-Engine:-Part-4
Previously: Developing-Games-Using-Frogatto's-Engine:-Part-2
The complete code listing for Elisa, after this tutorial so far:
{
id: "elisa",
prototype: ["player_controlled"],
friction: 2000,
editor_info: { category: "elisa" },
on_end_stand_anim: "set(animation, 'stand')",
on_end_attack_anim: "set(animation, 'stand')",
on_ctrl_tongue: "[set(animation, 'attack')]",
on_process: "if((ctrl_left or ctrl_right) and animation in ['stand'],
[set(animation, 'walk')])",
on_process_walk: "if(not (ctrl_left or ctrl_right), set(animation, 'stand'),
set(facing, if(ctrl_left, -1, 1)))",
on_end_walk_anim: "set(animation, 'walk')",
animation: [{
id: "stand",
image: "characters/elisa-spritesheet1.png",
rect: [4,4,57,57],
solid_area: [16,10,32,50],
pad: 3,
duration: 5,
frames: 3,
reverse: true,
accel_x: 0,
accel_y: 80,
},{
frames_per_row: 8,
id: "walk",
image: "characters/elisa-spritesheet1.png",
rect: [5,121,58,174],
solid_area: [22,10,38,50],
pad: 3,
duration: 6,
frames: 8,
accel_x: 1200,
accel_y: 80,
},{
id: "attack",
image: "characters/elisa-spritesheet1.png",
rect: [5,180,93,240],
solid_area: [16,10,32,50],
pad: 3,
duration: 5,
frames: 6,
frames_per_row: 3,
accel_y: 80,
}]
}
More help can be found via chat in Frogatto's Discord server, or by posting on the forums. This wiki is not a complete reference. Thank you for reading! You're the best. 🙂