9. Drawing With Functions¶
Here is a set of examples where we take a program that already exists and put everything in 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()
|
9.1. Make The main
Function¶
Next, create a main()
function. Put everything in it, and call the main
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 | 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()
|
When you do this, run your program and make sure it still works before proceeding.
9.2. Make The Drawing Functions¶
Next, pick an item to move to a function. Start with an easy one if you have it. I chose grass because it was only one line of code, and I wasn’t going to ever try to position it with x, 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 | 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()
|
Then, I took a more complex shape 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.