Menu
CoddyTech

אירוע טיימר

חלק מהיחידה חוקי המשחק במסלול ה-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(): כל משחק חדש ממתין שנייה שלמה לפני הנקודה הראשונה.

challenge icon

אתגר

בינוני
  1. הוסיפו את POINT = pygame.USEREVENT + 1 אחרי הצבעים.
  2. בתוך reset(), הפעילו טיימר ששולח את POINT כל 1000 ms.
  3. כאשר מתרחש אירוע POINT במהלך המשחק, הוסיפו 1 לניקוד.
  4. סלעים שנופלים מעבר למסך כבר לא מוסיפים ניקוד.

נסו בעצמכם

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()
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה חוקי המשחק

תרגלו בעצמכם: Pygame אונליין