أفضل نتيجة وإعادة تشغيل آمنة
جزء من قسم قواعد اللعبة في رحلة Pygame على Coddy. الدرس 30 من 30.
تعرض شاشة انتهاء اللعبة أفضل نتيجة وتبدأ لعبة جديدة عند الضغط على مفتاح المسافة. تُعيَّن قيمة best مرة واحدة، قبل الحلقة، وخارج reset()، لذا تحتفظ اللعبة الجديدة بها.
يؤدي مفتاح المسافة الآن وظيفة ثالثة على شاشة انتهاء اللعبة:
elif pygame.time.get_ticks() - over_time > 500:
reset()
state = "play"مفتاح المسافة هو مفتاح القفز، لذا غالبًا ما يكون اللاعب ضاغطًا عليه لحظة الاصطدام. من دون انتظار، ستُعاد اللعبة قبل أن يرى اللاعب النتيجة. تذكّر وقت الاصطدام في over_time، ولا تقبل الضغط على مفتاح المسافة على شاشة انتهاء اللعبة إلا بعد مرور 500 مللي ثانية.
التحدي
صعباعرض أفضل نتيجة وأعد التشغيل بأمان.
- بعد
state = "menu"، عيّنbest = 0وover_time = 0. عند الاصطدام، تُعيَّنbest = max(best, score)وتُضبطover_timeعلى الوقت الحالي. - تعرض شاشة انتهاء اللعبة
Game overوBest: 00120وPress Space to play again. - هناك، يستدعي مفتاح المسافة
reset()وتبدأ اللعبة مجددًا، بعد مرور 500 ms على الأقل منذ الاصطدام.
اضغط «العب» واصطدم: ستظهر أفضل نتيجة، ويبدأ مفتاح المسافة اللعبة من جديد. ثم اضغط «تحقق».
جرّب بنفسك
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)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
INK = (40, 50, 80)
SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1
SPAWN = pygame.USEREVENT + 1
POINT = pygame.USEREVENT + 2
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(),
]
def reset():
global runner, obstacles, speed, score
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
score = 0
pygame.time.set_timer(SPAWN, 1500)
pygame.time.set_timer(POINT, 100)
def show(text, text_font, y):
picture = text_font.render(text, True, INK)
screen.blit(picture, picture.get_rect(center=(320, y)))
reset()
state = "menu"
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()
elif state == "menu":
reset()
state = "play"
if event.type == SPAWN and state == "play":
obstacles.add(Obstacle())
pygame.time.set_timer(SPAWN, random.randint(1000, 2000))
if event.type == POINT and state == "play":
score += 1
if state == "play":
speed = min(14, 6 + score // 100)
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 == "menu":
show("Sky Runner", big_font, 110)
show("Press Space to start", font, 170)
else:
score_text = font.render(f"{score:05}", True, INK)
screen.blit(score_text, score_text.get_rect(topright=(630, 10)))
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()
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس قواعد اللعبة
6عدّاء السماء
العدّاءالقفزتدرّب بنفسك: Playground لـ Pygame