Hoe om Inskrywingswette in Jou Spel te Implementeer en te Gebruik
'N Spel word gewoonlik gemaak van verskeie verskillende entiteite wat met mekaar kommunikeer. Hierdie interaksies is geneig om baie dinamies en sterk geassosieer te wees met die spel. Hierdie handleiding dek die konsep en implementering van boodskapwyse stelsels wat entiteitinteraksies kan verenig, sodat jou kode hanteerbaar en hanteerbaar kan word, aangesien dit in kompleksiteit ontwikkel.
'N Bom kan met karakters reageer deur op te blaas en skade te veroorsaak, mediese kits kan 'n entiteit genees, slotte kan deure oopmaak, ensovoorts. In game interaksies is eindeloos, maar hoe kan ons speletjiekode hanteerbaar hou terwyl al die interaksies hanteer word? Hoe maak ons ​​seker dat die kode kan verander en voortgaan om te werk wanneer nuwe en onverwagte interaksies verskyn?
Interaksies in die spel is geneig om baie vinnig in kompleksiteit te groei.
Wanneer die interaksie bygevoeg word (veral die onverwagte), sal jou kode meer en meer lyk. 'N Naïef aansoek sal jou vinnig vra om vrae soos:
"Dit is entiteit A, so ek moet die skade metode skade () daarop aanspreek, of? Is dit skadeByItem ()? Miskien is hierdie metode van skadeByWeapon () korrek?"
Stel jou voor die slegte gemors wat versprei na al jou spel entiteite, omdat hulle almal op verskillende en vreemde maniere met mekaar kommunikeer. Gelukkig is daar 'n beter, eenvoudiger en meer hanteerbare manier om dit te doen.
Voer die boodskap queue. Die basiese idee agter hierdie konsep is om alle spelinteraksie as 'n kommunikasiestelsel toe te pas (wat vandag nog in gebruik is): die uitruil van boodskappe. Mense kommunikeer deur middel van boodskappe letters) vir eeue, want dit is 'n effektiewe en eenvoudige stelsel.
In ons werklike posdiens kan die inhoud van elke boodskap anders wees, maar die manier waarop hulle fisies gestuur en ontvang word, bly dieselfde. Die sender stuur die inligting in die koevert en sy adres na die bestemming. Doelwitte kan antwoord (of nie) deur dieselfde meganisme te volg, net om die "van/na" veld op die koevert te verander.
Interaksies wat gemaak is deur gebruik te maak van 'n boodskap wachtrij stelsel.
Deur die idee op jou spel toe te pas, kan alle interaksies tussen entiteite as boodskappe beskou word. As 'n spel entiteit wil omgaan met 'n ander (of 'n groep van hulle), al wat jou hoef te doen is 'n boodskap te stuur. Doelstellings sal hanteer of reageer op boodskappe gebaseer op hul inhoud en wie die sender is.
In hierdie benadering word kommunikasie tussen spelentiteite 'n eenheid. Alle entiteite kan boodskappe stuur en ontvang. Maak nie saak hoe kompleks of vreemd die interaksie of boodskap is nie, die kommunikasiekanale bly altyd dieselfde.
In die volgende afdeling, sal ek verduidelik hoe jou hierdie boodskap wachtrijbenadering in jou spel kan toepas.
Ontwerp van 'n Koevert (Boodskap)
Kom ons begin met die ontwerp van die koevert, wat die mees basiese element in die boodskapkousstelsel is.
'N Omhulsel kan geteken word soos in die foto hieronder:
Struktuur van 'n Boodskap.
Die eerste twee velde (sender en bestemming) is verwysings na geskep instansies en entiteite wat onderskeidelik hierdie boodskap ontvang. Deur hierdie velde te gebruik, kan die sender en ontvanger weet waar die boodskap gestuur word en waar dit vandaan kom.
Twee ander velde (tipes en data) werk saam om te verseker dat boodskappe korrek hanteer word. Die tipe kolom beskryf waaroor hierdie boodskap handel. As die tipe byvoorbeeld "skade" is, sal die ontvanger hierdie boodskap hanteer as 'n bevel om sy gesondheidspunte te verminder; As die tipe "nastreef", sal die ontvanger dit beskou as 'n opdrag om iets te volg - en so aan.
Die data veld verbind direk met die tipe kolom. Ontmoet vordering vorigeeld, soos die boodskaptipe "skade", sal die data veld 'n nommer bevat - sê, 10 - wat die hoeveelheid skade wat die ontvanger moet toepas op die gesondheidspunte beskryf. As die boodskapstype "nastreef", sal die data 'n voorwerp bevat waarin die teiken verduidelik word wat nagestreef moet word.
Die data veld kan enige inligting bevat, wat die koevert 'n veelsydige kommunikasiemiddel maak. Enigiets kan in die veld geplaas word: heelgetalle, boeie, snare en selfs ander voorwerpe. Die basiese reël is dat die ontvanger moet weet wat in die data veld is, gebaseer op wat in die tipe veld is.
Al die teorie kan vertaal word in 'n baie eenvoudige klas genaamd Boodskap. Dit bevat vier eienskappe, een vir elke veld:
Byvoorbeeld, dit word gebruik, indien entiteit A wil stuur "skade" boodskap aan entiteit B, al wat hy moet doen is om 'n voorwerp uit die klas te modelleer Skade, stel die eiendom to na B, stel die eiendom van na homself (entiteit A), stel die tipe na "skade" en stel die data uiteindelik tot 'n sekere getal (10, byvoorbeeld):
Noudat ons 'n manier het om 'n boodskap te skep, is dit tyd om te dink aan die klas wat dit sal stoor en aflewer.
Implementeer 'n Waglys
Die klas wat verantwoordelik is vir die stoor en aflewering van die boodskappe sal genoem word MessageQueue. Dit sal as poskantoor werk: alle boodskappe word aan hierdie klas oorhandig, wat verseker dat hulle na hul bestemming gestuur sal word.
Vir nou sal, die MessageQueuem klas 'n baie eenvoudige struktuur hê:
Eeiendom boodskap is skikking. Dit sal al die boodskappe stoor wat deur MessageQueue gestuur sal word. Die metode voeg () aanvaar voorwerpe uit die Boodskap klas as 'n parameter, en voeg daardie voorwerp by die boodskaplys.
Hier is hoe ons vorige voorbeeld van entiteit A boodskappe entiteit B oor skade sou werk met die MessageQueue klas:
Ons het nou 'n manier om boodskappe in 'n tou te skep en op te slaan. Dis tyd dat hulle hul bestemming bereik.
Om die MessageQueue klas daadwerklik 'n boodskap te stuur, moet ons eers bepaal hoe die entiteit die boodskap sal hanteer en ontvang. Die maklikste manier is om 'n metode te voeg met die naam onMessage () aan enige entiteit wat boodskappe kan ontvang:
Die MessageQueue klas sal die onMessage () metode van elke entiteit wat die boodskap moet ontvang bel. Die parameters wat aan die metode oorgedra word is boodskappe wat deur die tou stelsel gestuur word (en aanvaar deur bestemming).
Die MessageQueue klas sal 'n boodskap in sy tou gelyktydig in die aflewering() stuur:
Hierdie metode herhaal alle boodskappe in die tou en vir elke boodskap, veld om gebruik te word om 'n verwysing na die ontvanger te kry. Die onMessage() metode van die ontvanger word dan aangeskakel, met die huidige boodskap as 'n parameter, en die gelewer boodskap word dan uit die MessageQueue lys verwyder. Hierdie proses word herhaal totdat alle boodskappe gestuur word.
Die gebruik van Boodskap Queuing
Dit is tyd om al die besonderhede van hierdie implementering saam te sien. Kom ons gebruik ons ​​boodskapwinkelstelsel in 'n baie eenvoudige demo wat bestaan ​​uit verskeie mobiele entiteite wat met mekaar kommunikeer. Ter wille van eenvoud sal ons met drie entiteite werk: Geneser, Hardloper en Jagter.
Die Runner het 'n gesondheidsbalk en beweeg lukraak. Healer sal genees Runner wat verbyloop; daarbenewens die Hunter sal skade in die omgewing veroorsaak Runner. Alle interaksies sal hanteer word deur gebruik te maak van die boodskapkoeistelsel.
Voeg Boodskap wagwoord by
Kom ons begin deur die PlayState te skep wat 'n lys van entiteite (genesers, hardlopers en jagters) bevat en 'n voorbeeld van die MessageQueue klas:
In die speletjie-lus, verteenwoordig deur die update() metode, word die metode van die wagwoord se aflewering() gestuur, sodat alle boodskappe aan die einde van elke spelraam gelewer word.
Voeg die Runner
Die Runner klas het die volgende struktuur:
Die belangrikste deel is die onMessage() metode, wat deur die boodskapwachtrij genoem word wanneer daar 'n nuwe boodskap vir hierdie geval is. Soos vroeër verduidelik, word die tipe veld in die boodskap gebruik om te besluit wat hierdie kommunikasie is.
Gebaseer op die boodskaptipe, word die korrekte aksie geneem: as die boodskaptipe "wanfunksie" is, verminder gesondheidspunte; As die boodskap type "herstel", verhoog gesondheid punte. Die aantal gesondheidspunte wat verhoog of verminder word, word deur die sender in die data veld van die boodskap gedefinieer.
In die PlayState, voeg ons 'n paar hardlopers by die lys van entiteite:
Die gevolg is dat vier hardlopers willekeurig beweeg:
Voeg die Hunter
Die Hunter klas het die volgende struktuur:
Die jagters sal ook beweeg, maar dit sal skade aan al die naaste hardlopers veroorsaak. Hierdie gedrag word geïmplementeer in die update() metode, waar alle speletjie entiteite gekontroleer word en hardlopers boodskappe oor die skade sal stuur.
Die skadeboodskap word soos volg geskep:
Die boodskap bevat inligting oor die bestemming (die entiteit, in hierdie geval, wat die entiteit geanaliseer is in die huidige iterasie), die sender (dit, verteenwoordig die aanvallende jagter), die boodskap tipe ("skade") en die hoeveelheid skade (2, dit is toegeskryf aan die boodskap data veld).
Die boodskap word dan na die bestemming gestuur via die opdrag this.getMessageQueue(). Voeg (msg), wat die nuutgeskepte boodskap by die boodskapwachtrij voeg.
Ten slotte voeg ons die Hunter by die lys van entiteite in die PlayState:
Die gevolg is dat sommige hardlopers rondbeweeg, boodskappe van jagters ontvang terwyl hulle mekaar nader:
Ek het 'n vlieënde koevert bygevoeg as 'n visuele hulpmiddel om te help wys wat aangaan.
Voeg die Healer
Die Healer klas het die volgende struktuur:
Die kode en sy struktuur is baie soortgelyk aan die Hunter klas, behalwe vir sommige verskille. Soortgelyk aan die jagter se aansoek, die iteration update() metode om die lys van in game entiteite op te gradeer, stuur boodskappe aan alle entiteite binne sy genesingsreeks:
Die boodskap het ook 'n bestemming (entiteit), 'n sender (dit, is die geneser wat die aksie uitvoer), 'n boodskaptipe ("genees") en die aantal genesingspunte (2 toegeken in die data veld van die boodskap) .
Ons het bygevoeg Healer na die lys van innerlike entiteite Playstate net soos ons gedoen het Hunter en die resultaat is 'n toneel met hardlopers, jagters en genesers:
En dis dit! Ons het drie verskillende entiteite wat met mekaar kommunikeer deur boodskappe uit te ruil.
Bespreking Oor Buigsaamheid
Hierdie boodskap wachtrij stelsel is 'n veelsydige manier om in-game interaksies te bestuur. Interaksie word gedoen deur 'n geïntegreerde kommunikasiekanaal en het 'n enkele koppelvlak wat maklik om te gebruik en implementeer.
Aangesien jou spel in kompleksiteit groei, kan nuwe interaksies nodig wees. Sommige van hulle kan heeltemal onverwags wees, so jou sal kode moet aanpas om dit te hanteer. As jou 'n boodskaptoewysstelsel gebruik, is dit nodig om iewers nuwe boodskappe by te voeg en elders te hanteer.
Verbeel jou byvoorbeeld dat jou wil skep Hunter hang uit met die Healer; jou moet net maak die Hunter boodskappe met nuwe interaksies te stuur - byvoorbeeld, "flee"-en verseker dat die Healer kan dit in onMessage metode hanteer:
Hoekom nie Net Boodskappe Direk Stuur nie?
Terwyl die uitruil van boodskappe tussen entiteite nuttig kan wees, kan jy wonder hoekom MessageQueue tog nodig is. Kan jy nie net die ontvanger metode opMessage() noem in plaas daarvan om op MessageQueue te staatmaak, soos in die kode hieronder nie?
Jou kan sekerlik so 'n boodskapstelsel implementeer, maar die gebruik van MessageQueue het verskeie voordele.
Byvoorbeeld, deur sentrale boodskappe te sentreer, kan jou 'n paar koel kenmerke soos vertraagde boodskappe, die vermoë om boodskappe aan entiteitgroepe te stuur en visuele ontfoutingsinligting (soos die vlieënde koeverte wat in hierdie handleiding gebruik word) gebruik.
Daar is ruimte vir kreatiwiteit in die MessageQueue klas, tot jou en jou spelbehoeftes.
Hantering van interaksies tussen spelentiteite wat die boodskaptoewysstelsel gebruik, is 'n manier om jou kode georganiseer en gereed te hou vir die toekoms. Nuwe interaksies kan maklik en vinnig bygevoeg word, selfs jou mees komplekse idees, solank dit as boodskappe opgesom word.
Soos bespreek in die handleiding, kan u die gebruik van sentrale boodskaptoewys ignoreer en slegs boodskappe direk aan entiteite stuur. U kan ook kommunikasie sentraliseer deur gebruik te maak van die stuur (MessageQueue klas in ons geval) om in die toekoms plek te maak vir nuwe funksies, soos hangende boodskappe.
Ek hoop jou vind hierdie benadering nuttig en het dit bygevoeg aan jou spelontwikkelaar se spelgordel. Hierdie metode kan lyk as 'n oormaat vir klein projekte, maar dit sal sekerlik jou hoofpyn op die lang duur vir groter speletjies red.