Welcome to an exploration into Python’s capabilities into 2D animation. This article offers a focused approach into creating a specific animation scenario, a ball rolling down stairs, using Python and the robust Pygame library.
This technical deep-dive will provide a detailed understanding of the animation implementation process, along with an in-depth examination of features within the Pygame library.
Why to use PyGame for ball bouncing animation?
Pygame is like a magic toolbox for making video games with Python. It’s super handy because it not only helps you create games but also adds cool stuff like pictures, sounds, and special effects to make your game awesome.
Inside Pygame, there are special tools called ‘libraries’ that help you work with pictures and sounds. These libraries make it way easier to create the graphics and sounds for your game.
The best part? Pygame is perfect for beginners! If you’re just starting out with game development, Pygame takes away a lot of the tricky stuff and makes it really simple to design games.
Define PyGame constants for animation
This Python code snippet is defining the constants (parameters) and widht-height of the strairs for a Pygame animation of a ball bouncing down stairs.
import pygame
import sys
# Define constants
WIDTH, HEIGHT = 800, 500
BALL_RADIUS = 10
GRAVITY = 9.8
TIME_DELTA = 0.1
INITIAL_VELOCITY = 0
FORWARD_VELOCITY = 1 # constant for forward velocity
BOUNCE_DAMPENING = 0.7 # constant to reduce velocity after each bounce
STAIR_HEIGHT = 50 # constant for the height of each stair
STAIR_WIDTH = 100 # constant for the width of each stair
# Define the stairs
STAIRS = [(WIDTH - (i+1) * STAIR_WIDTH, HEIGHT - i * STAIR_HEIGHT) for i in range(WIDTH // STAIR_WIDTH)]
Here’s a breakdown of each line:
– WIDTH, HEIGHT = 800, 500: These are the dimensions of the Pygame window.
– BALL_RADIUS = 10: This is the radius of the ball in the animation.
– GRAVITY = 9.8: This is the gravity constant, which affects how fast the ball falls.
– TIME_DELTA = 0.1: This is the time step for each frame of the animation.
– INITIAL_VELOCITY = 0: This is the initial vertical velocity of the ball.
– FORWARD_VELOCITY = 1: This is the constant horizontal velocity of the ball.
– BOUNCE_DAMPENING = 0.7: This is a factor that reduces the ball’s velocity after each bounce, simulating energy loss.
– STAIR_HEIGHT = 50 and STAIR_WIDTH = 100: These are the dimensions of each stair in the animation.
– STAIRS = [(WIDTH – (i+1) * STAIR_WIDTH, HEIGHT – i * STAIR_HEIGHT) for i in range(WIDTH // STAIR_WIDTH)]: This line generates a list of tuples, each representing the position of a stair.
The x-coordinate of each stair is calculated by subtracting the width of the stair times its index from the width of the window. The y-coordinate is calculated by subtracting the height of the stair times its index from the height of the window. The number of stairs is determined by the width of the window divided by the width of the stairs.
Define ball related properties and physics
The code below is a part of a simple 2D physics simulation using the Pygame library. It simulates a ball bouncing down a set of steps.
# Initialize Pygame
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
class Ball:
def __init__(self, x, y, radius, color=(255, 0, 0)):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.velocity = INITIAL_VELOCITY
self.forward_velocity = FORWARD_VELOCITY # New attribute for forward velocity
def draw(self):
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius)
def update(self):
self.velocity += GRAVITY * TIME_DELTA
self.y += self.velocity * TIME_DELTA
self.x += self.forward_velocity # Update x position with forward velocity
# Roll down the stairs
for stair in STAIRS:
if self.y + self.radius > stair[1] and self.x + self.radius > stair[0] and self.x - self.radius < stair[0] + STAIR_WIDTH:
self.y = stair[1] - self.radius
self.velocity = -self.velocity * BOUNCE_DAMPENING # Reduce velocity after each bounce
break
# Create a ball
ball = Ball(0, HEIGHT , BALL_RADIUS) # Ball starts from the top most stair
Here’s a breakdown of the code:
1. Pygame is initialized and a screen is created with dimensions defined by WIDTH and HEIGHT.
2. A Ball class is defined with attributes for position (x, y), radius, color, velocity, and forward_velocity.
- The __init__ method initializes these attributes.
- The draw method draws the ball on the screen using the pygame.draw.circle function.
- The update method updates the ball’s position and velocity. It first applies gravity to the ball’s vertical velocity, then updates the ball’s vertical and horizontal positions. It also checks if the ball is hitting a stair and if so, it sets the ball’s position to be on top of the stair and reverses its velocity (simulating a bounce), also applying a dampening factor.
3. An instance of the Ball class is created, representing a ball starting from the top of the screen.
Generate animation of ball bouncing down steps
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill((0, 0, 0))
for stair in STAIRS: # Draw the stairs
pygame.draw.rect(screen, (255, 255, 255), pygame.Rect(stair[0], stair[1], STAIR_WIDTH, STAIR_HEIGHT))
ball.draw()
ball.update()
pygame.display.flip()
pygame.time.delay(int(TIME_DELTA * 80))
This is the main game loop for a Pygame application. Here’s a breakdown of what it does:
1. while True:: This is an infinite loop that keeps the game running until an exit condition is met.
2. for event in pygame.event.get():: This loop checks for any events (like mouse clicks, key presses, etc.) that Pygame has registered.
3. if event.type == pygame.QUIT:: If the event is a QUIT event (like closing the window), the game will stop.
4. pygame.quit() and sys.exit(): These commands are used to exit the Pygame and Python programs.
5. screen.fill((0, 0, 0)): This line clears the screen by filling it with black color (RGB: 0, 0, 0).
6. for stair in STAIRS:: This loop draws each stair on the screen. The stairs are represented as white rectangles.
7. ball.draw(): This line draws the ball on the screen.
8. ball.update(): This line updates the ball’s position based on its velocity and the effect of gravity.
9. pygame.display.flip(): This command updates the entire display to show the new positions of the ball and stairs.
10. pygame.time.delay(int(TIME_DELTA * 80)): This line creates a delay to control the speed of the game. The delay is based on the TIME_DELTA constant.
As you can see the possibilities of creating similar simulations using PyGame are endless. I urge you to take inspiration from this tutorial and create animations and simulations. However, if you want to use matplotlib to create similar anmations then check out this article.