# Bouncing Ball with Gravity¶

bouncing_ball.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``` ```""" Bounce a ball on the screen, using gravity. If Python and Arcade are installed, this example can be run from the command line with: python -m arcade.examples.bouncing_ball """ import arcade # --- Set up the constants # Size of the screen SCREEN_WIDTH = 600 SCREEN_HEIGHT = 600 SCREEN_TITLE = "Bouncing Ball Example" # Size of the circle. CIRCLE_RADIUS = 20 # How strong the gravity is. GRAVITY_CONSTANT = 0.3 # Percent of velocity maintained on a bounce. BOUNCINESS = 0.9 def 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 an stop render command. arcade.start_render() # Draw our rectangle arcade.draw_circle_filled(draw.x, draw.y, CIRCLE_RADIUS, arcade.color.BLACK) # Modify rectangles position based on the delta # vector. (Delta means change. You can also think # of this as our speed and direction.) draw.x += draw.delta_x draw.y += draw.delta_y draw.delta_y -= GRAVITY_CONSTANT # Figure out if we hit the left or right edge and need to reverse. if draw.x < CIRCLE_RADIUS and draw.delta_x < 0: draw.delta_x *= -BOUNCINESS elif draw.x > SCREEN_WIDTH - CIRCLE_RADIUS and draw.delta_x > 0: draw.delta_x *= -BOUNCINESS # See if we hit the bottom if draw.y < CIRCLE_RADIUS and draw.delta_y < 0: # If we bounce with a decent velocity, do a normal bounce. # Otherwise we won't have enough time resolution to accurate represent # the bounce and it will bounce forever. So we'll divide the bounciness # by half to let it settle out. if draw.delta_y * -1 > GRAVITY_CONSTANT * 15: draw.delta_y *= -BOUNCINESS else: draw.delta_y *= -BOUNCINESS / 2 # 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. draw.x = CIRCLE_RADIUS # type: ignore # dynamic attribute on function obj # Initial x position draw.y = SCREEN_HEIGHT - CIRCLE_RADIUS # type: ignore # dynamic attribute on function obj # Initial x position draw.delta_x = 2 # type: ignore # dynamic attribute on function obj # Initial x position draw.delta_y = 0 # type: ignore # dynamic attribute on function obj # Initial x position def main(): # Open up our window arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE) arcade.set_background_color(arcade.color.WHITE) # Tell the computer to call the draw command at the specified interval. arcade.schedule(draw, 1 / 80) # Run the program arcade.run() # When done running the program, close the window. arcade.close_window() if __name__ == "__main__": main() ```