בטוח אחרי פגיעה
חלק מהיחידה חוקי המשחק במסלול ה-Pygame של Coddy. שיעור 10 מתוך 29.
עמוד מתחת לסלע בגרסה הזאת. הסלע כבר לא קופץ בחזרה למעלה כשהוא פוגע, הוא עובר דרך השחקן ונוגע בשחקן במשך הרבה פריימים ברצף. כל אחד מהפריימים האלה מוריד חיים, כך שסלע אחד מסיים את המשחק.
במשחקים רבים יש פרק זמן קצר של חסינות לאחר פגיעה. כדי לדעת כמה זמן עבר, בדוק את השעון. pygame.time.get_ticks() הוא מספר אלפיות השנייה שחלפו מאז pygame.init(). זכור את רגע הפגיעה והחסר ממנו:
now = pygame.time.get_ticks()
if rock.colliderect(player) and now - hit_time > 1000:
hit_time = now
lives -= 1התחל את hit_time בערך -2000 בתוך reset(), כדי שהפגיעה הראשונה תמיד תיחשב.
הצג את זמן החסינות באמצעות הבהוב. הביטוי get_ticks() // 100 % 2 מחזיר 0 במשך עשירית שנייה, ואז 1, ואז שוב 0, ולכן ציור השחקן רק כשהערך הוא 0 גורם לו להבהב:
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)אתגר
בינוני- ב־
reset(), הגדירו אתhit_time = -2000(הוסיפו אותו לשורתglobal). - פגיעה גורעת חיים רק כאשר עברו יותר מ־1000 ms מאז
hit_time; לאחר מכן הגדירו אתhit_timeלזמן הנוכחי. - במשך 1000 ms לאחר פגיעה, ציירו את השחקן רק כאשר
pygame.time.get_ticks() // 100 % 2 == 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)
def reset():
global player, rock, score, lives
player = pygame.Rect(220, 300, 40, 40)
rock = pygame.Rect(random.randint(0, 456), -24, 24, 24)
score = 0
lives = 3
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)
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
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
if rock.colliderect(player):
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 אונליין