به‌روزرسانی و بازنشانی امتیاز

به‌روزرسانی امتیاز با نابودی موجودات بیگانه

برای نمایش زنده‌ی امتیاز روی صفحه مقدار stats.score را با نابودی هر موجود بیگانه به‌روزرسانی می‌کنیم و سپس prep_score() را برای به‌روزرسانی تصویرِ امتیاز صدا می‌کنیم. امّا ابتدا اجازه امتیازی را که هر بازیکن با زدن هر موجود بیگانه کسب می‌کند تعیین کنیم:

1
2
3
4
5
def initialize_dynamic_settings(self):
    --snip--

    # Scoring
    self.alien_points = 50

با پیشرفت بازی امتیاز هر موجود بیگانه را افزایش خواهیم داد. برای اطمینان از بازنشانی این امتیاز با شروع دوباره‌ی بازی، مقدار آن را در initialize_dynamic_settings() تعیین می‌کنیم.

با هر بار نابود شدن یک موجود بیگانه امتیاز را در _check_bullet_alien_collisions() به‌روز می‌کنیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def _check_bullet_alien_collisions(self):
    """Respond to bullet-alien collisions."""
    # Remove any bullets and aliens that have collided.
    collisions = pygame.sprite.groupcollide(
            self.bullets, self.aliens, True, True)

    if collisions:
        self.stats.score += self.settings.alien_points
        self.sb.prep_score()

    --snip--

زمانی که گلوله‌ای به یک موجود بیگانه اصابت می‌کند پای‌گیم دیکشنری collisions را برمی‌گرداند. ما وجود این دیکشنری را بررسی می‌کنیم و در صورت وجود مقدار ارزش موجود بیگانه را به امتیاز اضافه می‌کنیم. سپس prep_score() را برای ساختن تصویر جدیدی از امتیاز به‌روزشده صدا می‌کنیم.

اکنون هنگامی که هجوم بیگانگان را بازی می‌کنید باید بتوانید امتیاز خود را حساب کنید!

بازنشانی امتیاز

تا اینجا ما امتیاز جدید را پس از نابودی یک موجود بیگانه نمایش می‌دهیم که در بیشتر قسمت‌های بازی همین‌طور باید باشد. امّا در آغاز یک بازی جدید و تا پیش از این که اوّلین موجود بیگانه کشته شود، همچنان امتیاز قدیمی را می‌بینیم.

این مسأله را با نمایش امتیاز هنگام شروع یک بازی جدید برطرف می‌کنیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def _check_play_button(self, mouse_pos):
    --snip--

    if button_clicked and not self.stats.game_active:
        --snip--

        # Reset the game statistics.
        self.stats.reset_stats()

        self.stats.game_active = True

        self.sb.prep_score()

    --snip--

پس از بازنشانی آمارهای بازی هنگام شروع یک بازی جدید متد prep_score() را فرامی‌خوانیم. این کار امتیاز ۰ را روی تابلوی امتیازات نمایش می‌دهد.

اطمینان یافتن از ثبت امتیاز تمام شلّیک‌های موفّق

کدی که تا اینجا نوشته‌ایم امتیاز کشتن برخی موجودات بیگانه را جا می‌اندازد. برای مثال اگر در یک اجرای حلقه دو گلوله به موجودات بیگانه برخورد کند یا در صورتی‌که برای کشتن همزمان چند موجود بیگانه گلوله‌ای عریض‌تر در نظر بگیریم، بازیکن تنها امتیاز کشتن یک موجود بیگانه را دریافت خواهد کرد. برای حل این مشکل روش تشخیص برخورد گلوله و موجود بیگانه را بهبود می‌بخشیم.

در _check_bullet_alien_collisions() هر گلوله‌ای که به یک موجود بیگانه برخورد کند به کلیدی در دیکشنری collisions تبدیل خواهد شد. مقدار مرتبط با هر کلید لیستی از موجودات بیگانه است که گلوله به آن‌ها اصابت کرده است. در مقدارهای دیکشنری collisions حلقه می‌زنیم تا مطمئن شویم که به کشتنِ هر موجود بیگانه امتیازی اختصاص داده‌ایم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def _check_bullet_alien_collisions(self):
    --snip--

    if collisions:
        for aliens in collisions.values():
            self.stats.score += self.settings.alien_points * len(aliens)

        self.sb.prep_score()

    --snip--

اگر دیکشنری collisions تعریف شده باشد در تمام مقدارهای آن حلقه می‌زنیم. به یاد داریم که هر مقدار لیستی از موجودات بیگانه‌ای است که با یک گلوله کشته شده‌اند. ارزش هر کدام از موجودات بیگانه را در تعداد آن‌ها در هر لیست ضرب کرده و این مقدار را به امتیاز فعلی اضافه می‌کنیم. برای آزمایش درستی این کد عرض هر گلوله را به ۳۰۰ پیکسل افزایش دهید و امتیازهای کسب‌شده برای کشتن هر موجود بیگانه را با این گلوله‌ی عریض بررسی کنید؛ سپس عرض گلوله را به مقدار اوّلیّه‌ی خود برگردانید.

افزایش مقدار امتیازها

چون با رسیدن بازیکن به مرحله‌ای جدید بازی سخت‌تر می‌شود، موجودات بیگانه در مرحله‌های بالاتر ارزش بیشتری دارند. برای پیاده‌سازی این قابلیّت کدی اضافه می‌کنیم تا با افزایش سرعت بازی، مقدار امتیاز افزایش یابد:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Settings:
    """A class to store all settings for Alien Invasion."""

    def __init__(self):
        --snip--

        # How quickly the game speeds up
        self.speedup_scale = 1.1

        self.initialize_dynamic_settings()

    def initialize_dynamic_settings(self):
        --snip--

    def increase_speed(self):
        """Increase speed settings and alien point values."""
        self.ship_speed *= self.speedup_scale
        self.bullet_speed *= self.speedup_scale
        self.alien_speed *= self.speedup_scale

        self.alien_points = int(self.alien_points * self.score_scale)

نرخی به نام score_scale تعریف می‌کنیم که امتیازها بر اساس آن افزایش می‌یابد. افزایش کوچکی در سرعت (1.1) بازی را به سرعت چالشی می‌کند. امّا برای ایجاد تغییر قابل توجّه‌تری در امتیازدهی باید ارزش امتیاز هر موجود بیگانه را با مقدار بزرگتری (1.5) تغییر دهیم. حال همزمان با افزایش سرعت بازی ارزش امتیاز هر شلّیک موفّق را هم افزایش می‌دهیم. از تابع int() برای افزایش ارزش امتیاز بر اساس یک عدد صحیح استفاده می‌کنیم.

برای دیدن ارزش امتیاز کشتن هر موجود بیگانه یک print() به متد increase_speed() در Settings اضافه می‌کنیم:

1
2
3
4
5
6
def increase_speed(self):
    --snip--

    self.alien_points = int(self.alien_points * self.score_scale)

    print(self.alien_points)
نکته
حتماً پس از بررسی صحّت افزایش ارزش امتیاز فراخوانی print() را حذف کنید زیرا ممکن است بر عملکرد بازی تاثیر بگذارد و حواس بازیکن را پرت کند.