1"""
2Bounce a ball on the screen, using gravity.
3
4If Python and Arcade are installed, this example can be run from the command line with:
5python -m arcade.examples.bouncing_ball
6"""
7
8import arcade
9
10# --- Set up the constants
11
12# Size of the screen
13SCREEN_WIDTH = 600
14SCREEN_HEIGHT = 600
15SCREEN_TITLE = "Bouncing Ball Example"
16
17# Size of the circle.
18CIRCLE_RADIUS = 20
19
20# How strong the gravity is.
21GRAVITY_CONSTANT = 0.3
22
23# Percent of velocity maintained on a bounce.
24BOUNCINESS = 0.9
25
26
27def draw(_delta_time):
28 """
29 Use this function to draw everything to the screen.
30 """
31
32 # Start the render. This must happen before any drawing
33 # commands. We do NOT need an stop render command.
34 arcade.start_render()
35
36 # Draw our rectangle
37 arcade.draw_circle_filled(draw.x, draw.y, CIRCLE_RADIUS,
38 arcade.color.BLACK)
39
40 # Modify rectangles position based on the delta
41 # vector. (Delta means change. You can also think
42 # of this as our speed and direction.)
43 draw.x += draw.delta_x
44 draw.y += draw.delta_y
45
46 draw.delta_y -= GRAVITY_CONSTANT
47
48 # Figure out if we hit the left or right edge and need to reverse.
49 if draw.x < CIRCLE_RADIUS and draw.delta_x < 0:
50 draw.delta_x *= -BOUNCINESS
51 elif draw.x > SCREEN_WIDTH - CIRCLE_RADIUS and draw.delta_x > 0:
52 draw.delta_x *= -BOUNCINESS
53
54 # See if we hit the bottom
55 if draw.y < CIRCLE_RADIUS and draw.delta_y < 0:
56 # If we bounce with a decent velocity, do a normal bounce.
57 # Otherwise we won't have enough time resolution to accurate represent
58 # the bounce and it will bounce forever. So we'll divide the bounciness
59 # by half to let it settle out.
60 if draw.delta_y * -1 > GRAVITY_CONSTANT * 15:
61 draw.delta_y *= -BOUNCINESS
62 else:
63 draw.delta_y *= -BOUNCINESS / 2
64
65
66# Below are function-specific variables. Before we use them
67# in our function, we need to give them initial values. Then
68# the values will persist between function calls.
69#
70# In other languages, we'd declare the variables as 'static' inside the
71# function to get that same functionality.
72#
73# Later on, we'll use 'classes' to track position and velocity for multiple
74# objects.
75draw.x = CIRCLE_RADIUS # type: ignore # dynamic attribute on function obj # Initial x position
76draw.y = SCREEN_HEIGHT - CIRCLE_RADIUS # type: ignore # dynamic attribute on function obj # Initial x position
77draw.delta_x = 2 # type: ignore # dynamic attribute on function obj # Initial x position
78draw.delta_y = 0 # type: ignore # dynamic attribute on function obj # Initial x position
79
80
81def main():
82 # Open up our window
83 arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
84 arcade.set_background_color(arcade.color.WHITE)
85
86 # Tell the computer to call the draw command at the specified interval.
87 arcade.schedule(draw, 1 / 80)
88
89 # Run the program
90 arcade.run()
91
92 # When done running the program, close the window.
93 arcade.close_window()
94
95
96if __name__ == "__main__":
97 main()