مقدمه

در این درس، قابلیت شلیک گلوله را به بازی اضافه می‌کنیم. ما به بازیکن اجازه خواهیم داد تا با فشردن کلید فاصله (spacebar)، یک گلوله را از سفینه به سمت بالای صفحه شلیک کند. برای این کار، ما یک کلاس جدید برای گلوله‌ها می‌سازیم و از گروه‌های Pygame برای مدیریت تمام گلوله‌های فعال در صفحه استفاده خواهیم کرد.

ایجاد کلاس Bullet

مانند سفینه، ما منطق مربوط به گلوله‌ها را نیز در یک کلاس جداگانه به نام Bullet کپسوله‌سازی می‌کنیم. این کلاس از کلاس Sprite در Pygame ارث‌بری می‌کند که به ما اجازه می‌دهد تا عناصر مرتبط را در یک گروه (Group) مدیریت کنیم. یک فایل جدید به نام bullet.py بسازید.

Copy Icon bullet.py
import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """A class to manage bullets fired from the ship."""

    def __init__(self, ai_game):
        """Create a bullet object at the ship's current position."""
        super().__init__()
        self.screen = ai_game.screen
        self.settings = ai_game.settings
        self.color = self.settings.bullet_color

        # Create a bullet rect at (0, 0) and then set correct position.
        self.rect = pygame.Rect(0, 0, self.settings.bullet_width, self.settings.bullet_height)
        self.rect.midtop = ai_game.ship.rect.midtop
        
        # Store the bullet's position as a float.
        self.y = float(self.rect.y)

    def update(self):
        """Move the bullet up the screen."""
        # Update the exact position of the bullet.
        self.y -= self.settings.bullet_speed
        # Update the rect position.
        self.rect.y = self.y

    def draw_bullet(self):
        """Draw the bullet to the screen."""
        pygame.draw.rect(self.screen, self.color, self.rect)

این کلاس به جای یک تصویر، یک مستطیل ساده را به عنوان گلوله ترسیم می‌کند. در سازنده، ما یک مستطیل با ابعاد مشخص ساخته و موقعیت midtop آن را برابر با موقعیت midtop سفینه قرار می‌دهیم تا به نظر برسد که گلوله از سفینه شلیک می‌شود.

متد update مسئول حرکت دادن گلوله به سمت بالای صفحه است. ما موقعیت عمودی را به صورت یک عدد اعشاری (float) ذخیره می‌کنیم تا بتوانیم سرعت حرکت را با دقت بیشتری کنترل کنیم.

مدیریت گلوله‌ها

حالا باید کد AlienInvasion را برای مدیریت شلیک و حرکت گلوله‌ها به‌روزرسانی کنیم.

ذخیره گلوله‌ها در یک گروه (Group)

ما از pygame.sprite.Group برای ذخیره تمام گلوله‌های فعال در بازی استفاده خواهیم کرد. Group یک کلاس ویژه در Pygame است که شبیه به یک لیست عمل می‌کند اما متدهای اضافی برای مدیریت Spriteها دارد.

Copy Icon alien_invasion.py
# In __init__() method:
self.bullets = pygame.sprite.Group()

# In _check_keydown_events() method (inside `_check_events`):
elif event.key == pygame.K_SPACE:
    self._fire_bullet()

# New method in AlienInvasion class:
def _fire_bullet(self):
    """Create a new bullet and add it to the bullets group."""
    new_bullet = Bullet(self)
    self.bullets.add(new_bullet)

# In run_game() method:
self.bullets.update() # Update positions of all bullets

# In _update_screen() method (which you should create from the drawing code in `run_game`):
for bullet in self.bullets.sprites():
    bullet.draw_bullet()

ما یک گروه جدید به نام bullets می‌سازیم. وقتی کاربر کلید فاصله را فشار می‌دهد، تابع _fire_bullet فراخوانی شده، یک نمونه جدید از Bullet ساخته و آن را به گروه اضافه می‌کند.

فراخوانی self.bullets.update() به صورت خودکار متد update را روی تمام گلوله‌های داخل گروه اجرا می‌کند. به همین ترتیب، در حلقه ترسیم، ما روی sprites گروه پیمایش کرده و هر گلوله را ترسیم می‌کنیم.

حذف گلوله‌های خارج از صفحه

گلوله‌ها پس از خروج از بالای صفحه، دیگر نیازی به آنها نیست و باید از حافظه حذف شوند تا از مصرف بیهوده منابع جلوگیری شود.

Copy Icon alien_invasion.py
# Inside run_game() method, after bullets.update():
# Get rid of bullets that have disappeared.
for bullet in self.bullets.copy():
    if bullet.rect.bottom <= 0:
        self.bullets.remove(bullet)

در این کد، ما روی یک کپی از گروه bullets پیمایش می‌کنیم. این کار به ما اجازه می‌دهد تا در داخل حلقه، گلوله‌ها را از گروه اصلی حذف کنیم. اگر یک گلوله از لبه بالایی صفحه (bottom <= 0) عبور کرده باشد، آن را از گروه حذف می‌کنیم.

در این درس، ما با موفقیت قابلیت شلیک را به بازی خود اضافه کردیم. با ایجاد یک کلاس Bullet و استفاده از pygame.sprite.Group توانستیم به صورت کارآمد چندین گلوله را مدیریت، حرکت داده و حذف کنیم. در فصل بعدی، «ساخت بازی هجوم بیگانگان (۲)»، ما اولین دشمنان خود یعنی «ناوگانی از بیگانگان» را به بازی اضافه خواهیم کرد.