אירוע טיימר
חלק מהיחידה חוקי המשחק במסלול ה-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 ms. - כאשר מתרחש אירוע
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()
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה חוקי המשחק
תרגלו בעצמכם: Pygame אונליין