9. Drawing With Functions¶
We learned how to draw in How to Draw with Your Computer. In Lab 2: Draw a Picture we applied that to create our own drawing. We learned how to create functions in Creating Functions. In this chapter, we’ll combine all that knowledge to create our own drawing functions.
We’ll do that by expanding on the code you wrote for Lab 2: Draw a Picture.
To show you how, I’m going to start with a similar program and convert it to using functions.
First the original program:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import arcade
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing with Functions")
arcade.set_background_color(arcade.color.DARK_BLUE)
arcade.start_render()
# Draw the ground
arcade.draw_lrtb_rectangle_filled(0, SCREEN_WIDTH, SCREEN_HEIGHT / 3, 0, arcade.color.AIR_SUPERIORITY_BLUE)
# Draw a snow person
# Snow
arcade.draw_circle_filled(300, 200, 60, arcade.color.WHITE)
arcade.draw_circle_filled(300, 280, 50, arcade.color.WHITE)
arcade.draw_circle_filled(300, 340, 40, arcade.color.WHITE)
# Eyes
arcade.draw_circle_filled(285, 350, 5, arcade.color.BLACK)
arcade.draw_circle_filled(315, 350, 5, arcade.color.BLACK)
# Finish and run
arcade.finish_render()
arcade.run()
|
Ok, it isn’t very fancy, but that will make this process easier to follow.
9.1. Make The main
Function¶
After copying the code into Lab 3, we’ll create a main()
function.
Put everything in it, and call the main
function.
Are those too many lines to indent? You can indent groups of lines by selecting them, and then hitting “tab”. If you want to un-indent a group of lines, hit shift-tab.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import arcade
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
def main():
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing with Functions")
arcade.set_background_color(arcade.color.DARK_BLUE)
arcade.start_render()
# Draw the ground
arcade.draw_lrtb_rectangle_filled(0, SCREEN_WIDTH, SCREEN_HEIGHT / 3, 0, arcade.color.AIR_SUPERIORITY_BLUE)
# Draw a snow person
# Snow
arcade.draw_circle_filled(300, 200, 60, arcade.color.WHITE)
arcade.draw_circle_filled(300, 280, 50, arcade.color.WHITE)
arcade.draw_circle_filled(300, 340, 40, arcade.color.WHITE)
# Eyes
arcade.draw_circle_filled(285, 350, 5, arcade.color.BLACK)
arcade.draw_circle_filled(315, 350, 5, arcade.color.BLACK)
# Finish and run
arcade.finish_render()
arcade.run()
# Call the main function to get the program started.
main()
|
After this, run your program and make sure it still works before proceeding. If it doesn’t work, stop and get help. Continuing will only make the problem harder.
9.2. Make The Drawing Functions¶
Next, pick an item to move to a function. Start with an easy one if you have it.
9.2.1. Grass Function¶
I chose grass to start withbecause it was only one line of code, and I wasn’t going to ever try to position it with an x, y coordinate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | import arcade
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
def draw_grass():
""" Draw the ground """
arcade.draw_lrtb_rectangle_filled(0, SCREEN_WIDTH, SCREEN_HEIGHT / 3, 0, arcade.color.AIR_SUPERIORITY_BLUE)
def main():
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing with Functions")
arcade.set_background_color(arcade.color.DARK_BLUE)
arcade.start_render()
draw_grass()
# Draw a snow person
# Snow
arcade.draw_circle_filled(300, 200, 60, arcade.color.WHITE)
arcade.draw_circle_filled(300, 280, 50, arcade.color.WHITE)
arcade.draw_circle_filled(300, 340, 40, arcade.color.WHITE)
# Eyes
arcade.draw_circle_filled(285, 350, 5, arcade.color.BLACK)
arcade.draw_circle_filled(315, 350, 5, arcade.color.BLACK)
# Finish and run
arcade.finish_render()
arcade.run()
# Call the main function to get the program started.
main()
|
Test, and make sure it is working.
9.2.2. Snow Person Function¶
Now let’s take the more complex snow person and put it in a function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import arcade
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
def draw_grass():
""" Draw the ground """
arcade.draw_lrtb_rectangle_filled(0, SCREEN_WIDTH, SCREEN_HEIGHT / 3, 0, arcade.color.AIR_SUPERIORITY_BLUE)
def draw_snow_person():
""" Draw a snow person """
# Snow
arcade.draw_circle_filled(300, 200, 60, arcade.color.WHITE)
arcade.draw_circle_filled(300, 280, 50, arcade.color.WHITE)
arcade.draw_circle_filled(300, 340, 40, arcade.color.WHITE)
# Eyes
arcade.draw_circle_filled(285, 350, 5, arcade.color.BLACK)
arcade.draw_circle_filled(315, 350, 5, arcade.color.BLACK)
def main():
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing with Functions")
arcade.set_background_color(arcade.color.DARK_BLUE)
arcade.start_render()
draw_grass()
draw_snow_person()
# Finish and run
arcade.finish_render()
arcade.run()
# Call the main function to get the program started.
main()
|
But this draws the snowman only at one spot. I want to draw lots of snowmen, anywhere I put them!
To do this, let’s add an x and y:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import arcade
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
def draw_grass():
""" Draw the ground """
arcade.draw_lrtb_rectangle_filled(0, SCREEN_WIDTH, SCREEN_HEIGHT / 3, 0, arcade.color.AIR_SUPERIORITY_BLUE)
def draw_snow_person(x, y):
""" Draw a snow person """
# Draw a point at x, y for reference
arcade.draw_point(x, y, arcade.color.RED, 5)
# Snow
arcade.draw_circle_filled(300 + x, 200 + y, 60, arcade.color.WHITE)
arcade.draw_circle_filled(300 + x, 280 + y, 50, arcade.color.WHITE)
arcade.draw_circle_filled(300 + x, 340 + y, 40, arcade.color.WHITE)
# Eyes
arcade.draw_circle_filled(285 + x, 350 + y, 5, arcade.color.BLACK)
arcade.draw_circle_filled(315 + x, 350 + y, 5, arcade.color.BLACK)
def main():
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing with Functions")
arcade.set_background_color(arcade.color.DARK_BLUE)
arcade.start_render()
draw_grass()
draw_snow_person(50, 50)
# Finish and run
arcade.finish_render()
arcade.run()
# Call the main function to get the program started.
main()
|
But that’s not perfect. If you’ll note, I added a dot at the x and y. The snowman draws way off from the dot, because originally I didn’t try to draw it at 0, 0. I need to recenter the snowman on the dot.
We need to re-center the shape onto the spot we are drawing. Typically you’ll need to subtract from all the x and y values the same amount.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import arcade
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
def draw_grass():
""" Draw the ground """
arcade.draw_lrtb_rectangle_filled(0, SCREEN_WIDTH, SCREEN_HEIGHT / 3, 0, arcade.color.AIR_SUPERIORITY_BLUE)
def draw_snow_person(x, y):
""" Draw a snow person """
# Draw a point at x, y for reference
arcade.draw_point(x, y, arcade.color.RED, 5)
# Snow
arcade.draw_circle_filled(x, 60 + y, 60, arcade.color.WHITE)
arcade.draw_circle_filled(x, 140 + y, 50, arcade.color.WHITE)
arcade.draw_circle_filled(x, 200 + y, 40, arcade.color.WHITE)
# Eyes
arcade.draw_circle_filled(x - 15, 210 + y, 5, arcade.color.BLACK)
arcade.draw_circle_filled(x + 15, 210 + y, 5, arcade.color.BLACK)
def main():
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing with Functions")
arcade.set_background_color(arcade.color.DARK_BLUE)
arcade.start_render()
draw_grass()
draw_snow_person(150, 140)
draw_snow_person(450, 180)
# Finish and run
arcade.finish_render()
arcade.run()
# Call the main function to get the program started.
main()
|
9.3. How To Animate A Drawing Function¶
We can animate our drawing if we want. Here are the steps.
9.3.1. Create An on_draw
Method¶
Right now our program only draws our image once. We need to move all the drawing code
in our main
to an on_draw
function. Then we’ll tell the computer to draw
that over and over.
Continuing from our last example, our program will look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import arcade
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
def draw_grass():
""" Draw the ground """
arcade.draw_lrtb_rectangle_filled(0, SCREEN_WIDTH, SCREEN_HEIGHT / 3, 0, arcade.color.AIR_SUPERIORITY_BLUE)
def draw_snow_person(x, y):
""" Draw a snow person """
# Draw a point at x, y for reference
arcade.draw_point(x, y, arcade.color.RED, 5)
# Snow
arcade.draw_circle_filled(x, 60 + y, 60, arcade.color.WHITE)
arcade.draw_circle_filled(x, 140 + y, 50, arcade.color.WHITE)
arcade.draw_circle_filled(x, 200 + y, 40, arcade.color.WHITE)
# Eyes
arcade.draw_circle_filled(x - 15, 210 + y, 5, arcade.color.BLACK)
arcade.draw_circle_filled(x + 15, 210 + y, 5, arcade.color.BLACK)
def on_draw(delta_time):
""" Draw everything """
arcade.start_render()
draw_grass()
draw_snow_person(150, 140)
draw_snow_person(450, 180)
def main():
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing with Functions")
arcade.set_background_color(arcade.color.DARK_BLUE)
# Call on_draw every 60th of a second.
arcade.schedule(on_draw, 1/60)
arcade.run()
# Call the main function to get the program started.
main()
|
Do this with your own program. Nothing will move, but it should still run.
9.3.2. Add Variable To Control Where We Draw Our Item¶
Next, we are going to create a variable inside of the on_draw
function.
This variable will hold our x value.
Each time we call on_draw
, we’ll change x so that it moves to the right.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | import arcade
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
def draw_grass():
""" Draw the ground """
arcade.draw_lrtb_rectangle_filled(0, SCREEN_WIDTH, SCREEN_HEIGHT / 3, 0, arcade.color.AIR_SUPERIORITY_BLUE)
def draw_snow_person(x, y):
""" Draw a snow person """
# Draw a point at x, y for reference
arcade.draw_point(x, y, arcade.color.RED, 5)
# Snow
arcade.draw_circle_filled(x, 60 + y, 60, arcade.color.WHITE)
arcade.draw_circle_filled(x, 140 + y, 50, arcade.color.WHITE)
arcade.draw_circle_filled(x, 200 + y, 40, arcade.color.WHITE)
# Eyes
arcade.draw_circle_filled(x - 15, 210 + y, 5, arcade.color.BLACK)
arcade.draw_circle_filled(x + 15, 210 + y, 5, arcade.color.BLACK)
def on_draw(delta_time):
""" Draw everything """
arcade.start_render()
draw_grass()
draw_snow_person(on_draw.snow_person1_x, 140)
draw_snow_person(450, 180)
# Add one to the x value, making the snow person move right
# Negative numbers move left. Larger numbers move faster.
on_draw.snow_person1_x += 1
# Create a value that our on_draw.snow_person1_x will start at.
on_draw.snow_person1_x = 150
def main():
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing with Functions")
arcade.set_background_color(arcade.color.DARK_BLUE)
# Call on_draw every 60th of a second.
arcade.schedule(on_draw, 1/60)
arcade.run()
# Call the main function to get the program started.
main()
|
For more information, see the Bouncing Rectangle Example.