شبیه سازی توپ های تندرست با برخورد در پایتون با استفاده از پیگام

در این مقاله ، ما از طریق یک برنامه پایتون که با استفاده از کتابخانه Pygame ، توپ های تندرست را در یک پنجره شبیه سازی می کند ، قدم می زنیم. این کد همچنین شامل عملکردی برای تشخیص و حل برخورد بین توپ ها است. این مثال مقدمه خوبی برای هر دو فیزیک اساسی در برنامه نویسی و نحوه استفاده از PyGame برای ایجاد شبیه سازی های پویا ارائه می دهد.
آنچه یاد خواهید گرفت
- تنظیم پیگام برای ایجاد یک شبیه سازی.
- اجرای حرکت اساسی توپ ها با سرعت تصادفی.
- تشخیص برخورد بین توپ و حل آنها مطابق با اصول فیزیکی.
- با استفاده از برنامه نویسی شی گرا (OOP) در پایتون برای ساختار شبیه سازی.
تنظیم محیط
قبل از غواصی به کد ، باید اطمینان حاصل کنیم که Pygame نصب شده است. اگر هنوز پیگام را نصب نکرده اید ، می توانید با استفاده از PIP این کار را انجام دهید:
pip install pygame
درک کد
در اینجا مروری بر نحوه عملکرد برنامه آورده شده است:
1 تنظیم اولیه Pygame و تنظیم نمایش
pygame.init()
# Set up the display
width = 800
height = 600
ball_radius = 20
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
کد با شروع Pygame و تنظیم صفحه نمایش شروع می شود. ابعاد پنجره 800×600 پیکسل است و هر توپ در شبیه سازی شعاع 20 پیکسل دارد.
2 تعریف رنگ ها
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
اینها تعاریف رنگی RGB است که برای ارائه توپ و پس زمینه استفاده می شود. در این حالت ، ما سه رنگ برای توپ (قرمز ، سبز ، آبی) و دو رنگ برای پس زمینه (سفید و سیاه) داریم.
3 کلاس توپ: مدیریت توپ های انفرادی
class Ball:
def __init__(self, color):
self.x = random.randint(ball_radius, width - ball_radius)
self.y = random.randint(ball_radius, height - ball_radius)
self.velocity_x = random.randint(1, 3) * 2
self.velocity_y = random.randint(1, 3) * -2
self.color = color
در Ball
کلاس برای این برنامه مهم است. هر شیء توپ دارای خواصی مانند موقعیت است (x
با y
) ، سرعت (velocity_x
با velocity_y
) ، و رنگ. موقعیت و سرعت اولیه توپ به طور تصادفی تنظیم می شود ، بنابراین هر توپ در یک مکان متفاوت شروع می شود و با سرعت منحصر به فرد حرکت می کند.
4 حرکت توپ ها و استفاده از مرزهای مرزی
def move(self):
self.x += self.velocity_x
self.y += self.velocity_y
# Bounce off walls, considering the radius of the ball
if self.x <= ball_radius or self.x >= width - ball_radius:
self.velocity_x *= -1
if self.x <= ball_radius:
self.x = ball_radius
elif self.x >= width - ball_radius:
self.x = width - ball_radius
if self.y <= ball_radius:
self.velocity_y *= -1
self.y = ball_radius
elif self.y >= height - ball_radius:
self.velocity_y *= -1
self.y = height - ball_radius
در move
روش موقعیت توپ را بر اساس سرعت آن به روز می کند. این برنامه با معکوس کردن سرعت در امتداد محور مربوطه هنگام برخورد یک دیوار ، برخوردهای دیواری را کنترل می کند و باعث می شود توپ از دیوارها گزاف گویی کند.
5 کشیدن توپ روی صفحه
def draw(self):
pygame.draw.circle(screen, self.color, (self.x, self.y), ball_radius)
در draw
روش از pygame استفاده می کند pygame.draw.circle()
عملکردی را برای ارائه هر توپ روی صفحه با رنگ و موقعیت مربوطه خود انجام دهید.
6 برخورد با توپ به توپ
def check_collision(self, other_ball):
dx = self.x - other_ball.x
dy = self.y - other_ball.y
distance = math.sqrt(dx**2 + dy**2)
# If the distance between centers is less than twice the radius, a collision occurred
if distance < 2 * ball_radius:
# Normalize the vector between the two balls
normal_vector = pygame.math.Vector2(dx, dy).normalize()
# Calculate relative velocity
relative_velocity = pygame.math.Vector2(self.velocity_x, self.velocity_y) - pygame.math.Vector2(other_ball.velocity_x, other_ball.velocity_y)
# Calculate the velocity along the normal vector (dot product)
velocity_along_normal = relative_velocity.dot(normal_vector)
if velocity_along_normal > 0:
return
# Calculate the impulse scalar
impulse = 2 * velocity_along_normal / (2 * ball_radius)
# Apply the impulse to the velocities of both balls
self.velocity_x -= impulse * normal_vector.x
self.velocity_y -= impulse * normal_vector.y
other_ball.velocity_x += impulse * normal_vector.x
other_ball.velocity_y += impulse * normal_vector.y
# Reposition the balls to avoid overlap
overlap = 2 * ball_radius - distance
self.x += normal_vector.x * overlap / 2
self.y += normal_vector.y * overlap / 2
other_ball.x -= normal_vector.x * overlap / 2
other_ball.y -= normal_vector.y * overlap / 2
در check_collision
روش تشخیص برخورد بین دو توپ را کنترل می کند. این فاصله بین مراکز دو توپ را محاسبه می کند. اگر فاصله کمتر از مجموع شعاع آنها باشد (یعنی آنها با هم همپوشانی دارند) ، این برنامه از اصول اساسی فیزیک برای حل برخورد با تنظیم سرعت و موقعیت های توپ استفاده می کند. این تضمین می کند که توپ ها به روشی واقع بینانه از یکدیگر گزاف گویی می کنند.
7 حلقه بازی اصلی
balls = [Ball(red), Ball(green), Ball(blue)]
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Move and check collisions for each ball
for ball in balls:
ball.move()
# Check for collisions between the balls
for i in range(len(balls)):
for j in range(i + 1, len(balls)):
balls[i].check_collision(balls[j])
# Draw the window
screen.fill(white)
# Draw all balls
for ball in balls:
ball.draw()
# Update and render
pygame.display.flip()
clock.tick(60)
حلقه بازی اصلی به طور مداوم موقعیت های توپ ها را به روز می کند ، چک ها را بررسی می کند و صفحه را ارائه می دهد. پنجره در شروع هر تکرار حلقه با یک پس زمینه سفید پر شده است و سپس هر توپ در بالا کشیده می شود. حلقه با 60 فریم در ثانیه اجرا می شود (clock.tick(60)
).
8 خروج از برنامه
pygame.quit()
وقتی کاربر پنجره را می بندد ، پیگام خاموش می شود و برنامه خاتمه می یابد.
کد کامل
در اینجا کد کامل برای شبیه سازی وجود دارد:
import pygame
import random
import math
# Initialize Pygame
pygame.init()
# Set up the display
width = 800
height = 600
ball_radius = 20
# Define colors
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
# Create a Pygame display surface
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
# Ball class to manage multiple balls
class Ball:
def __init__(self, color):
self.x = random.randint(ball_radius, width - ball_radius)
self.y = random.randint(ball_radius, height - ball_radius)
self.velocity_x = random.randint(1, 3) * 2
self.velocity_y = random.randint(1, 3) * -2
self.color = color
def move(self):
self.x += self.velocity_x
self.y += self.velocity_y
# Bounce off walls, considering the radius of the ball
if self.x <= ball_radius or self.x >= width - ball_radius:
self.velocity_x *= -1
if self.x <= ball_radius:
self.x = ball_radius
elif self.x >= width - ball_radius:
self.x = width - ball_radius
if self.y <= ball_radius:
self.velocity_y *= -1
self.y = ball_radius
elif self.y >= height - ball_radius:
self.velocity_y *= -1
self.y = height - ball_radius
def draw(self):
pygame.draw.circle(screen, self.color, (self.x, self.y), ball_radius)
def check_collision(self, other_ball):
dx = self.x - other_ball.x
dy = self.y - other_ball.y
distance = math.sqrt(dx**2 + dy**2)
# If the distance between centers is less than twice the radius, a collision occurred
if distance < 2 * ball_radius:
# Normalize the vector between the two balls
normal_vector = pygame.math.Vector2(dx, dy).normalize()
# Calculate relative velocity
relative_velocity = pygame.math.Vector2(self.velocity_x, self.velocity_y) - pygame.math.Vector2(other_ball.velocity_x, other_ball.velocity_y)
# Calculate the velocity along the normal vector (dot product)
velocity_along_normal = relative_velocity.dot(normal_vector)
if velocity_along_normal > 0:
return
# Calculate the impulse scalar
impulse = 2 * velocity_along_normal / (2 * ball_radius)
# Apply the impulse to the velocities of both balls
self.velocity_x -= impulse * normal_vector.x
self.velocity_y -= impulse * normal_vector.y
other_ball.velocity_x += impulse * normal_vector.x
other_ball.velocity_y += impulse * normal_vector.y
# Reposition the balls to avoid overlap
overlap = 2 * ball_radius - distance
self.x += normal_vector.x * overlap / 2
self.y += normal_vector.y * overlap / 2
other_ball.x -= normal_vector.x * overlap / 2
other_ball.y -= normal_vector.y * overlap / 2
# Create 3 balls of different colors
balls = [Ball(red), Ball(green), Ball(blue)]
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Move and check collisions for each ball
for ball in balls:
ball.move()
# Check for collisions between the balls
for i in range(len(balls)):
for j in range(i + 1, len(balls)):
balls[i].check_collision(balls[j])
# Draw the window
screen.fill(white)
# Draw all balls
for ball in balls:
ball.draw()
# Update and render
pygame.display.flip()
clock.tick(60)
pygame.quit()
پایان
این شبیه سازی ساده اصول اولیه برنامه نویسی شی گرا در پایتون را به همراه مقدمه ای برای تشخیص برخورد و شبیه سازی فیزیک نشان می دهد. با Pygame ، می توانید تجسم های پویا و تعاملی ایجاد کنید و آن را به یک انتخاب عالی برای ایجاد بازی ها و شبیه سازی ها تبدیل کنید.