Dette er del tre av en femdelers serie av opplæringsprogrammer om å lage spill med Python 3 og Pygame. I del to, vi dekket TextObject
klassen brukes til å gjengi tekst på skjermen, opprettet hovedvinduet, og lærte å tegne gjenstander som murstein, ballen og padle.
I denne delen vil vi dykke inn i hjertet av Breakout og lære å håndtere hendelser, møte de viktigste Breakout-klassene, og se hvordan du kan flytte de forskjellige spillobjektene.
I Breakout er det tre typer hendelser: tastetrykk hendelser, mus hendelser og timer hendelser. Hovedløkken i Game-klassen tar seg av tastetrykk og mushendelser og gir dem til abonnenter (ved å ringe en handlerfunksjon).
Mens spillklassen er veldig generisk og har ingen Breakout-spesifikk kunnskap, er abonnementet selv og hvordan man håndterer hver hendelse veldig spesifikk.
Breakout-klassen er der mesteparten av domenekunnskapen om Breakout-spillet er administrert. Vi vil møte Breakout-klassen flere ganger i løpet av denne serien. Her er linjene som registrerer de ulike arrangementshåndteringene.
Noter det alle viktige hendelser for både venstre og høyre piltastene vil gå til samme håndteringsmetode for padle.
# Registrer håndtaket håndtaksmus_event () for en knappobjekt selv.mouse_handlers.append (b.handle_mouse_event) # Registrer håndtaket () -metoden til padlen for å håndtere viktige hendelser selv.keydown_handlers [pygame.K_LEFT] .append (paddle.handle) self.keydown_handlers [pygame.K_RIGHT] .append (paddle.handle) self.keyup_handlers [pygame.K_LEFT] .append (paddle.handle) self.keyup_handlers [pygame.K_RIGHT] .append (paddle.handle)
Spillklassen vil ringe de registrerte handlerne for hver nøkkelhendelse og sende nøkkelen. Legg merke til at det ikke er Paddle-klassen. I Breakout er det eneste objektet som er interessert i disse hendelsene, padlen. Når en tast trykkes eller slippes, er dens håndtak()
Metoden kalles.
Padleen trenger ikke å vite om det var en nøkkel ned eller nøkkel opphendelse fordi den styrer nåværende tilstand gjennom et par boolske variabler: moving_left
og moving_right
. Hvis moving_left
er sant, betyr det at venstre piltast er trykket og neste hendelse vil bli tastet opp, noe som vil frigjøre det. Det samme gjelder for høyre piltast. Logikken er like enkelt som å bytte disse variablene som svar på enhver hendelse.
def håndtak (selv, nøkkel): hvis nøkkel == pygame.K_LEFT: self.moving_left = ikke self.moving_left annet: self.moving_right = ikke self.moving_right
Breakout har en spillmeny du møter snart. Knappen på menyen håndterer ulike mus hendelser som bevegelse og klikk (mus ned og mus opp hendelser). Som svar på disse hendelsene oppdaterer knappen en intern tilstandsvariabel. Her er musens håndteringskode:
def handle_mouse_event (selv, type, pos): hvis type == pygame.MOUSEMOTION: self.handle_mouse_move (pos) elif type == pygame.MOUSEBUTTONDOWN: self.handle_mouse_down (pos) elif type == pygame.MOUSEBUTTONUP: self.handle_mouse_up pos) def handle_mouse_move (selv, pos): hvis self.bounds.collidepoint (pos): hvis self.state! = 'presset': self.state = 'hover' annet: self.state = 'normal' def handle_mouse_down , pos): hvis self.bounds.collidepoint (pos): self.state = 'presset' def handle_mouse_up (selv, post): hvis selvstart == 'trykket': self.on_click (self) self.state = ' sveve'
Legg merke til at handle_mouse_event ()
Metode som er registrert for å motta mushendelser, kontrollerer typen av hendelsen og videresender den til den spesifikke metoden som håndterer den aktuelle hendelsestypen.
Timer hendelser behandles ikke gjennom hovedløkken. Men siden hovedløkken kalles hver ramme, er det enkelt å sjekke om en bestemt tidsbegrenset hendelse skyldes. Du vil se et eksempel på dette senere når du diskuterer tidsbestemte spesialeffekter.
En annen situasjon er når vi vil fryse spillet, for eksempel når du viser en melding om at spilleren skal kunne lese uten distraksjon. De Vis melding()
Metoden for Breakout-klassen bruker denne tilnærmingen og samtalen time.sleep ()
. Her er den aktuelle koden:
importere config som c klasse Breakout (Spill): def show_message (selv, tekst, farge = colors.WHITE, font_name = "Arial", font_size = 20, sentralisert = False): message = TextObject (c.screen_width // 2, c .screen_height // 2, lambda: tekst, farge, font_name, font_size) self.draw () message.draw (self.surface, sentralisert) pygame.display.update () time.sleep (c.message_duration)
Gameplay-delen er hvor regler for Breakout kommer til å spille (se hva jeg gjorde der?). Gameplay handler om å flytte de forskjellige objektene som svar på hendelsene og endre spilltilstanden basert på deres interaksjoner.
Du så tidligere at Padle-klassen reagerer på piltastene ved å oppdatere dens moving_left
og moving_right
Enger. Den faktiske bevegelsen skjer i Oppdater()
metode. Det er noen beregning skjer her hvis padleen er nær venstre eller høyre kant av skjermen. Vi vil ikke at padleen skal bevege seg utover kantene på skjermen (inkludert en forhåndsdefinert forskyvning).
Så hvis bevegelsen ville ha tatt den utover kanten, justerer koden bevegelsen for å stoppe nøyaktig ved kanten. Siden padleen bare beveger seg horisontalt, er den vertikale delen av bevegelsen alltid null.
import pygame import config som c fra game_object import GameObject klassen Paddle (GameObject): def __init __ (selv, x, y, w, h, farge, offset): GameObject .__ init __ (selv, x, y, w, h) selv. farge = farge self.offset = offset self.moving_left = False self.moving_right = False ... def oppdatering (selv): hvis self.moving_left: dx = - (min.autom.autset, self.left)) elif self.moving_right: dx = min (self.offset, c.screen_width - self.right) ellers: return self.move (dx, 0)
Ballen bruker bare funksjonaliteten til GameObject
grunnklasse, som beveger spillobjekter basert på deres fart (med horisontale og vertikale komponenter). Hastigheten på ballen er bestemt av mange faktorer i Breakout-klassen som du snart vil se. Siden bevegeligheten bare legger hastigheten til den nåværende stillingen, er retningen ballen beveger seg fullt bestemt av sin hastighet langs horisontale og vertikale akser.
Ballen i Breakout ser ut av ingensteds i begynnelsen av spillet hver gang spilleren mister livet. Det materialiserer bare ut av eter og begynner å falle enten rett ned eller i liten vinkel. Når ballen er opprettet i create_ball ()
metode, mottar den en hastighet med en tilfeldig horisontal komponent mellom -2 og 2 og en vertikal komponent, som bestemmes i config.py-modulen (for øyeblikket satt til 3).
def create_ball (selv): speed = (random.randint (-2, 2), c.ball_speed) self.ball = Ball (c.screen_width // 2, c.screen_height // 2, c.ball_radius, c.ball_color , hastighet) self.objects.append (self.ball)
I denne delen dekket vi hendelseshåndtering som tastetrykk, musebevegelse og museklikk. Vi gjør også dykk i noen av spillets elementer i Breakout, slik at du beveger padleen, flytter ballen og styrer ballen.
Husk også å se hva vi har tilgjengelig for salg og for studier i Envato Market hvis du ønsker å studere mer Python-relatert materiale.
I del fire vil vi takle det viktige kollisionsdetekteringsemnet og se hva som skjer når ballen rammer forskjellige spillobjekter som padle, murstein og til og med veggene, taket og gulvet.
Da blir vi oppmerksom på spillmenyen. Vi oppretter egendefinerte knapper som vi vil bruke som en meny vi kan vise og skjule etter behov.