Lab 3: Drawing with Functions

Requirements

Your goal: Draw and animate an image.

../../_images/lab_03_example_01.gif

Requirements for Drawing

You can update your program from Lab 2, or create a new program. This lab is worth 20 points. See the point breakdown below.

Incorporate the following items:

  • Find the folder for Lab 03 in PyCharm. Feel free to use any code from Lab 02 you want, just copy it across.
  • Create three functions that draw something. (15 pts total, up to 5 pts per function)
    • Define the function and successfully call it. (1 pt)
    • Make your drawing function complex. 0 points for a one-line function that just draws a rectangle, 0 points for copying the example from the book, 2 points for a cohesive multi-line function. (2 pts)
    • Pass in x and y parameters and successfully position the object as shown in How to Create a Custom Drawing Function. (2 pts)
  • Properly use the main function for your main program as shown in Make Everything a Function. (1 pt)

Drawing with functions is worth 16 points. You can get the final 4 points by animating your image.

Requirements for Animation

Animate an object. The movement does not need to be complex.

Tips to Make Things Easier

Putting Code In a Function

Say I have a drawing with a tractor. See highlighted lines below:

make_function_1.py
 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
"""
This is a sample program to show how to draw using the Python programming
language and the Arcade library.
"""

# Import the "arcade" library
import arcade

# Open up a window.
# From the "arcade" library, use a function called "open_window"
# Set the window title to "Drawing Example"
# Set the and dimensions (width and height)
arcade.open_window(800, 600, "Drawing Example")

# Set the background color
arcade.set_background_color(arcade.color.AIR_SUPERIORITY_BLUE)

# Get ready to draw
arcade.start_render()

# Draw the grass
arcade.draw_lrtb_rectangle_filled(0, 800, 200, 0, arcade.color.BITTER_LIME)

# --- Draw the barn ---

# Barn cement base
arcade.draw_lrtb_rectangle_filled(30, 350, 210, 170, arcade.color.BISQUE)

# Bottom half
arcade.draw_lrtb_rectangle_filled(30, 350, 350, 210, arcade.color.BROWN)

# Left-bottom window
arcade.draw_rectangle_filled(70, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(70, 260, 20, 30, arcade.color.BLACK)

# Right-bottom window
arcade.draw_rectangle_filled(310, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(310, 260, 20, 30, arcade.color.BLACK)

# Barn door
arcade.draw_rectangle_filled(190, 230, 100, 100, arcade.color.BLACK_BEAN)

# Rail above the door
arcade.draw_rectangle_filled(190, 280, 180, 5, arcade.color.BONE)

# Draw second level of barn
arcade.draw_polygon_filled([[20, 350],
                            [100, 470],
                            [280, 470],
                            [360, 340]],
                            arcade.color.BROWN)

# Draw loft of barn
arcade.draw_triangle_filled(100, 470, 280, 470, 190, 500, arcade.color.BROWN)

# Left-top window
arcade.draw_rectangle_filled(130, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(130, 440, 20, 30, arcade.color.BLACK)

# Right-top window
arcade.draw_rectangle_filled(250, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(250, 440, 20, 30, arcade.color.BLACK)

# Draw 2nd level door
arcade.draw_rectangle_outline(190, 310, 30, 60, arcade.color.BONE, 5)

# --- Draw the tractor ---

# Draw the engine
arcade.draw_rectangle_filled(600, 120, 140, 70, arcade.color.GRAY)
arcade.draw_rectangle_filled(590, 105, 90, 40, arcade.color.BLACK)

# Draw the smoke stack
arcade.draw_rectangle_filled(580, 175, 10, 40, arcade.color.BLACK)

# Back wheel
arcade.draw_circle_filled(490, 110, 50, arcade.color.BLACK)
arcade.draw_circle_filled(490, 110, 45, arcade.color.BLACK_OLIVE)
arcade.draw_circle_filled(490, 110, 35, arcade.color.OLD_LACE)
arcade.draw_circle_filled(490, 110, 10, arcade.color.RED)

# Front wheel
arcade.draw_circle_filled(650, 90, 30, arcade.color.BLACK)
arcade.draw_circle_filled(650, 90, 25, arcade.color.BLACK_OLIVE)
arcade.draw_circle_filled(650, 90, 18, arcade.color.OLD_LACE)
arcade.draw_circle_filled(650, 90, 5, arcade.color.RED)

# --- Finish drawing ---
arcade.finish_render()

# Keep the window up until someone closes it.
arcade.run()

I can easily move it to a function and call the function. See the highlighted lines below:

make_function_2.py
 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""
This is a sample program to show how to draw using the Python programming
language and the Arcade library.
"""

# Import the "arcade" library
import arcade

def draw_tractor():
    """ Draw the tractor """

    # Draw the engine
    arcade.draw_rectangle_filled(600, 120, 140, 70, arcade.color.GRAY)
    arcade.draw_rectangle_filled(590, 105, 90, 40, arcade.color.BLACK)

    # Draw the smoke stack
    arcade.draw_rectangle_filled(580, 175, 10, 40, arcade.color.BLACK)

    # Back wheel
    arcade.draw_circle_filled(490, 110, 50, arcade.color.BLACK)
    arcade.draw_circle_filled(490, 110, 45, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(490, 110, 35, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(490, 110, 10, arcade.color.RED)

    # Front wheel
    arcade.draw_circle_filled(650, 90, 30, arcade.color.BLACK)
    arcade.draw_circle_filled(650, 90, 25, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(650, 90, 18, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(650, 90, 5, arcade.color.RED)


# Open up a window.
# From the "arcade" library, use a function called "open_window"
# Set the window title to "Drawing Example"
# Set the and dimensions (width and height)
arcade.open_window(800, 600, "Drawing Example")

# Set the background color
arcade.set_background_color(arcade.color.AIR_SUPERIORITY_BLUE)

# Get ready to draw
arcade.start_render()

# Draw the grass
arcade.draw_lrtb_rectangle_filled(0, 800, 200, 0, arcade.color.BITTER_LIME)

# --- Draw the barn ---

# Barn cement base
arcade.draw_lrtb_rectangle_filled(30, 350, 210, 170, arcade.color.BISQUE)

# Bottom half
arcade.draw_lrtb_rectangle_filled(30, 350, 350, 210, arcade.color.BROWN)

# Left-bottom window
arcade.draw_rectangle_filled(70, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(70, 260, 20, 30, arcade.color.BLACK)

# Right-bottom window
arcade.draw_rectangle_filled(310, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(310, 260, 20, 30, arcade.color.BLACK)

# Barn door
arcade.draw_rectangle_filled(190, 230, 100, 100, arcade.color.BLACK_BEAN)

# Rail above the door
arcade.draw_rectangle_filled(190, 280, 180, 5, arcade.color.BONE)

# Draw second level of barn
arcade.draw_polygon_filled([[20, 350],
                            [100, 470],
                            [280, 470],
                            [360, 340]],
                            arcade.color.BROWN)

# Draw loft of barn
arcade.draw_triangle_filled(100, 470, 280, 470, 190, 500, arcade.color.BROWN)

# Left-top window
arcade.draw_rectangle_filled(130, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(130, 440, 20, 30, arcade.color.BLACK)

# Right-top window
arcade.draw_rectangle_filled(250, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(250, 440, 20, 30, arcade.color.BLACK)

# Draw 2nd level door
arcade.draw_rectangle_outline(190, 310, 30, 60, arcade.color.BONE, 5)

draw_tractor()

# --- Finish drawing ---
arcade.finish_render()

# Keep the window up until someone closes it.
arcade.run()

But my function isn’t very useful, because it always draws the tractor in the same spot. I can pass in parameters like:

make_function_3.py
 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""
This is a sample program to show how to draw using the Python programming
language and the Arcade library.
"""

# Import the "arcade" library
import arcade

def draw_tractor(x, y):
    """ Draw the tractor """

    # Draw the engine
    arcade.draw_rectangle_filled(600, 120, 140, 70, arcade.color.GRAY)
    arcade.draw_rectangle_filled(590, 105, 90, 40, arcade.color.BLACK)

    # Draw the smoke stack
    arcade.draw_rectangle_filled(580, 175, 10, 40, arcade.color.BLACK)

    # Back wheel
    arcade.draw_circle_filled(490, 110, 50, arcade.color.BLACK)
    arcade.draw_circle_filled(490, 110, 45, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(490, 110, 35, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(490, 110, 10, arcade.color.RED)

    # Front wheel
    arcade.draw_circle_filled(650, 90, 30, arcade.color.BLACK)
    arcade.draw_circle_filled(650, 90, 25, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(650, 90, 18, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(650, 90, 5, arcade.color.RED)


# Open up a window.
# From the "arcade" library, use a function called "open_window"
# Set the window title to "Drawing Example"
# Set the and dimensions (width and height)
arcade.open_window(800, 600, "Drawing Example")

# Set the background color
arcade.set_background_color(arcade.color.AIR_SUPERIORITY_BLUE)

# Get ready to draw
arcade.start_render()

# Draw the grass
arcade.draw_lrtb_rectangle_filled(0, 800, 200, 0, arcade.color.BITTER_LIME)

# --- Draw the barn ---

# Barn cement base
arcade.draw_lrtb_rectangle_filled(30, 350, 210, 170, arcade.color.BISQUE)

# Bottom half
arcade.draw_lrtb_rectangle_filled(30, 350, 350, 210, arcade.color.BROWN)

# Left-bottom window
arcade.draw_rectangle_filled(70, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(70, 260, 20, 30, arcade.color.BLACK)

# Right-bottom window
arcade.draw_rectangle_filled(310, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(310, 260, 20, 30, arcade.color.BLACK)

# Barn door
arcade.draw_rectangle_filled(190, 230, 100, 100, arcade.color.BLACK_BEAN)

# Rail above the door
arcade.draw_rectangle_filled(190, 280, 180, 5, arcade.color.BONE)

# Draw second level of barn
arcade.draw_polygon_filled([[20, 350],
                            [100, 470],
                            [280, 470],
                            [360, 340]],
                            arcade.color.BROWN)

# Draw loft of barn
arcade.draw_triangle_filled(100, 470, 280, 470, 190, 500, arcade.color.BROWN)

# Left-top window
arcade.draw_rectangle_filled(130, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(130, 440, 20, 30, arcade.color.BLACK)

# Right-top window
arcade.draw_rectangle_filled(250, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(250, 440, 20, 30, arcade.color.BLACK)

# Draw 2nd level door
arcade.draw_rectangle_outline(190, 310, 30, 60, arcade.color.BONE, 5)

draw_tractor(0, 0)

# --- Finish drawing ---
arcade.finish_render()

# Keep the window up until someone closes it.
arcade.run()

This is close, but not great. My function ignores the x and y that are passed in. So I need to use that x and y.

See below. I use x and y, and draw two tractors.

make_function_4.py
 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""
This is a sample program to show how to draw using the Python programming
language and the Arcade library.
"""

# Import the "arcade" library
import arcade

def draw_tractor(x, y):
    """ Draw the tractor """

    # Draw the engine
    arcade.draw_rectangle_filled(600 + x, 120 + y, 140, 70, arcade.color.GRAY)
    arcade.draw_rectangle_filled(590 + x, 105 + y, 90, 40, arcade.color.BLACK)

    # Draw the smoke stack
    arcade.draw_rectangle_filled(580 + x, 175 + y, 10, 40, arcade.color.BLACK)

    # Back wheel
    arcade.draw_circle_filled(490 + x, 110 + y, 50, arcade.color.BLACK)
    arcade.draw_circle_filled(490 + x, 110 + y, 45, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(490 + x, 110 + y, 35, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(490 + x, 110 + y, 10, arcade.color.RED)

    # Front wheel
    arcade.draw_circle_filled(650 + x, 90 + y, 30, arcade.color.BLACK)
    arcade.draw_circle_filled(650 + x, 90 + y, 25, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(650 + x, 90 + y, 18, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(650 + x, 90 + y, 5, arcade.color.RED)


# Open up a window.
# From the "arcade" library, use a function called "open_window"
# Set the window title to "Drawing Example"
# Set the and dimensions (width and height)
arcade.open_window(800, 600, "Drawing Example")

# Set the background color
arcade.set_background_color(arcade.color.AIR_SUPERIORITY_BLUE)

# Get ready to draw
arcade.start_render()

# Draw the grass
arcade.draw_lrtb_rectangle_filled(0, 800, 200, 0, arcade.color.BITTER_LIME)

# --- Draw the barn ---

# Barn cement base
arcade.draw_lrtb_rectangle_filled(30, 350, 210, 170, arcade.color.BISQUE)

# Bottom half
arcade.draw_lrtb_rectangle_filled(30, 350, 350, 210, arcade.color.BROWN)

# Left-bottom window
arcade.draw_rectangle_filled(70, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(70, 260, 20, 30, arcade.color.BLACK)

# Right-bottom window
arcade.draw_rectangle_filled(310, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(310, 260, 20, 30, arcade.color.BLACK)

# Barn door
arcade.draw_rectangle_filled(190, 230, 100, 100, arcade.color.BLACK_BEAN)

# Rail above the door
arcade.draw_rectangle_filled(190, 280, 180, 5, arcade.color.BONE)

# Draw second level of barn
arcade.draw_polygon_filled([[20, 350],
                            [100, 470],
                            [280, 470],
                            [360, 340]],
                            arcade.color.BROWN)

# Draw loft of barn
arcade.draw_triangle_filled(100, 470, 280, 470, 190, 500, arcade.color.BROWN)

# Left-top window
arcade.draw_rectangle_filled(130, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(130, 440, 20, 30, arcade.color.BLACK)

# Right-top window
arcade.draw_rectangle_filled(250, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(250, 440, 20, 30, arcade.color.BLACK)

# Draw 2nd level door
arcade.draw_rectangle_outline(190, 310, 30, 60, arcade.color.BONE, 5)

draw_tractor(0, 0)
draw_tractor(300, 0)

# --- Finish drawing ---
arcade.finish_render()

# Keep the window up until someone closes it.
arcade.run()

Better. But when I tell the computer to draw the tractor at (0, 0), it doesn’t draw it there. It draws it at the original spot. Which makes sense when you look at the coordinates. Our original code does not center the tractor at (0, 0).

We can fix this by looking at the smallest x and smallest y of the drawing and subtract them out:

make_function_5.py
 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""
This is a sample program to show how to draw using the Python programming
language and the Arcade library.
"""

# Import the "arcade" library
import arcade

def draw_tractor(x, y):
    """ Draw the tractor """

    # Draw the engine
    arcade.draw_rectangle_filled(600 - 490 + x, 120 - 90 + y, 140, 70, arcade.color.GRAY)
    arcade.draw_rectangle_filled(590 - 490 + x, 105 - 90 + y, 90, 40, arcade.color.BLACK)

    # Draw the smoke stack
    arcade.draw_rectangle_filled(580 - 490 + x, 175 - 90 + y, 10, 40, arcade.color.BLACK)

    # Back wheel
    arcade.draw_circle_filled(490 - 490 + x, 110 - 90 + y, 50, arcade.color.BLACK)
    arcade.draw_circle_filled(490 - 490 + x, 110 - 90 + y, 45, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(490 - 490 + x, 110 - 90 + y, 35, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(490 - 490 + x, 110 - 90 + y, 10, arcade.color.RED)

    # Front wheel
    arcade.draw_circle_filled(650 - 490 + x, 90 - 90 + y, 30, arcade.color.BLACK)
    arcade.draw_circle_filled(650 - 490 + x, 90 - 90 + y, 25, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(650 - 490 + x, 90 - 90 + y, 18, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(650 - 490 + x, 90 - 90 + y, 5, arcade.color.RED)


# Open up a window.
# From the "arcade" library, use a function called "open_window"
# Set the window title to "Drawing Example"
# Set the and dimensions (width and height)
arcade.open_window(800, 600, "Drawing Example")

# Set the background color
arcade.set_background_color(arcade.color.AIR_SUPERIORITY_BLUE)

# Get ready to draw
arcade.start_render()

# Draw the grass
arcade.draw_lrtb_rectangle_filled(0, 800, 200, 0, arcade.color.BITTER_LIME)

# --- Draw the barn ---

# Barn cement base
arcade.draw_lrtb_rectangle_filled(30, 350, 210, 170, arcade.color.BISQUE)

# Bottom half
arcade.draw_lrtb_rectangle_filled(30, 350, 350, 210, arcade.color.BROWN)

# Left-bottom window
arcade.draw_rectangle_filled(70, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(70, 260, 20, 30, arcade.color.BLACK)

# Right-bottom window
arcade.draw_rectangle_filled(310, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(310, 260, 20, 30, arcade.color.BLACK)

# Barn door
arcade.draw_rectangle_filled(190, 230, 100, 100, arcade.color.BLACK_BEAN)

# Rail above the door
arcade.draw_rectangle_filled(190, 280, 180, 5, arcade.color.BONE)

# Draw second level of barn
arcade.draw_polygon_filled([[20, 350],
                            [100, 470],
                            [280, 470],
                            [360, 340]],
                            arcade.color.BROWN)

# Draw loft of barn
arcade.draw_triangle_filled(100, 470, 280, 470, 190, 500, arcade.color.BROWN)

# Left-top window
arcade.draw_rectangle_filled(130, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(130, 440, 20, 30, arcade.color.BLACK)

# Right-top window
arcade.draw_rectangle_filled(250, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(250, 440, 20, 30, arcade.color.BLACK)

# Draw 2nd level door
arcade.draw_rectangle_outline(190, 310, 30, 60, arcade.color.BONE, 5)

draw_tractor(0, 0)
draw_tractor(300, 0)

# --- Finish drawing ---
arcade.finish_render()

# Keep the window up until someone closes it.
arcade.run()

Or more simply:

make_function_6.py
 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""
This is a sample program to show how to draw using the Python programming
language and the Arcade library.
"""

# Import the "arcade" library
import arcade

def draw_tractor(x, y):
    """ Draw the tractor """

    # Draw the engine
    arcade.draw_rectangle_filled(110 + x, 30 + y, 140, 70, arcade.color.GRAY)
    arcade.draw_rectangle_filled(100 + x, 15 + y, 90, 40, arcade.color.BLACK)

    # Draw the smoke stack
    arcade.draw_rectangle_filled(90 + x, 85 + y, 10, 40, arcade.color.BLACK)

    # Back wheel
    arcade.draw_circle_filled(x, 20 + y, 50, arcade.color.BLACK)
    arcade.draw_circle_filled(x, 20 + y, 45, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(x, 20 + y, 35, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(x, 20 + y, 10, arcade.color.RED)

    # Front wheel
    arcade.draw_circle_filled(160 + x, y, 30, arcade.color.BLACK)
    arcade.draw_circle_filled(160 + x, y, 25, arcade.color.BLACK_OLIVE)
    arcade.draw_circle_filled(160 + x, y, 18, arcade.color.OLD_LACE)
    arcade.draw_circle_filled(160 + x, y, 5, arcade.color.RED)


# Open up a window.
# From the "arcade" library, use a function called "open_window"
# Set the window title to "Drawing Example"
# Set the and dimensions (width and height)
arcade.open_window(800, 600, "Drawing Example")

# Set the background color
arcade.set_background_color(arcade.color.AIR_SUPERIORITY_BLUE)

# Get ready to draw
arcade.start_render()

# Draw the grass
arcade.draw_lrtb_rectangle_filled(0, 800, 200, 0, arcade.color.BITTER_LIME)

# --- Draw the barn ---

# Barn cement base
arcade.draw_lrtb_rectangle_filled(30, 350, 210, 170, arcade.color.BISQUE)

# Bottom half
arcade.draw_lrtb_rectangle_filled(30, 350, 350, 210, arcade.color.BROWN)

# Left-bottom window
arcade.draw_rectangle_filled(70, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(70, 260, 20, 30, arcade.color.BLACK)

# Right-bottom window
arcade.draw_rectangle_filled(310, 260, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(310, 260, 20, 30, arcade.color.BLACK)

# Barn door
arcade.draw_rectangle_filled(190, 230, 100, 100, arcade.color.BLACK_BEAN)

# Rail above the door
arcade.draw_rectangle_filled(190, 280, 180, 5, arcade.color.BONE)

# Draw second level of barn
arcade.draw_polygon_filled([[20, 350],
                            [100, 470],
                            [280, 470],
                            [360, 340]],
                            arcade.color.BROWN)

# Draw loft of barn
arcade.draw_triangle_filled(100, 470, 280, 470, 190, 500, arcade.color.BROWN)

# Left-top window
arcade.draw_rectangle_filled(130, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(130, 440, 20, 30, arcade.color.BLACK)

# Right-top window
arcade.draw_rectangle_filled(250, 440, 30, 40, arcade.color.BONE)
arcade.draw_rectangle_filled(250, 440, 20, 30, arcade.color.BLACK)

# Draw 2nd level door
arcade.draw_rectangle_outline(190, 310, 30, 60, arcade.color.BONE, 5)

draw_tractor(0, 0)
draw_tractor(300, 0)

# --- Finish drawing ---
arcade.finish_render()

# Keep the window up until someone closes it.
arcade.run()

Animation Tips

Below are progressively more complex examples on how to do this.

Setup

First, make sure you’ve completed the steps above. Move your drawing items into functions. This next part will be much easier if you’ve already done that.

Our next step to do animation is to move all the drawing commands out of main and into a new function called on_draw. Don’t just move the item you’ll be animating here, move everything.

See the code example below. Note what the main function looks like. Note how the drawing is now in on_draw.

animate_example_01.py
 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
import arcade

# --- Set up the constants

# Size of the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600

# Size of the rectangle
RECT_WIDTH = 50
RECT_HEIGHT = 50


def on_draw(delta_time):
    """
    Use this function to draw everything to the screen.
    This function will be called over and over because of the "schedule"
    command below.
    """

    arcade.start_render()

    # Draw a rectangle.
    arcade.draw_rectangle_filled(100, 50,
                                 RECT_WIDTH, RECT_HEIGHT,
                                 arcade.color.ALIZARIN_CRIMSON)

# Open up our window
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Bouncing Rectangle Example")
arcade.set_background_color(arcade.color.WHITE)

# The "schedule" command
# Tell the computer to call the draw command 80 times per second
arcade.schedule(on_draw, 1 / 80)

# Run the program
arcade.run()

Example 1

Now for the animation.

In this example, we move the box to the left by changing center_x. Also note that every time we use center_x we let the computer know it is a variable inside of on_draw that persists between calls. We do this by calling it on_draw.center_x.

animate_example_01.py
 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
import arcade

# --- Set up the constants

# Size of the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600

# Size of the rectangle
RECT_WIDTH = 50
RECT_HEIGHT = 50


def on_draw(delta_time):
    """
    Use this function to draw everything to the screen.
    This function will be called over and over because of the "schedule"
    command below.
    """

    arcade.start_render()

    # Draw a rectangle.
    arcade.draw_rectangle_filled(on_draw.center_x, on_draw.center_y,
                                 RECT_WIDTH, RECT_HEIGHT,
                                 arcade.color.ALIZARIN_CRIMSON)

    # Modify rectangle's position.
    # Notice our variable starts with the function name and a period
    # 'on_draw.'
    # We use this to keep a value between function calls.
    on_draw.center_x += 1


# Give our function variables a starting value.
on_draw.center_x = 100      # Initial x position
on_draw.center_y = 50       # Initial y position

# Open up our window
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Bouncing Rectangle Example")
arcade.set_background_color(arcade.color.WHITE)

# The "schedule" command
# Tell the computer to call the draw command 80 times per second
arcade.schedule(on_draw, 1 / 80)

# Run the program
arcade.run()

Example 2

This example moves the box up and to the left by changing both x and y. We also move the code for drawing the window into a main function.

animate_example_02.py
 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
import arcade

# --- Set up the constants

# Size of the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600

# Size of the rectangle
RECT_WIDTH = 50
RECT_HEIGHT = 50


def on_draw(delta_time):
    """
    Use this function to draw everything to the screen.
    This function will be called over and over because of the "schedule"
    command below.
    """

    arcade.start_render()

    # Draw a rectangle.
    arcade.draw_rectangle_filled(on_draw.center_x, on_draw.center_y,
                                 RECT_WIDTH, RECT_HEIGHT,
                                 arcade.color.ALIZARIN_CRIMSON)

    # Modify rectangle's position
    on_draw.center_x += 1
    on_draw.center_y += 1


on_draw.center_x = 100      # Initial x position
on_draw.center_y = 50       # Initial y position


def main():
    # Open up our window
    arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Bouncing Rectangle Example")
    arcade.set_background_color(arcade.color.WHITE)

    # The "schedule" command
    # Tell the computer to call the draw command 80 times per second
    arcade.schedule(on_draw, 1 / 80)

    # Run the program
    arcade.run()

main()

Example 3

This example uses new variables delta_x and delta_y to track the vector of the rectangle. It will multiply either of these by -1 to reverse the direction when we hit the edge of the screen.

But it isn’t perfect, because we are checking the center of the rectangle to hit the edge, rather than the outside edge of the rectangle.

animate_example_03.py
 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import arcade

# --- Set up the constants

# Size of the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600

# Size of the rectangle
RECT_WIDTH = 50
RECT_HEIGHT = 50


def on_draw(delta_time):
    """
    Use this function to draw everything to the screen.
    """

    # Start the render. This must happen before any drawing
    # commands. We do NOT need a stop render command.
    arcade.start_render()

    # Draw a rectangle.
    # For a full list of colors see:
    # http://pythonhosted.org/arcade/arcade.color.html
    arcade.draw_rectangle_filled(on_draw.center_x, on_draw.center_y,
                                 RECT_WIDTH, RECT_HEIGHT,
                                 arcade.color.ALIZARIN_CRIMSON)

    # Modify rectangle's position based on the delta
    # vector. (Delta means change. You can also think
    # of this as our speed and direction.)
    on_draw.center_x += on_draw.delta_x
    on_draw.center_y += on_draw.delta_y

    # Figure out if we hit the edge and need to reverse.
    if on_draw.center_x < 0:
        on_draw.delta_x *= -1
    if on_draw.center_x > SCREEN_WIDTH:
        on_draw.delta_x *= -1

    if on_draw.center_y < 0:
        on_draw.delta_y *= -1
    if on_draw.center_y > SCREEN_HEIGHT:
        on_draw.delta_y *= -1

# Below are function-specific variables. Before we use them
# in our function, we need to give them initial values. Then
# the values will persist between function calls.
#
# In other languages, we'd declare the variables as 'static' inside the
# function to get that same functionality.
#
# Later on, we'll use 'classes' to track position and velocity for multiple
# objects.
on_draw.center_x = 100      # Initial x position
on_draw.center_y = 50       # Initial y position
on_draw.delta_x = 4  # Initial change in x
on_draw.delta_y = 4  # Initial change in y


def main():
    # Open up our window
    arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Bouncing Rectangle Example")
    arcade.set_background_color(arcade.color.WHITE)

    # Tell the computer to call the draw command at the specified interval.
    arcade.schedule(on_draw, 1 / 80)

    # Run the program
    arcade.run()


if __name__ == "__main__":
    main()

Example 4

This adds the math to check the outside edge.

animate_example_04.py
 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import arcade

# --- Set up the constants

# Size of the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600

# Size of the rectangle
RECT_WIDTH = 50
RECT_HEIGHT = 50


def on_draw(delta_time):
    """
    Use this function to draw everything to the screen.
    """

    # Start the render. This must happen before any drawing
    # commands. We do NOT need a stop render command.
    arcade.start_render()

    # Draw a rectangle.
    # For a full list of colors see:
    # http://pythonhosted.org/arcade/arcade.color.html
    arcade.draw_rectangle_filled(on_draw.center_x, on_draw.center_y,
                                 RECT_WIDTH, RECT_HEIGHT,
                                 arcade.color.ALIZARIN_CRIMSON)

    # Modify rectangle's position based on the delta
    # vector. (Delta means change. You can also think
    # of this as our speed and direction.)
    on_draw.center_x += on_draw.delta_x
    on_draw.center_y += on_draw.delta_y

    # Figure out if we hit the edge and need to reverse.
    if on_draw.center_x < RECT_WIDTH // 2:
        on_draw.delta_x *= -1
    if on_draw.center_x > SCREEN_WIDTH - RECT_WIDTH // 2:
        on_draw.delta_x *= -1

    if on_draw.center_y < RECT_HEIGHT // 2:
        on_draw.delta_y *= -1
    if on_draw.center_y > SCREEN_HEIGHT - RECT_HEIGHT // 2:
        on_draw.delta_y *= -1

# Below are function-specific variables. Before we use them
# in our function, we need to give them initial values. Then
# the values will persist between function calls.
#
# In other languages, we'd declare the variables as 'static' inside the
# function to get that same functionality.
#
# Later on, we'll use 'classes' to track position and velocity for multiple
# objects.
on_draw.center_x = 100      # Initial x position
on_draw.center_y = 50       # Initial y position
on_draw.delta_x = 4  # Initial change in x
on_draw.delta_y = 4  # Initial change in y


def main():
    # Open up our window
    arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Bouncing Rectangle Example")
    arcade.set_background_color(arcade.color.WHITE)

    # Tell the computer to call the draw command at the specified interval.
    arcade.schedule(on_draw, 1 / 80)

    # Run the program
    arcade.run()


if __name__ == "__main__":
    main()
    

Example 5

We get a variable called delta_time that holds how long it has been since the computer was last called. If the computer is slowing down, we can keep the movement from slowing down by adjusting for the actual time between function calls. The example below tracks how many pixels per second we should travel, then multiplies that by delta_time.

Note that a video walkthrough of the code is at: https://vimeo.com/168063840

animate_example_full.py
 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""
This simple animation example shows how to bounce a rectangle
on the screen.

It assumes a programmer knows how to create functions already.

It does not assume a programmer knows how to create classes. If you do know
how to create classes, see the starting template for a better example:

http://pythonhosted.org/arcade/examples/starting_template.html

Or look through the examples showing how to use Sprites.

A video walk-through of this example is available at:
https://vimeo.com/168063840
"""

import arcade

# --- Set up the constants

# Size of the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600

# Size of the rectangle
RECT_WIDTH = 50
RECT_HEIGHT = 50


def on_draw(delta_time):
    """
    Use this function to draw everything to the screen.
    """

    # Start the render. This must happen before any drawing
    # commands. We do NOT need a stop render command.
    arcade.start_render()

    # Draw a rectangle.
    # For a full list of colors see:
    # http://pythonhosted.org/arcade/arcade.color.html
    arcade.draw_rectangle_filled(on_draw.center_x, on_draw.center_y,
                                 RECT_WIDTH, RECT_HEIGHT,
                                 arcade.color.ALIZARIN_CRIMSON)

    # Modify rectangle's position based on the delta
    # vector. (Delta means change. You can also think
    # of this as our speed and direction.)
    on_draw.center_x += on_draw.delta_x * delta_time
    on_draw.center_y += on_draw.delta_y * delta_time

    # Figure out if we hit the edge and need to reverse.
    if on_draw.center_x < RECT_WIDTH // 2 \
            or on_draw.center_x > SCREEN_WIDTH - RECT_WIDTH // 2:
        on_draw.delta_x *= -1
    if on_draw.center_y < RECT_HEIGHT // 2 \
            or on_draw.center_y > SCREEN_HEIGHT - RECT_HEIGHT // 2:
        on_draw.delta_y *= -1

# Below are function-specific variables. Before we use them
# in our function, we need to give them initial values. Then
# the values will persist between function calls.
#
# In other languages, we'd declare the variables as 'static' inside the
# function to get that same functionality.
#
# Later on, we'll use 'classes' to track position and velocity for multiple
# objects.
on_draw.center_x = 100      # Initial x position
on_draw.center_y = 50       # Initial y position
on_draw.delta_x = 115  # Initial change in x
on_draw.delta_y = 130  # Initial change in y


def main():
    # Open up our window
    arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Bouncing Rectangle Example")
    arcade.set_background_color(arcade.color.WHITE)

    # Tell the computer to call the draw command at the specified interval.
    arcade.schedule(on_draw, 1 / 80)

    # Run the program
    arcade.run()


if __name__ == "__main__":
    main()