Menu
CoddyTech

النقاط والسرعة

جزء من قسم قواعد اللعبة في رحلة Pygame على Coddy. الدرس 28 من 29.

تُحتسب نتيجة لعبة الركض اللانهائي حسب المسافة. يضيف مؤقّت نقطة كل 100 ms، لذا تُساوي ثانية واحدة من الركض 10 نقاط:

POINT = pygame.USEREVENT + 2
pygame.time.set_timer(POINT, 100)

اعرض النتيجة في أعلى اليمين بأصفار بادئة، مثل 00042، كما في Meteor Dodge.

تزداد صعوبة اللعبة مع تقدّمك. اربط السرعة بالنتيجة: 6 بكسلات لكل إطار في البداية، وزِدها بمقدار واحد كل 100 نقطة، على ألا تتجاوز 14 مطلقًا:

speed = min(14, 6 + score // 100)

تقرأ Obstacle.update() قيمة speed في كل إطار، لذا تصل السرعة الجديدة أيضًا إلى العوائق الموجودة على الشاشة بالفعل. تمثّل min الحد الأقصى: عند 14، يعبر العائق النافذة في أقل من ثانية، وأي سرعة أعلى من ذلك لن تتيح للاعب التفاعل.

challenge icon

التحدي

متوسط
  1. أضف POINT = pygame.USEREVENT + 2، واضبط مؤقتًا له كل 100 ms، وأضف score = 0.
  2. أثناء اللعب، أضف 1 إلى النتيجة عند حدوث POINT.
  3. أثناء اللعب، اضبط speed = min(14, 6 + score // 100) قبل التحديث.
  4. اعرض النتيجة بخمسة أرقام باللون (40, 50, 80) عند الموضع topright=(630, 10).

جرّب بنفسك

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((640, 320))
pygame.display.set_caption("Sky Runner")
clock = pygame.time.Clock()
font = pygame.font.Font("assets/fonts/pixel.ttf", 32)

SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1
SPAWN = pygame.USEREVENT + 1


class Runner(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.frames = [
            pygame.image.load("assets/images/player.png").convert_alpha(),
            pygame.image.load("assets/images/player_walk.png").convert_alpha(),
        ]
        self.image = self.frames[0]
        self.step = 0
        self.rect = self.image.get_rect(midbottom=(100, GROUND_Y))
        self.vy = 0

    def jump(self):
        if self.rect.bottom == GROUND_Y:
            self.vy = -16

    def update(self):
        self.vy += GRAVITY
        self.rect.y += self.vy
        if self.rect.bottom >= GROUND_Y:
            self.rect.bottom = GROUND_Y
            self.vy = 0
        if self.rect.bottom == GROUND_Y:
            self.step += 1
            self.image = self.frames[self.step // 8 % 2]
        else:
            self.image = self.frames[1]


class Obstacle(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = random.choice(obstacle_images)
        self.rect = self.image.get_rect(midbottom=(664, GROUND_Y))

    def update(self):
        self.rect.x -= speed
        if self.rect.right < 0:
            self.kill()


obstacle_images = [
    pygame.image.load("assets/images/spike_ball.png").convert_alpha(),
    pygame.image.load("assets/images/blob.png").convert_alpha(),
]
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
pygame.time.set_timer(SPAWN, 1500)
state = "play"

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
            if state == "play":
                runner.jump()
        if event.type == SPAWN and state == "play":
            obstacles.add(Obstacle())
            pygame.time.set_timer(SPAWN, random.randint(1000, 2000))

    if state == "play":
        runner.update()
        obstacles.update()
        if pygame.sprite.spritecollideany(runner, obstacles, pygame.sprite.collide_mask):
            state = "over"

    screen.fill(SKY)
    pygame.draw.rect(screen, GROUND, (0, GROUND_Y, 640, 60))
    screen.blit(runner.image, runner.rect)
    obstacles.draw(screen)
    if state == "over":
        message = font.render("Game over", True, (40, 50, 80))
        screen.blit(message, message.get_rect(center=(320, 140)))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس قواعد اللعبة

تدرّب بنفسك: Playground لـ Pygame