Menabrak
Termasuk bagian Aturan Game dalam perjalanan Pygame di Coddy. Pelajaran 27 dari 29.
Menyentuh rintangan akan mengakhiri permainan. pygame.sprite.spritecollideany(sprite, group) mengembalikan sprite pertama dalam grup yang menyentuh sprite tersebut, atau None.
Secara default, fungsi ini membandingkan rect. Gambar-gambarnya memiliki sudut tembus pandang, terutama blob, jadi dua rect bisa saling tumpang tindih meskipun tidak ada bagian yang terlihat saling menyentuh. Argumen ketiga memilih pengujian yang lebih akurat:
if pygame.sprite.spritecollideany(runner, obstacles, pygame.sprite.collide_mask):
state = "over"collide_mask membandingkan piksel gambar yang terlihat dan mengabaikan bagian yang tembus pandang. Jadi, tabrakan hanya terjadi saat pemain bisa melihatnya.
State bekerja seperti di Meteor Dodge: pembaruan, lompatan, dan rintangan baru hanya terjadi saat nilainya "play", dan layar game over menampilkan permainan yang membeku dengan sebuah pesan.
Tantangan
Sedang- Tambahkan font
assets/fonts/pixel.ttfdengan ukuran 32, danstate = "play". - Hanya saat state bernilai
"play": lompat, tambahkan rintangan, perbarui runner dan rintangan. - Saat runner menyentuh rintangan (
collide_mask), atur state menjadi"over". - Saat game berakhir, tampilkan
Game overdi(40, 50, 80)dengan posisi tengah di (320, 140).
Coba sendiri
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 320))
pygame.display.set_caption("Sky Runner")
clock = pygame.time.Clock()
SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1
SPAWN = pygame.USEREVENT + 1
class Runner(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.frames = [
pygame.image.load("assets/images/player.png").convert_alpha(),
pygame.image.load("assets/images/player_walk.png").convert_alpha(),
]
self.image = self.frames[0]
self.step = 0
self.rect = self.image.get_rect(midbottom=(100, GROUND_Y))
self.vy = 0
def jump(self):
if self.rect.bottom == GROUND_Y:
self.vy = -16
def update(self):
self.vy += GRAVITY
self.rect.y += self.vy
if self.rect.bottom >= GROUND_Y:
self.rect.bottom = GROUND_Y
self.vy = 0
if self.rect.bottom == GROUND_Y:
self.step += 1
self.image = self.frames[self.step // 8 % 2]
else:
self.image = self.frames[1]
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = random.choice(obstacle_images)
self.rect = self.image.get_rect(midbottom=(664, GROUND_Y))
def update(self):
self.rect.x -= speed
if self.rect.right < 0:
self.kill()
obstacle_images = [
pygame.image.load("assets/images/spike_ball.png").convert_alpha(),
pygame.image.load("assets/images/blob.png").convert_alpha(),
]
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
pygame.time.set_timer(SPAWN, 1500)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
runner.jump()
if event.type == SPAWN:
obstacles.add(Obstacle())
pygame.time.set_timer(SPAWN, random.randint(1000, 2000))
runner.update()
obstacles.update()
screen.fill(SKY)
pygame.draw.rect(screen, GROUND, (0, GROUND_Y, 640, 60))
screen.blit(runner.image, runner.rect)
obstacles.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Semua pelajaran di Aturan Game
Latihan sendiri: Playground Pygame