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

در این مقاله ، ما از طریق یک برنامه پایتون که با استفاده از کتابخانه 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 ، می توانید تجسم های پویا و تعاملی ایجاد کنید و آن را به یک انتخاب عالی برای ایجاد بازی ها و شبیه سازی ها تبدیل کنید.



