Try the game: Physics Ball Simulator by dot-ammar
This game, I wrote in Python, is a physics-based simulation that provides an interactive and visual representation of key concepts from AP Physics 1. It allows users to control a ball's movement, observing real-time changes in velocity, acceleration, and distance traveled. The game's physics engine calculates the trajectory of the ball under the influence of gravity and user interactions, offering a practical understanding of kinematics and dynamics.
The Game simulates gravity and its effect on the ball's movement. Gravity is defined in terms of pixels per frame squared, scaled to the screen's dimensions:
PIXELS_PER_METER = 100
GRAVITY = 9.8 * PIXELS_PER_METER / (FPS**2)
The function predict_path
calculates the ball's trajectory based on its current position, velocity, gravity, and screen boundaries. It uses a loop to iteratively update the ball's position using its velocity, adjusting for gravity with each step:
for _ in range(max_steps):
x += velocity_x
y += velocity_y
velocity_y += gravity
path.append((x, y))
Velocity is calculated in a way that is essentially:
pos_x += vel_x * time_step
pos_y += vel_y * time_step + 0.5 * gravity * time_step ** 2
vel_y += gravity * time_step
The game handles collisions with the ground, ceiling, and walls. Upon collision, it modifies the ball's velocity to simulate a bounce, applying a dampening factor to simulate energy loss:
if ball_rect.bottom >= screen.get_height():
ball_velocity[1] *= -0.7
ball_velocity[0] *= friction
The game calculates and displays real-time metrics like velocity, acceleration, and distance traveled. Velocity and acceleration are computed in meters per second, considering the frame rate for time measurement. The distance is calculated by including the velocity over time:
velocity_x = (ball_velocity[0] / PIXELS_PER_METER) * FPS
distance_traveled += velocity_magnitude * SECONDS_PER_FRAME
Users can interact with the ball, dragging and throwing it. The game tracks mouse movement to determine the ball's new velocity when released:
if dragging:
ball_velocity = weighted_velocity[:]
where weighted_velocity
is defined by:
current_mouse_pos = pygame.mouse.get_pos()
ball_rect.center = current_mouse_pos
# Calculate the instantaneous velocity
movement_x = current_mouse_pos[0] - last_mouse_pos[0]
movement_y = current_mouse_pos[1] - last_mouse_pos[1]
if abs(movement_x) > MIN_MOVEMENT_THRESHOLD or abs(movement_y) > MIN_MOVEMENT_THRESHOLD:
instant_velocity = [movement_x, movement_y]
# Update the weighted velocity
weighted_velocity[0] = alpha * instant_velocity[0] + (1 - alpha) * weighted_velocity[0]
weighted_velocity[1] = alpha * instant_velocity[1] + (1 - alpha) * weighted_velocity[1]
else:
# Reset weighted_velocity if there's no significant movement
weighted_velocity = [0, 0]
last_mouse_pos = current_mouse_pos
This works to create a smooth throwing simulation.
The game demonstrates key concepts from the AP Physics 1 curriculum, including:
- Kinematics in one and two dimensions
- Newton's laws of motion
- Friction and collisions
Screen.Recording.2024-01-09.at.11.28.55.PM.mov
![image](https://private-user-images.githubusercontent.com/80134790/295449266-03f81138-ea74-4daa-ba76-0a21b525be0f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkzMzY0NjUsIm5iZiI6MTczOTMzNjE2NSwicGF0aCI6Ii84MDEzNDc5MC8yOTU0NDkyNjYtMDNmODExMzgtZWE3NC00ZGFhLWJhNzYtMGEyMWI1MjViZTBmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTIlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEyVDA0NTYwNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTE0MDg2NmE0YjU3ZGIzZTk0M2NiMTRjYjMyOTk3ZWZhYTRhMzlkMzNkYTI1OTdkZjU1YWM2MjViNWJjYTU4MDEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.i_1hEMyZakOvyvqZzZy3g8U_5UANQZWLR5t54Cp3YAI)
Key observation from metrics:
- Acceleration is constant
9.8m/s^2
- X Velocity is constant through the air.
- Y Velocity changes due to acceleration.