Getting Started With gewel
The best way to get started with gewel is to jump right in.
Installation
The first thing we need to do is install gewel. We are going to make two assumptions here:
You are familiar with Python and installing packages using pip.
You have a virtual environment running Python 3.9 or higher.
If you are not sure about these two things, we recommend you read about pip and virtualenv or a virtual environment management tool like pipenv, which is what we use while developing gewel.
Once you have a virtual environment running Python 3.9, you can install gewel by running
$ pip install gewel
at the command line.
Hello, World
Now that we have gewel installed, we can get started on our first script.
We are going to build our first animation around a character named Bep.
Bep is not very interesting just standing there doing nothing, so we are going to animate them. Our goal is to produce something like the following:
The Scripting Phase
We’ll start out in what is called the scripting phase. In this phase we are essentially writing the script for the animation.
We begin by creating a Drawable
from the image we have of Bep. Anything we can draw or animate
with gewel is based on the Drawable
class. Since we happen to have a PNG file of Bep (the one shown above when
we first introduced them), we’ll use the
PngDrawable
subclass, as follows:
from gewel.draw import PngDrawable
bep = PngDrawable('bep.png', x=32, y=240)
What did we just do? We loaded our PNG file into a
drawable object called bep
and we specified and
initial position for the drawable at x=32
and
y=240
. That’s the location on the screen where Bep
will start out.
If you want to try this yourself, you’ll need the bep.png
file. Click this link to download
bep.png
and
save it in the same directory as the python script where
you saved the code snippet above.
Now let’s move Bep across the screen, like we saw in the animation. We do that with one line of code:
bep.move_to(608, 240, duration=2.0)
This tells Bep to move to a new location on the screen,
576 pixels to the right of where they started. The
duration=2.0
argument specifies that this movement
should take two seconds.
That was easy. Now what about the back flip that Bep does to get back to where they started? This will take two lines of code:
bep.quadratic_move_to(320, 0, 32, 240, duration=2.0, update_time=False)
bep.rotate_to_degrees(360, duration=2.0)
The first line moves Bep from where they are to their
original location at 32, 240
. But what do the arguments
320, 0
that come before the destination mean?
Those are the x and y coordinates of a control
point that controls the path Bep takes along the way.
Notice that the control
point is at the top center of the screen (by convention y
coordinates on the screen increase as they go down). So Bep
will go towards the control point, but then curve away towards
their final destination.
The duration=2.0
argument is like the one we used before.
It says the motion will take two seconds.
So now we just have the update_time=False
argument left to
deal with. We did not provide that argument when we did our
original move_to
, so it used the default value of
update_time=True
. True
means that Bep should update
their internal clock to the point at which the move was complete,
so that whatever move comes next will be done after that. But
this time, we don’t want to wait until Bep arrives before we
do the back flip. We want them to do it while moving. That’s
why we used update_time=False
on the move. Now we can
take another action, and it will begin at the same time as the
quadratic_move_to
started. For more on the use of update_time
see Next-Action Time During Scripting.
The next move is the
rotate_to_degrees
line above.
This is the back flip! We told Bep to rotate 360 degrees
over a duration of two seconds. These two seconds start
at the same time the quadratic move started. That move
also took two seconds, so the move and the rotation end
at the exact same time and Bep sticks the landing!
So that’s it. We’ve written all the code needed to tell Bep where to start and how to move to create the animation we want. That brings us to the end of the scripting phase.
Next, we just need to add a few more lines of code so we can actually play the animation we just created. This is called the rendering phase.
We are going to construct a scene, which is just another kind of drawable that contains other drawables, and put Bep in it along with a background.
from gewel.draw import Background
background = Background()
scene = Scene([background, bep])
The Rendering Phase
Finally, we construct a player to play the scene in a pop-up window so we can view it. We have completed the script for the scene, and have entered the rendering phase.
from gewel.player import Player
player = Player(scene)
player.mainloop()
When the window pops up you will see Bep on the left side of the window, just where we placed them. By default the player starts in autoplay mode and is set to loop, so you should see Bep start doing their thing.
The final script that does all of this, which you should be able to copy, paste, and run in your virtual environment, is
from gewel.draw import PngDrawable, Background, Scene
from gewel.player import Player
# Scripting phase...
bep = PngDrawable('bep.png', x=32, y=240)
bep.move_to(608, 240, duration=2.0)
bep.quadratic_move_to(320, 0, 32, 240, duration=2.0, update_time=False)
bep.rotate_to_degrees(360, duration=2.0)
background = Background()
scene = Scene([background, bep])
# Rendering phase...
player = Player(scene)
player.mainloop()
One final step you might want to try, in case you want to preserve
your first animation for posterity, is to write it out to an mp4
file. All you have to do is replace the last two lines of the script
above (the ones that instantiate player
and start it up) with
from gewel.record import Mp4Recorder
recorder = Mp4Recorder('helloworld.mp4')
recorder.record(scene)
Now when you run the script, instead of popping up a window with the animation, it will write it to a file that you can share with your friends.
Scaffolding
If you took the opportunity to play around with this first animation as the sidebar suggested, it’s possible you didn’t always get the effect you wanted. And even if you did, when things get more complicated and there are multiple objects moving around it isn’t always easy to debug what went wrong. Luckily, gewel has some tools to help.
Since animation is a visual medium, it helps to have visual tools for debugging. These can be much more effective than digging through log files. The most important visual debugging tool gewel offers is called scaffolding. Scaffolding shows you the control points and paths that are controlling an object’s movement as it moves. Like the motion itself, it is set up during the scripting phase.
Let’s turn it on and see how it works. An animation will be worth a thousand words.
To turn on scaffolding, we’ll modify our code so it looks as follows:
from gewel.draw import PngDrawable, Background, Scene
from gewel.player import Player
# Scripting phase...
bep = PngDrawable('bep.png', x=32, y=240)
scaffold_1 = bep.move_to(608, 240, duration=2.0, scaffold=True)
scaffold_2 = bep.quadratic_move_to(320, 0, 32, 240, duration=2.0,
update_time=False, scaffold=True)
bep.rotate_to_degrees(360, duration=2.0)
background = Background()
scene = Scene([background, bep, scaffold_1, scaffold_2])
# Rendering phase...
player = Player(scene)
player.mainloop()
The major change is that we made are that we added the scaffold=True
argument to our calls to move_to
and quadratic_move_to
on lines
in the scripting phase of the listing above. When
we add this argument, those functions return scaffolding objects to us.
We assigned
those objects to variables name scaffold_1
and scaffold_2
.
Scaffolding objects, it turns out, are also Drawable
objects,
so we add them to our scene right before we enter the rendering
phase.
Now when we run again, the result looks like this:
Notice that while Bep is moving across the screen there are othe markers and lines on the screen. There is a pale blue x at the start an end of each move, and another one at the control point of the quadratic move. The path of each move is shown with a pale gray line, and for the quadrative move there are lines from the start point to the control point and from the control point to the end point. All of this lets us quickly and visually diagnose if something is wrong. For example, if we a control point is in the wrong place and that is the reason we’re seeing some movement we don’t expect, then we will be able to see that immediately.
So that about wraps things up for this guide to getting started with gewel. There is, of course, a lot more still to learn on a variety of topics.
For additional code samples illustrating many of the fundamental concepts of gewel, see Sample Code.
If you want to learn about all the other sub-packages of the gewel package, the Gewel page has links to all of them.