حمّله عند البدء
جزء من قسم قواعد اللعبة في رحلة Pygame على Coddy. الدرس 21 من 29.
تم حفظ الرقم القياسي؛ والآن اقرأه مجددًا عند بدء اللعبة. يحوّل int(file.read()) نص الملف إلى رقم. في المرة الأولى لا يكون هناك ملف، ويوقف open البرنامج مع FileNotFoundError.
يلتقط try وexcept هذا الخطأ وينفّذان شيئًا آخر بدلًا من ذلك:
def load_best():
try:
with open("highscore.txt") as file:
return int(file.read())
except FileNotFoundError:
return 0
best = load_best()ينفّذ Python كتلة try. إذا أثار open الخطأ FileNotFoundError، ينتقل إلى كتلة except ويُرجع 0. أما أي خطأ آخر، فيظل يوقف البرنامج، وهذا ما تريده: فهو خطأ حقيقي في البرنامج.
يفتح open("highscore.txt") الملف للقراءة عند عدم تحديد وضع.
على جهاز كمبيوتر، أغلق اللعبة وشغّلها مجددًا، وسيظهر أفضل رقم من المرة السابقة على شاشة انتهاء اللعبة الأولى. وفي المتصفح، يحدث الأمر نفسه في كل مرة تضغط فيها على «العب»، إلى أن يُعاد تحميل الصفحة.
التحدي
متوسط- اكتب
load_best(): تُعيد الرقم الموجود فيhighscore.txt، أو 0 إذا لم يكن هذا الملف موجودًا. - عيّن
best = load_best()بدلًا منbest = 0.
جرّب بنفسك
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Meteor Dodge")
clock = pygame.time.Clock()
heart = pygame.image.load("assets/images/heart.png").convert_alpha()
heart_empty = pygame.image.load("assets/images/heart_empty.png").convert_alpha()
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
WHITE = (240, 240, 240)
PLATE = (60, 60, 90)
POINT = pygame.USEREVENT + 1
SPAWN = pygame.USEREVENT + 2
def reset():
global player, rocks, score, lives
player = pygame.Rect(220, 300, 40, 40)
rocks = []
score = 0
lives = 3
pygame.time.set_timer(POINT, 1000)
pygame.time.set_timer(SPAWN, 800)
def draw_menu():
screen.fill((30, 30, 46))
title = big_font.render("Meteor Dodge", True, WHITE)
title_rect = title.get_rect(center=(240, 140))
pygame.draw.rect(screen, PLATE, title_rect.inflate(24, 12))
screen.blit(title, title_rect)
hint = font.render("Press Enter to play", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
def draw_game():
screen.fill((30, 30, 46))
pygame.draw.rect(screen, (255, 196, 0), player)
for rock in rocks:
pygame.draw.rect(screen, (235, 80, 80), rock)
score_text = font.render(f"{score:05}", True, WHITE)
score_rect = score_text.get_rect(topright=(470, 10))
pygame.draw.rect(screen, PLATE, score_rect.inflate(12, 8))
screen.blit(score_text, score_rect)
for i in range(3):
if i < lives:
screen.blit(heart, (10 + i * 40, 10))
else:
screen.blit(heart_empty, (10 + i * 40, 10))
def play_frame():
global rocks, lives, state, best
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 6
if keys[pygame.K_RIGHT]:
player.x += 6
player.clamp_ip(screen.get_rect())
kept = []
for rock in rocks:
rock.y += 3
if rock.colliderect(player):
lives -= 1
elif rock.top <= 360:
kept.append(rock)
rocks = kept
if lives <= 0:
state = "over"
best = max(best, score)
with open("highscore.txt", "w") as file:
file.write(str(best))
draw_game()
def draw_over():
draw_game()
message = big_font.render("Game over", True, WHITE)
screen.blit(message, message.get_rect(center=(240, 160)))
hint = font.render("Press R to play again", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
best_text = font.render(f"Best: {best}", True, WHITE)
screen.blit(best_text, best_text.get_rect(center=(240, 240)))
reset()
state = "menu"
best = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == POINT and state == "play":
score += 1
if event.type == SPAWN and state == "play":
rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and state == "menu":
reset()
state = "play"
elif event.key == pygame.K_r and state == "over":
reset()
state = "play"
if state == "menu":
draw_menu()
elif state == "play":
play_frame()
else:
draw_over()
pygame.display.flip()
clock.tick(60)
pygame.quit()
جميع دروس قواعد اللعبة
تدرّب بنفسك: Playground لـ Pygame