Menu
CoddyTech

Darbe Sonrası Güvende

Coddy'nin Pygame Journey'sinin Oyun Kuralları bölümünün bir parçası. Ders 10 / 29.

Bu sürümde bir kayanın altında dur. Kaya çarptığında artık en üste geri zıplamaz, oyuncunun içinden düşer ve oyuncuya art arda birçok kare boyunca dokunur. Bu karelerin her biri bir can götürür, bu yüzden tek bir kaya oyunu bitirir.

Birçok oyun, çarpışmadan sonra kısa bir güvenli süre verir. Ne kadar zaman geçtiğini öğrenmek için saate sor. pygame.time.get_ticks(), pygame.init() çağrıldığından beri geçen milisaniye sayısıdır. Çarpışma anını hatırla ve çıkar:

now = pygame.time.get_ticks()
if rock.colliderect(player) and now - hit_time > 1000:
    hit_time = now
    lives -= 1

İlk çarpışmanın her zaman sayılması için reset() içinde hit_time değerini -2000 olarak başlat.

Güvenli süreyi yanıp sönerek göster. get_ticks() // 100 % 2 saniyenin onda biri boyunca 0, sonra 1, ardından yeniden 0 olur; bu yüzden oyuncuyu yalnızca değer 0 olduğunda çizmek, yanıp sönmesini sağlar:

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)
challenge icon

Görev

Orta
  1. reset() içinde hit_time = -2000 ayarla (global satırına ekle).
  2. hit_time üzerinden 1000 ms'den fazla zaman geçtiğinde, isabet bir can götürür; ardından hit_time değerini şimdiki zamana ayarla.
  3. İsabetten sonraki 1000 ms boyunca oyuncuyu yalnızca pygame.time.get_ticks() // 100 % 2 == 0 olduğunda çiz.

Kendin dene

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()

Oyun Kuralları bölümündeki tüm dersler

Kendi başına pratik yap: Pygame playground