Vi har kommet langt i denne nybegynners guide til objektorientert programmering, og diskuterer prinsippene for samhold, kopling, innkapsling, og abstraksjon. I denne siste artikkelen diskuterer vi OOP-prinsippet om arv og dens bruk i spillutvikling.
Merk: Selv om denne opplæringen er skrevet ved hjelp av Java, bør du kunne bruke de samme teknikkene og konseptene i nesten hvilket som helst spillutviklingsmiljø.
Arv er prinsippet om klassehierarki. Det er evnen til ett objekt å ta på seg tilstandene, oppføringene og funksjonaliteten til et annet objekt.
Et virkelighets eksempel på arv er genetisk arv. Vi mottar alle gener fra begge våre foreldre som deretter definerer hvem vi er. Vi deler kvaliteter av begge foreldrene våre, og likevel er de forskjellige fra dem.
Objekter i OOP kan gjøre det samme. Foreldreklasser kan ha barneklasser (også kjent som superklasser og underklasser), som kan ha de samme egenskapene til foreldreklassen, og kan definere nye tilstander, atferd og egenfunksjon.
For eksempel, vurder følgende klasse som kan brukes som en overordnet klasse til forskjellige former:
offentlig klasse Form beskyttet int høyde; beskyttet int bredde; offentlig form (int h, int w) height = h; bredde = w; offentlig int område () returhøyde * bredde; offentlig int getHeight () returhøyde; offentlig int getWidth () returbredde; offentlig tomgang setHet (int h) returhøyde; Offentlig tomt settWidth (int w) returbredde;
For å utvide denne klassen for å implementere en trekant, ville det se slik ut:
Public Class Triangle utvider Shape Public Triangle (int h, int w) super (h, w); offentlig int område () return super.area () / 2;
Triangel
har alle de samme tilstandene og funksjonene som Form
, men omdefinerer område()
funksjon for å returnere det riktige området av a Triangel
(halv basetid høyde).
Søkeordet super
brukes til å referere til superklassen og noen av dens tilstander og funksjoner. Det er derfor vi kan bruke super()
å ringe konstruktøren til superklassen og super.area ()
å ringe område()
funksjon av superklassen. Så, i dette tilfellet, super.area ()
avkastning høyde bredde
.
De beskyttet
Søkeord er det siste tilgangsnivået. Det virker som den private tilgangsnivåmodifieringsenheten, men tillater også at noen undergrupper har tilgang til variabelen eller funksjonen.
Som du kan se, kan arv i stor grad bidra til å redusere kode redundans mellom lignende gjenstander ved å ta det som disse objektene har til felles og sette dem på ett sted. Dette skaper også mer vedlikeholdsbar kode fordi den bidrar til å overholde prinsippet om DRY og for å forhindre rippel-effekten i kodendringer.
Hvis alt dette virker kjent, er det sannsynligvis fordi abstraksjon hadde svært like fordeler (så vel som de fleste andre prinsipper for OOP). Abstraksjon er nært knyttet til arv som en abstrakt klasse kan brukes som en superklasse for å lage undergrupper. Den eneste forskjellen mellom en abstrakt klasse og en normal klasse er at en abstrakt klasse ikke kan brukes til å skape et objekt.
La oss gå tilbake til våre tre spill en gang til for å beskrive hvordan å søke arv.
Husk at vi definerte en abstrakt klasse for å flytte objekter over en skjerm. Husk også at vi definerte a Skip
klasse for skipets objekt. Å søke arv til asteroider, kan vi ha Skip
klassen forlenge Movable
klassen som følger:
/ ** * Skipsklassen * / offentlig klasse Skipet strekker seg Flyttbar (/ ** * Funksjon for å rotere skipet * / offentlig tomgang rotere () // Kode som gjør skipet / ** * Funksjon for å brenne * / offentlig ugyldig brann () // kode for brann
Koden som trengs for å flytte skipet blir tatt vare på i Movable
abstrakt klasse, så vi kan fjerne den fra Skip
klasse. Alle de andre gjenstandene for asteroider kan også arve fra Movable
klassen, noe som gjør det svært enkelt å endre hvordan man beveger et objekt.
En ting å merke seg om arv er evnen til å ha flere arv, eller en klasses evne til å arve fra flere klasser samtidig. Noen språk tillater det, andre gjør det ikke.
Java er et av språkene som ikke tillater flere arv. Derfor kunne du ikke ha Ship-objektet arve fra begge a Move
klasse og a teikne
klasse.
Arv kan brukes på Tetris ved å ha Tetrimino og alle spillbildene arve fra teikne
klassen, som vi definerte i den siste artikkelen.
Husk at for Pac-Man identifiserte vi deg objekter: Pac-Man, en Ghost og en pac-punkt. Gjennom hele denne serien har vi bare diskutert disse tre gjenstandene og har satt bort å nevne noe om det siste kritiske stykket Pac-Man: kraftpellet. Med arv er vi nå klare til å snakke om det.
En kraftpellett er en spesiell pac-punkt som gjør at Pac-Man kan spise spøkelser. Dens tilstander og oppførsel er akkurat det samme som en pac-punkt, med den eneste forskjellen som er størrelsen og evnen til å blinke (husk at for å holde spillet løst koblet, vil vi ha en annen klasse til å overvåke når en kraftpellet blir spist og aktiv changeState ()
metode for spøkelsene). Dette er når arv kommer til nytte.
Siden en pac-dot og power pellet er praktisk talt det samme objektet, kan vi lage en PowerPellet
klasse som strekker seg PacDot
klasse. De PowerPellet
klassen ville bare måtte endre noen stater for å gjøre det større og legge til at oppførselen til å vokse og krympe for å skape en blinkende effekt. Og det er det - vi har nå en kraftpellet med lite ekstra arbeid. Ikke altfor dårlig.
Koden for hvordan dette ville se ut, kan være som følger:
/ ** * Pac-punktsklassen * / offentlig klasse PacDot strekker Tegningsbar beskyttet int størrelse; beskyttet int score; offentlig PacDot () size = 10; poengsum = 10; / ** * Returnerer verdien av pac-punktet for å legge til spillerens poengsum når spist * / public int getScore () return score; / ** * Returnerer størrelsen på pac-dot * / public int getSize () return size; / ** * Power Pellet Class * / offentlig klasse PowerPellet utvider PacDot private int sizeModifier; // trenger ikke å definere størrelse og score fordi disse er // allerede definert i PacDot - PowerPellet arver dem. offentlig PowerPellet () size = 20; poengsum = 50; sizeModifier = -2; / ** * Blinkfunksjonen som vil bli kalt hver gang kraftpellet * er tegnet. Endrer sizeModifier for å simulere en blinkende effekt * / public void blink () size + = sizeModifier; hvis (størrelse < 10 || size > 20) sizeModifier = -sizeModifier;Det er verdt å nevne at for å holde styr på alle våre klasser og klassearv for Pac-Man, kan du bruke et klassediagram for å se hvordan alt er relatert.
Arv er svært nyttig for å skape mer vedlikeholdsbar kode fordi den tillater oss å lage lignende objekter uten å duplisere koden mellom dem. Det bidrar også til å skape organisert kode ved å vise klasselierarki.
Og det er det! Vi er nå ferdig med OOP-serien her på Gamedevtuts +. Jeg håper du har hatt glede av disse artiklene, og at de har hjulpet deg til å bedre forstå hvordan OOP-prinsipper kan brukes til spillutvikling. Husk å følge oss på Twitter, Facebook eller Google+ for å holde deg oppdatert med de siste innleggene.