حدث مؤقّت
جزء من قسم قواعد اللعبة في رحلة Pygame على Coddy. الدرس 11 من 29.
تُكافئ النقطة الواحدة عن كل صخرة تسقط من أمامك الانتظار. لكن احتساب نقطة عن كل ثانية تصمد فيها أكثر إنصافًا. يمكن لـ pygame إرسال حدث خاص بلعبتك كل ثانية.
أنواع الأحداث هي أرقام. pygame.USEREVENT هو أول رقم يتركه pygame متاحًا لك، لذا سمِّ نوع الحدث الخاص بك انطلاقًا منه:
POINT = pygame.USEREVENT + 1
...
pygame.time.set_timer(POINT, 1000)منذ ذلك الحين، يصل حدث POINT كل 1000 ms مع الأحداث الأخرى، وتعالجه كما تعالج ضغطة مفتاح:
if event.type == POINT and state == "play":
score += 1يظل المؤقّت يعمل في القائمة وعلى شاشة انتهاء اللعبة، لذا تحقّق من الحالة. يؤدي استدعاء set_timer مرة أخرى إلى إعادة تشغيله، ولهذا يوضع في reset(): تنتظر كل لعبة جديدة ثانية كاملة قبل الحصول على أول نقطة.
التحدي
متوسط- أضف
POINT = pygame.USEREVENT + 1بعد الألوان. - في
reset()، ابدأ مؤقّتًا يرسلPOINTكل 1000 مللي ثانية. - عند وقوع حدث
POINTأثناء اللعب، أضف 1 إلى النقاط. - لم تعد الصخور التي تسقط إلى أسفل تمنح نقاطًا.
جرّب بنفسك
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)
def reset():
global player, rock, score, lives, hit_time
player = pygame.Rect(220, 300, 40, 40)
rock = pygame.Rect(random.randint(0, 456), -24, 24, 24)
score = 0
lives = 3
hit_time = -2000
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))
safe = pygame.time.get_ticks() - hit_time < 1000
if not safe or pygame.time.get_ticks() // 100 % 2 == 0:
pygame.draw.rect(screen, (255, 196, 0), player)
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 score, lives, state, hit_time
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())
rock.y += 4
if rock.top > 360:
rock.y = -24
rock.x = random.randint(0, 456)
score += 1
now = pygame.time.get_ticks()
if rock.colliderect(player) and now - hit_time > 1000:
hit_time = now
lives -= 1
if lives == 0:
state = "over"
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)))
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:
if event.key == pygame.K_RETURN and state == "menu":
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