# 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.