احفظ الرقم القياسي
جزء من قسم قواعد اللعبة في رحلة Pygame على Coddy. الدرس 20 من 29.
أغلق اللعبة وسيختفي best: لا تعيش المتغيرات إلا أثناء تشغيل البرنامج. للاحتفاظ برقم للمرة القادمة، اكتبه في ملف.
with open("highscore.txt", "w") as file:
file.write(str(best))تفتح open(..., "w") الملف للكتابة. وتنشئ الملف إذا لم يكن موجودًا، وتفرغه إذا كان موجودًا، لذا يحتوي الملف دائمًا على رقم واحد. تأخذ write نصًا، ولهذا تحوّل str(best) الرقم إلى نص أولًا. وتغلق كتلة with الملف عند انتهائها، لذا يُحفَظ كل ما كُتب.
لا يحتوي اسم الملف على مجلد، لذا يُنشأ الملف في المجلد الذي يعمل منه البرنامج. على جهاز الكمبيوتر، شغّل main.py من مجلده الخاص، وسيظهر highscore.txt بجواره ويبقى هناك.
في المتصفح، تعيش ملفات اللعبة في ذاكرة الصفحة: العب مرة أخرى وسيظل الملف موجودًا، لكن إعادة تحميل الصفحة تبدأ دون ملف.
التحدي
متوسط- عندما تنتهي اللعبة، وبعد تحديث
best، اكتب قيمته فيhighscore.txt.
جرّب بنفسك
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)
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