Menu
CoddyTech

Aman Setelah Terkena Benturan

Termasuk bagian Aturan Game dalam perjalanan Pygame di Coddy. Pelajaran 10 dari 29.

Berdirilah di bawah batu dalam versi ini. Batu tidak lagi melompat kembali ke atas saat menabrak, batu jatuh menembus pemain, dan menyentuh pemain selama banyak frame berturut-turut. Setiap frame mengurangi satu nyawa, jadi satu batu mengakhiri permainan.

Banyak game memberi waktu aman singkat setelah terkena serangan. Untuk mengetahui berapa lama waktu yang telah berlalu, tanyakan pada jam. pygame.time.get_ticks() adalah jumlah milidetik sejak pygame.init(). Ingat momen saat terkena serangan, lalu kurangi:

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

Atur hit_time ke -2000 di reset(), agar serangan pertama selalu dihitung.

Tampilkan waktu aman dengan membuat pemain berkedip. get_ticks() // 100 % 2 bernilai 0 selama sepersepuluh detik, lalu 1, kemudian kembali menjadi 0, jadi menggambar pemain hanya saat nilainya 0 akan membuatnya berkedip:

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

Tantangan

Sedang
  1. Di dalam reset(), atur hit_time = -2000 (tambahkan ke baris global).
  2. Nyawa berkurang akibat terkena hanya jika lebih dari 1000 ms telah berlalu sejak hit_time; lalu atur hit_time ke waktu saat ini.
  3. Selama 1000 ms setelah terkena, gambar pemain hanya ketika pygame.time.get_ticks() // 100 % 2 == 0.

Coba sendiri

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

Semua pelajaran di Aturan Game

Latihan sendiri: Playground Pygame