برنامه نویسی

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

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

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا