Stagerapport Onderzoek naar en ontwikkeling van een 2D webgame: PHL Adventure
Auteur: Steven Houben Datum: 16 juni 2008, Hasselt Instelling: Provinciale Hogeschool Limburg Stagebedrijf: Peyote / Onderzoeksinstituut voor Toegepaste Informatica (tinfo) Stagelector: Jan Willekens Stagementor: Frank Vangeirt
VOORWOORD Sinds 2 jaar ligt mijn persoonlijke interesse binnen de informatica op het vlak van visualisatie en simulatie en vooral op het onderzoek daar rond. Als student aan de PHL ben ik aanvankelijk vrij weinig in contact gekomen met deze technologieën omdat de opleiding vooral gericht is op bedrijfsapplicaties en in mindere mate op deze andere technologieën. Via de open source communities ben ik wel in contact gekomen met deze aspecten van de informatica. Als eerste experiment heb ik een game engine ontwikkeld op het .Net framework op basis van GDI+.1 Ik was dan ook enthousiast toen ik vernam dat er een mogelijkheid was om onderzoek te doen naar deze technologieën in zowel het project als tijdens de stage. Ondanks het feit dat ik weinig ervaring had met webbased games leek het me een mooie uitdaging om dit project tot een goed einde te brengen.
1
GDI+ (Graphics Device Interface): Eén van de 3 core componenten van Windows, gebruikt voor visuele rendering.
INHOUDSTABEL
1
INLEIDING ..................................................................................................................... 11
1.1
Bedrijfsvoorstelling ................................................................................................................................. 12
1.2
Concept fase ............................................................................................................................................. 13
1.3
Project fase............................................................................................................................................... 14
2
FLASH PLAYER 9 & ACTIONSCRIPT 3 .................................................................. 16
2.1
Flash cs3 ................................................................................................................................................... 16
2.2
Actionscript 3 ........................................................................................................................................... 17
2.3
Hiërarchie ................................................................................................................................................ 19
3
2D ISOMETRIC MAP SCROLLING TILE BASED GAME ENGINE .................... 21
3.1
tweedimensionaal (2D) ............................................................................................................................ 21
3.2
Map scrolling ........................................................................................................................................... 23
3.3
Tile based ................................................................................................................................................. 24
3.4
Game (computerspel) .............................................................................................................................. 25
3.5
Engine ....................................................................................................................................................... 25
4
FLASH GAME ENGINE ................................................................................................ 26
4.1 Core .......................................................................................................................................................... 26 4.1.1 Collections ........................................................................................................................................ 26 4.1.2 Components....................................................................................................................................... 28 4.1.3 Data ................................................................................................................................................... 28 4.1.4 IO ...................................................................................................................................................... 28 4.1.5 Math .................................................................................................................................................. 29 4.1.6 Objects .............................................................................................................................................. 30 4.1.7 Physics .............................................................................................................................................. 30 4.1.8 Rendering .......................................................................................................................................... 30 4.1.9 Sound ................................................................................................................................................ 32 4.2
Global ....................................................................................................................................................... 32
4.3 UI (user interface) ................................................................................................................................... 33 4.3.1 menu .................................................................................................................................................. 33 4.3.2 Components....................................................................................................................................... 35
4.4 Game ........................................................................................................................................................ 37 4.4.1 Collections ........................................................................................................................................ 37 4.4.2 Data ................................................................................................................................................... 37 4.4.3 Gameplay .......................................................................................................................................... 38 4.4.4 IO (input/output ................................................................................................................................. 42 4.4.5 Objects .............................................................................................................................................. 43
5 5.1
PHL ADVENTURE GAME ........................................................................................... 46 Preload ..................................................................................................................................................... 46
5.2 Spel ........................................................................................................................................................... 48 5.2.1 Declaratie en initialisatie ................................................................................................................... 48 5.2.2 Draw call ........................................................................................................................................... 50 5.2.3 Interactie en gameplay ...................................................................................................................... 53 5.3
Resources ................................................................................................................................................. 60
5.4
Toolkit ...................................................................................................................................................... 61
5.5
Activiteiten ............................................................................................................................................... 62
6
CONCLUSSIE EN AANBEVELINGEN ...................................................................... 63
7
BESLUIT .......................................................................................................................... 64
REFERENTIES ...................................................................................................................... 65 BIJLAGEN ............................................................................................................................. 66 Bijlage 1................................................................................................................................................................ 67 Bijlage 2................................................................................................................................................................ 69 Bijlage 3................................................................................................................................................................ 71 Bijlage 4................................................................................................................................................................ 73 Bijlage 5................................................................................................................................................................ 75 Bijlage 6................................................................................................................................................................ 77 Bijlage 7................................................................................................................................................................ 78
FIGUREN
Figuur 1: Schermafdruk van de Flash IDE .............................................................................. 16 Figuur 2: Schematische voorstelling van de werking van de Flash compiler. Actionscript klassen worden aan een flash designer object gekoppeld en zo via de flash IDE gecompileerd tot een uitvoerbaar shockwave object. ........................................................ 19 Figuur 3: Hiërarchie van de standaard ingebouwde display klasse. De tob level klasse is het object. Dit object is de superklasse van alle andere klassen in Actionscript 3. ................ 19 Figuur 4: Schematische voorstelling van het OOP model. Dit model toont aan hoe de onderlinge hiërarchie in het OOP model werkt. Wanneer een bovenliggend klasse een onderliggend klasse wil aanspreken kan dit via de methoden en eigenschappen van die klasse. Een onderliggende klasse die de bovenliggende klasse wil aanspreken moet gebruik maken van het DOM event model. ........................................................................ 20 Figuur 5: Tweedimensionale vorm .......................................................................................... 21 Figuur 6: Voorstelling van een axonometrische projectie waarbij alle hoeken tussen de geprojecteerde assen 120° zijn. ......................................................................................... 21 Figuur 7: Transpositie van tweedimensionale projectie naar een isometrische projectie. ..... 22 Figuur 8: Theoretische isometrische transitie. Door de gestandaardiseerde isometrische formules toe te passen op lineaire tweedimensionale x- en y-waarden verplaatsen de assen zich naar een isometrische projectie. ...................................................................... 23 Figuur 9: Schematische voorstelling van lineaire beweging. De blauwe pijl duidt een mogelijke beweging aan van de speler. De speler kan dus vrij bewegen in alle richtingen binnen het zichtbare scherm. ............................................................................................. 23 Figuur 10: Schematische voorstelling van lineaire beweging door middel van mapbeweging. De groene pijlen duiden de gecentraliseerde positie van de speler aan. Wanneer de speler naar rechts beweegt wordt de viewport geüpdate in dezelfde richting als de speler. De map zelf beweegt echter in de tegenovergestelde richting. Hierdoor wordt de illusie van beweging gecreëerd. .......................................................................................................... 24 Figuur 11: Schematische voorstelling van de architectuur van de engine. De engine en het spel bestaat ui 4 belangrijke packages die elke een specifiek functie hebben. De resources is een verzameling van alle data noodzakelijk voor het functioneren van het spel en de engine................................................................................................................................. 26 Figuur 12: De constructor van de GenericCollection klasse. In de constructor wordt een required type meegestuurd. Dit type vormt de basis van de runtime type check. ............. 27 Figuur 13: Runtime type checking in de GenericCollection klasse. Voor een object toegevoegd wordt aan de collectie controleert de functie eerst het type van het object. .. 27 Figuur 14: De drawing klasse. Deze klasse implementeert 4 synchrone................................. 31 Figuur 15: Implementatie van een klasse op basis van de drawing klasse. Deze klasse overschrijft 1 call en tekent vervolgens een object door de _draw methode van de super klasse op te roepen. ........................................................................................................... 31 Figuur 16: Voorbeeld van de werking van de statische BitmapCache klasse. Deze klasseis een statische verzameling van textures. ................................................................................... 32 Figuur 17: Voorbeeld van een statische klasse: de ItemType klasse. ...................................... 33
Figuur 18: Schermafdruk van het menu. .................................................................................. 33 Figuur 19: Schermafdruk van het selectiemenu. ...................................................................... 34 Figuur 20: Schermafdruk van het frame .................................................................................. 34 Figuur 21: Schermafdruk van de mp3 speler. .......................................................................... 35 Figuur 22: Spectrum functie. Deze functie visualiseert een geluidsbestand. ........................... 35 Figuur 23: Schematische voorstelling van de werking van de inventory................................. 36 Figuur 24: Schermafdruk van het messageframe. ................................................................... 36 Figuur 25: AddTile methode van de tileset klasse. .................................................................. 37 Figuur 26: Schematische voorstelling van de datastructuur van de engine. De php klassen maken via een default gateway een verbinding met de AMFPHP engine die op zijn beurt de verbinding met de mysql databank tot stand brengt via ingebouwd php klassen. ........ 38 Figuur 27: Intersectie tussen 2 objecten. ................................................................................. 38 Figuur 28: Schematische voorstelling van het collision detection model. In dit geval kan de speler enkel naar boven, naar links of naar onder bewegen. ............................................ 39 Figuur 29: Eigenschappen van de entity klasse. In deze eigenschappen worden de matrixwaarden van de aanliggende tiles bijgehouden. ..................................................... 39 Figuur 30: Schematische voorstelling van de diepteverwerking bij een beweging naar rechts. ........................................................................................................................................... 40 Figuur 31: Schematisch voorstelling van de displaylist. De displaylist kan enkel displayobjecten bevatten en de indices dienen opeenvo
Figuur 46: Keyboard event handler. De handler vangt het event op en ontleed het eventobject. Op basis van filtering kent de handler een specifieke actie toe. ........................................ 55 Figuur 47: Schematische voorstelling van de werking van het DTS systeem. Dit systeem laat toe om enkel de één rij of kolom tiles te verwijderen en één rij of kolom tiles bij te tekenen. .............................................................................................................................. 57 Figuur 48: Een onderdeel van de move() functie. Op basis van de richting berekent deze functie de verplaatsing van het object, de map en de viewport. ........................................ 57 Figuur 49: De processItem() functie controleert het gevonden object en koppelt hieraan een actie. .................................................................................................................................. 58 Figuur 50: Een deel van de doMission() functie. Deze functie regelt welk missie met welk objectief aangemaakt moet worden. .................................................................................. 60 Figuur 51: Schermafdruk van de map editor. .......................................................................... 61 Figuur 52: Schermafdruk van de mission editor. ..................................................................... 62
TABELLEN
Tabel 1: Onderzoek naar de verschillen tussen de mogelijke programmeeromgevingen. ....... 14 Tabel 2 : Language karakteristieken van Actionscript3 (Grossman,Huang 2006). ................ 18 Tabel 3: Standaard isometrische formules............................................................................... 22 Tabel 4: Matrix vs Tilemap. ..................................................................................................... 25 Tabel 5: Structuur van een map bestand. ................................................................................. 28 Tabel 6: Structuur van een texturelist bestand......................................................................... 28 Tabel 7: Isometrische formules waarbij geen rekening wordt gehouden met de grootte van een tile. ..................................................................................................................................... 29 Tabel 8: Voorbeeld van de werking van de stringsearch klasse De maxtrixwaarde wordt opgedeeld in 3 afzonderlijk waarden................................................................................. 30 Tabel 9: Formules die de viewport berekenen. ........................................................................ 51 Tabel 10: Voorbeeld van een berekening van één viewport punt. ........................................... 51 Tabel 11: Formules voor de berekening van de viewport offset. ............................................. 51
GRAFIEKEN
Grafiek 1: Frames per second bij de aanwezigheid en afwezigheid van een realtime minimap. ........................................................................................................................................... 44
1
INLEIDING
In een industrie waar jaarlijks honderden nieuwe geavanceerde 3D games verschijnen, zien we de laatste jaren een opmerkelijke trend. Steeds meer bedrijven bieden via een website spelletjes aan, onder de web 2.0 noemer, die in een webbrowser gespeeld kunnen worden. Jaarlijks lokken deze websites miljoenen spelers van alle leeftijden. Door de lage drempel, door de eenvoudige gameplay 2 en door de platformonafhankelijkheid 3 zijn deze spelletjes enorm populair bij gebruikers die vroeger geen interesse in games vertoonden. Deze spelletjes zijn vaak gratis doordat ze omgeven zijn door reclame en advertenties voor bedrijven of diensten. Ook de introductie van de mobiele telefoon (GSM) biedt een nieuw platform aan om spelletjes op te draaien. Deze spelletjes vertonen veel gelijkenissen met de spelletjes die aangeboden worden via de webbrowser en zijn meestal in dezelfde taal geprogrammeerd (Java/Flash/...). Verschillende grote game studio‟s spelen in op deze nieuwe markt. Zo biedt Electronic Arts verschillende games aan die via de webbrowser kunnen gedownload worden en speelbaar zijn op de mobiele telefoon, PDA of webbrowser. Zelfs ID software heeft aangekondigd hun legendarisch game QUAKE III ARENA te poorten en gratis aan te bieden via webbrowser onder de naam Quake Zero (Carmack, 2007). Deze spelletjes zijn vaak eenvoudig van aard en gebaseerd op of zelfs een kloon van spelletjes uit de jaren ‟90. De teken-, reken- en geheugentechnieken die op deze nieuwe platforms gebruikt worden, zijn identiek aan de technieken die tien jaar geleden beschikbaar waren voor de computer. Bovendien is de stijgende trend dat steeds meer bedrijven vragende partij zijn om webapplicaties te gaan visualiseren, om op deze manier hun klanten een verhoogde interactiviteit aan te kunnen bieden (Patch, 2006). Klanten gaan via sterk visuele applicaties veel sneller en veel gebruiksvriendelijker data en informatie op maat krijgen. Ook verlopen klassieke onderzoeksmethoden, zoals bijvoorbeeld een enquête, via visualisatie efficiënter en aangenamer. Game ontwikkeling is een tak in de informaticawereld die in België helaas nog veel te weinig aan bod komt. Maar de laatste jaren kunnen we een positieve evolutie betreffende game ontwikkeling vaststellen. Meer en meer bedrijven gaan zich verdiepen in visualisatie- en simulatietechnieken maar ook de overheid speelt in op dit nieuwe concept. Het Onderzoeksinstituut voor Toegepaste Informatica(TINFO) dat verbonden is met de PHL is in deze context samen met het bedrijf Peyote een onderzoeksproject gestart naar de ontwikkeling van een webgame. Gedurende de stageperiode hebben 3 collega‟s en ikzelf dit project verder uitgewerkt tot een werkend prototype. Wij hebben dan ook tijdens de stageperiode het volledige vertrouwen maar ook de verantwoordelijkheid gekregen van onze stagebegeleider Frank Vangeirt om dit project zelfstandig uit te werken. In dit stagerapport ga ik trachten de verschillende aspecten van dit onderzoeksproject te doorlopen en een structureel beeld te geven van werking van het prototype van de PHL Webgame.
2 3
Gameplay: De manier waarop het spel reageert of de manier waarop het spel gespeeld wordt. Platformonafhankelijk: Een toepassing die op alle besturingssystemen gebruikt kan worden. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
11
1.1
BEDRIJFSVOORSTELLING
Het Onderzoeksinstituut voor Toegepaste Informatica(TINFO) is verbonden aan de opleiding Toegepaste Informatica (TIN) van het departement Handelswetenschappen en Bedrijfskunde van de Provinciale Hogeschool Limburg (PHL). Het instituut werd opgestart in 2005 met Marcel Gaens als eerste onderzoekscoördinator. In oktober 2007 werd Marcel Gaens opgevolgd door Frank Van Geirt. TINFO is actief op het gebied van toegepast onderzoek en dienstverlening in het domein van Information Communication Technology (ICT). Binnen deze ICT-sector wordt gewerkt in verschillende onderzoeksdomeinen. Voor elk van de onderzoeksdomeinen legt TINFO zich toe op projectmatig en toegepast onderzoekswerk in samenwerking met partners uit de openbare en private sector. Als onderzoeksinstituut willen we bovendien een substantiële bijdrage leveren aan het creëren van een breed maatschappelijk draagvlak voor ICT integratie in alle facetten van het dagdagelijkse leven. Als onderzoeksinstituut is het ons doel om de specifieke ICT-problemen van bedrijven op te lossen via beschikbare applicaties. Pas wanneer de op de markt beschikbare applicaties niet voldoen aan de eisen, wordt een ontwikkeltraject opgestart. In het speerpunt „Netwerken en mobiele communicatie‟ wordt dan ook onderzoek en dienstverlening verricht rond mobiele applicaties voor laptops, PDA, smartphone, sensoren, RFID, e.d. Binnen dit speerpunt wordt voornamelijk samengewerkt met het onderzoeksinstituut ArcK van het departement Architectuur, Interieurarchitectuur en Beeldende Kunst. De verschillende onderzoeksprojecten situeren zich binnen het kader van game engines, classificatie van games en de ontwikkeling van games en simulaties. Het gebruik van (databank gestuurde) webapplicaties zit in stijgende lijn. Meer en meer klassieke desktop applicaties vinden hun tegenhanger op het internet. In dit domein heeft het onderzoeksinstituut al heel wat kennis en expertise opgedaan. Verder wordt binnen dit speerpunt onderzoek uitgevoerd naar nieuwe technieken die op het internet kunnen toegepast worden, onder de noemer web3d. Peyote is een studio die gespecialiseerd is in 3D computeranimatie en – visualisatie. De studio werd in 2000 opgericht door David Molenberghs en was toen gehuisvest in de Brusselse Dansaertwijk. Er wordt vooral karakteranimatie en 3D content gemaakt voor film en tv. Een hoogtepunt was de restyling van TV1 (nu één) waarvoor Peyote enkele idents aanleverde. In 2004 verhuisde Peyote naar Hasselt en werd er begonnen aan de 18 maanden durende productie van iMagic, een virtuele trainingssimulator voor wielrenners. Hiervoor werden 3 medewerkers in dienst genomen, die na het project weer zullen afvloeien. Nieuwe contacten zorgen ervoor dat er meer en meer opdrachten ontstaan voor visualisaties rond animaties. In de toekomst wil Peyote zich specialiseren in realistische, industriële visualisaties. Ondertussen wordt David Molenberghs gevraagd om een gastcollege “3D modeling” te geven aan de technische hogeschool GroepT te Leuven. Hier raakt hij betrokken bij projecten betreffende interactiviteit en simulatie. Dit stimuleert hem om nieuwe grafische en technische grenzen te verkennen in het vakgebied 3D. Momenteel start Peyote samen met de onderzoekscel TINFO van de PHL een onderzoek betreffende 3D op het internet.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
12
1.2 CONCEPT FASE Een computerspel en de ontwikkeling ervan wordt in grote mate bepaald door het concept. Dit concept moet een omschrijving zijn van de grafische mogelijkheden, de gameplay, de User interfaces, ... kortom, alles wat betrekking heeft op hoe het spel eruit ziet en hoe het spel gespeeld wordt. Het ontwerpen van dit concept was een departementsoverschrijdende samenwerking tussen studenten van het Departement Beeldende Kunst en studenten van het Departement Handelswetenschappen. Studenten van verschillende afstudeerrichtingen van de twee departementen werden in kleine groepjes opgedeeld met als opdracht elk een eigen concept te bedenken. Er werden wekelijkse vergaderingen gehouden waarin besproken werd hoe het spel er zou kunnen uitzien. Al snel werd de grote kloof tussen de twee departementen duidelijk. Enerzijds hadden de studenten van het Departement Beeldende Kunst goede ideeën die in de praktijk niet haalbaar waren. Anderzijds hadden de studenten van het Departement Handelswetenschappen er een minimalistische kijk op. Deze contrasten zorgden voor de ideale combinatie tussen creativiteit enerzijds en haalbaarheid anderzijds. Uiteindelijk mocht elke groep een presentatie geven waarin de groep hun concept mocht verdedigen voor een jury. Deze jury besliste dan welk concept uiteindelijk gebruikt werd voor het spel. Na keuze van één concept, werd deze door de jury verder aangevuld met suggesties en ideeën. Het gekozen concept diende vervolgens als basis voor het draaiboek waarop het spel gebaseerd zou worden. Een draaiboek is een verzameling van alle zaken die in het spel verwerkt moeten worden. Het draaiboek van dit spel is initieel gestart door de studenten van beeldende kunst en later werd het verder uitgewerkt door Mr.Van Geirt. (bijlage 7) Het verhaal achter het concept is dat onze school bekend staat tot in de ruimte voor zijn intelligente leerlingen. Op een dag dient een buitenaards wezen zich aan om op de PHL te studeren. Hij moet hiervoor eerst een toelatingsproef afleggen. Vooraleer hij hieraan kan beginnen, moet hij informatie verzamelen over de verschillende departementen en afstudeerrichtingen (Van Geirt, 2008). Het idee voor een webgame is eigenlijk voortgevloeid uit de vraag hoe de PHL afstuderende studenten uit het secundaire onderwijs kan bevragen en motiveren om te studeren aan de PHL. Studenten die nog op zoek zijn naar een school om hun hogere studies te doen kunnen via deze webgame op een interactieve en gevisualiseerde manier de campus en de studierichtingen verkennen. Het spel leidt de studenten door een geabstraheerde voorstelling van de campus. Door middel van opdrachten kan de student de verschillende studierichtingen verkennen en zo interactief ontdekken waar zijn interesses nu precies liggen. Elke opdracht is een minigame dat een representatie is van één specifieke studierichting. Elke oplossing van een minigame is dan ook uniek en vraagt dan ook andere werk- en benaderingsmethoden. Na het spelen van deze webgame zou de student enerzijds moeten weten welke studierichtingen de PHL nu precies aanbiedt en anderzijds waar zijn persoonlijke interesses nu precies liggen.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
13
1.3
PROJECT FASE
Het onderzoeksproject is reeds gestart in de projectperiode gedurende het 2de trimester. In deze periode zijn verschillende acpecten aan bod gekomen. Allereerst hebben verschillende collega‟s zich gedurende de projectfase bezig gehouden met het opmaken van een analyse. Het grote probleem met deze analyse was dat er nog geen architectuur bestond of uitgedacht was die voor dit onderzoeksproject van toepassing was. Er werd dan ook besloten de analyse te beschouwen als een generische benadering van de uiteindelijke gameplay of met andere woorden een schematisch voorstelling van het draaiboek. De volgende stap in dit proces was het aanmaken van een database op basis van de eerder gemaakte analyse. Er werd gekozen voor een mysql database omgeving daar deze opensource beschikbaar is. Deze database is volledige beheerbaar met een webbased applicatie. De opdracht was duidelijk:”Bouw een platformonafhankelijk modulair spel dat in de browser wordt gespeeld”. Dit betekende in de praktijk dat we op zoek moesten gaan naar een programmeeromgeving die op alle besturingssystemen kan functioneren en in alle webbrowsers speelbaar is. Voor we overgegaan zijn tot het maken van een keuze is er een vergelijkende studie gedaan tussen de verschillende mogelijkheden. De verschillende omgevingen die in aanmerking kwamen zijn met elkaar vergeleken op volgende punten:
Platformonafhankelijkheid Kan de omgeving op alle besturingssystemen worden gebruikt? Browser support Wordt de omgeving door alle browsers ondersteund? Flexibiliteit Is de programmeeromgeving flexibel en snel aan te leren? OOP Voldoet de programmeeromgeving aan de OOP 4 principes Support Is er een actieve community die deze programmeeromgeving ondersteund?
Flash Actionscript Platformonafhankelijk x Browser support x Flexibliteit x OOP x Support x
.Net silverlight / x x x x
Javascript x x / x /
Shockwave x / / / /
Tabel 1: Onderzoek naar de verschillen tussen de mogelijke programmeeromgevingen.
4
OOP (Object Oriented Programming):OOP is een programmeerparadigma dat gebruikt maakt van objecten en de interactie tussen de objecten. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
14
Zoals in tabel 1 aangetoond wordt, is Flash Actionscript 3 de meeste aangewezen omgeving voor dit onderzoeksproject. De omgeving voldoet immers aan volgende aspecten:
Platformonafhankelijkheid Wordt ondersteund door alle besturingssystemen. Browser support Wordt ondersteund door alle webbrowsers. 850 miljoen gebruikers hebben de plug-in al geïnstalleerd en de meeste webbrowsers installeren de plug-in standaard mee. Flexibiliteit Actionscript is een flexibele programmeertaal en is vrij eenvoudig aan te leren. OOP Actionscript 3 is gebaseerd op de ECMA 3 standaarden5. Deze standaard voorziet een OOP model, een DOM Event model 6en een EX4 xml model7. Support Flash Actionscript kent een grote community.
Vooraleer overgegaan kan worden tot het ontwikkelen van een spel is het noodzakelijk over een stabiele engine te beschikken waarop dit spel gebouwd kan worden. Allereerst zijn we begonnen met het zoeken naar een opensource engine die aan onze specificaties voldeed. Helaas hebben we tijdens onze zoektocht geen valabele engine gevonden. Er werd gekeken naar enkele bestaande opensource engines waaronder Sandy 3D, Papervision 3D,The fisix engine en Pixlib. De meeste van deze engines zijn geschreven voor Actionscript 2 en later vertaald naar Actionscript 3. Ze zijn allen zeer ingewikkeld en zijn vooral gericht op visuele rendering 8en in mindere mate op gameplay. Ook zijn ze vooral bedoeld voor 3D omgevingen. Daarom werd beslist een eigen engine te ontwerpen op basis van een zelf uitgedachte architectuur die alle specificaties bezit nodig om het PHL Adventure Game te bouwen. Tijdens de projectperiode is er vooral veel onderzoek gedaan naar het implementeren van theoretische modellen rond 2D games in Actionscript 3. Enkele voorbeelden van deze modellen zijn isometrie (WikiPedia,2007), Tile-based isometrie (PA, 2005), Matrix rekenen (Weeks, 1997), Depth sorting (Lamont, 2007) en Isometrische beweging (Kirupa, 2008). Uiteindelijk werd aan het aan einde van deze periode een prototype van de engine afgeleverd met daarop 3 werkende applicaties:
Prototype van PHL Adventure Game Pacman Logistics
5
ECMA (European Computer Manufacturers Association): Private standaardenorganisatie voor informatie- en communicatiesystemen. 6 DOM(Document Object Model) Event Model: Event driven W3C standaard die een hiërarchische event-based model aanbiedt. 7 E4X (ECMAScript for XML): ECMA extensie die „native‟ xml integreert in ECMA programmeeromgevingen. 8 Renderen: Het berekenen en visualiseren van computer afbeeldingen. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
15
2 FLASH PLAYER 9 & ACTIONSCRIPT 3 Voor dit onderzoeksproject werd specifiek gekozen voor Flash, meerbepaald Flash player 9, in combinatie met Actionscript 3. Als IDE 9 werd gekozen voor Flash CS3. 2.1 FLASH CS3 Adobe Flash CS3 is de laatste versie van de Flash IDE en de enige versie die de ontwikkeling met Actionscript 3 en Flash player 9 ondersteunt. De Flash authoring tool is een IDE waarin men vanuit een grafische user interface (GUI) Flash applicaties kan bouwen (figuur 1).
Figuur 1: Schermafdruk van de Flash IDE
9
IDE (integrated Development Environment): Programma waarin een bepaald programmeeromgeving in gebruikt kan worden. Vaak is een IDE voorzien van een grafische designer, een code editor en een compiler. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
16
2.2
ACTIONSCRIPT 3
Flash Actionscript werd oorspronkelijk in het leven geroepen als ondersteuning van het visuele Flash concept en is door de jaren heen uitgegroeid tot een volwaardige scripttaal. De meeste recente versie, Actionscript 3, wordt uitgevoerd op de nieuwe Actionscript Virtual Machine 10 2 (AVM) die gebouwd werd op de nieuwste Flash Player, versie 9. Deze laatste versie van Actionscript is, net als javascript, gebaseerd op ECMAScript en is bijgevolg volledig object georiënteerd. Actionscript 3 biedt verschillende verbeteringen ten op zichte van Actionscript 2 maar er zijn toch beperkingen ten op zichte van klassieke programmeeromgevingen. De belangrijkste karakteristieken van Actionscript 3 worden in tabel 2 besproken. Run- en compiletime foutmeldingen In tegenstelling tot zijn voorganger, Actionscript 2, ondersteunt Actionscript 3 runtime foutmeldingen. Deze foutmeldingen zijn vergelijkbaar met soortgelijke scripttalen en bieden een vangnet voor verschillende typen foutmeldingen. Runtime types De Flash player onderzoekt in runtime het type van een object waardoor type safety 11 verbeterd wordt. Deze types worden gebruikt om variabelen te representeren op de computer zelf waardoor het geheugenverbruik drastisch gereduceerd wordt. Regulaire expressies en bit operatoren12 Actionscript 3 ondersteunt regulaire expressies volgens de ECMA standaarden alsook het gebruik van bitoperatoren. Namespaces Abstracte container constructie die als wrapper rond bepaalde klassen wordt gebruikt om zo dubbelzinnige namen in de broncode te vermijden. Multiple inheritance Een Actionscript 3 klasse kan zowel overerven van een superklasse als van een interface. Een interface kan niet beschouwd worden als een volwaardige klasse maar als een klassenstructuur. Performance Verbeterde performance door een overervingsysteem dat gebaseerd is op klassen in plaats van prototypes. Packages en namespaces Ondersteunt packages en namespaces. Compiler Compileert tegen een volledig nieuw type bytecode. Event handling Actionscript 3 is volledig Event driven gebaseerd op het DOM event model. Integratie van E4X Actionscript 3 ondersteunt de ECMA E4X xml standaarden voor het verwerken van xml data.
10
Virtual machine: Software dat een hardwareomgeving nabootst. In het geval van Actionscript draait een gecompileerd programma in een virtuele omgeving en dus niet op de machine zelf. 11 Type safe: Een type safe programmeertaal biedt datatypes aan die van een specifiek voorgedefinieerd type zijn en dus niet generisch geïmplementeerd zijn. 12 Bitoperatoren: Operatoren waarmee niet de data maar het aantal bits achter de data wordt gemanipuleerd. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
17
Toegang tot de Flash runtime omgeving Actionscript 3 ondersteunt direct toegang tot de Flash runtime omgeving (bibliotheek) en de display list. Methode overloading ECMAscript 3 ondersteunt geen methode overloading waardoor je enkel de default constructor of methodes met dezelfde functionaliteit maar andere benamingen moet gebruiken. Er is wel de mogelijkheid om optionele parameters mee te geven hoewel dit drastische beperkingen heeft ten opzichte van het overloaden van een methode. Generics ECMAscript 3 ondersteunt geen generics13. Dit kan wel omzeild worden door runtime type checking toe te passen. Abstracte klassen ECMAcript 3 ondersteunt geen abstracte klassen14. Actionscript 3 voorziet dit door interfaces aan te bieden waardoor multiple inheritance wordt nagebootst. In realiteit zijn interfaces niets meer dan voorgedefinieerde klassenstructuren. Het vreemde in deze context is dat verschillende base klassen van Actionscript 3 wel abstract zijn. Het ontbreken van deze structuur is enkel te wijten aan het feit dat Adobe Actionscript 3 de ECMA standaarden volgt. Array De array in Actionscript 3 is niet type safe maar gaat uit van de top-level klasse: het object. Unsafe code Actionscript 3 ondersteunt geen unsafe code15. Garbage Collection De standaard garbage collection16 is vaak traag en moet handmatig geforceerd worden. Tabel 2 : Language karakteristieken van Actionscript3 (Grossman,Huang 2006).
Shockwave Flash (.SWF) is een gedeeltelijk open bestandformaat voor interactieve multimediatoepassing gebaseerd op vectoren, afbeeldingen, audio en video. Een swf bestand is klein genoeg om een applicatie serverside en via de webbrowser aan te bieden maar heeft ook de mogelijkheid om zwaardere applicaties lokaal te draaien. Flash authoring tool bestanden (.FLA) zijn bestanden die het bronmateriaal van de Flash applicaties bijhouden. Actionscript klassen (.as of .actionscript) zijn platte source bestanden die gekoppeld kunnen worden aan een FLA via “embedded code” of via de documentklasse. “Embedded code17” is Actionscript broncode die achter een object op de tijdlijn wordt geplaatst en dus rechtstreeks in het Flash designer bestand zit. De documentklasse kan gebruikt worden om een extern Actionscript bestand te koppelen aan de timeline of stage van een FLA. De Flash 9 compiler compileert Actionscript code vanuit de FLA documentklasse naar bytecode in de vorm van SWF. Deze SWF kan worden afgespeeld in de Actionscript Virtual Machine 2 (AVM). Actionscript kan dus niet direct gecompileerd worden maar moet gekoppeld worden aan een Flash designer bestand. Deze Flash 9 compiler is niet dezelfde compiler als de Flex18 Actionscript compiler (figuur 2). 13
Generics: Stijl van programmeren volgens het type-to-be-specified-later principe. Hierdoor kan de klasse aangepast worden afhankelijk van het nodige datatype. 14 Abstracte klasse: Een klasse die één of meer voorgedefinieerde methoden bevat maar die niet geinitialiseerd kan worden, enkel overgeërfd kan worden. 15 Unsafe code: Broncode die de geheugentoekenning zelf beheert. 16 Garbage Collection: Automatische geheugenbeheer. 17 Embedded code: Broncode die rechtstreeks in een flash object staat. 18 Flex: Een framework gericht op de ontwikkeling van RIA (rich internet application). Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
18
Figuur 2: Schematische voorstelling van de werking van de Flash compiler. Actionscript klassen worden aan een flash designer object gekoppeld en zo via de flash IDE gecompileerd tot een uitvoerbaar shockwave object.
2.3
HIËRARCHIE
Allereerst bekijken we de hiërarchie van de standaard ingebouwde klassen (figuur 3). Deze hiërarchie is erg belangrijk omdat ze ons in staat stelt om generische broncode te schrijven. Object
• Top level
EventDispatcher
• extends Object
DisplayObject
• extends EventDispatcher
InteractiveObject
• extends DisplayObject
DisplayObjectContainer
• extends InteractiveObject
Sprite
• extends DisplayObjectContainer
MovieClip
• extends Sprite
Figuur 3: Hiërarchie van de standaard ingebouwde display klasse. De tob level klasse is het object. Dit object is de superklasse van alle andere klassen in Actionscript 3.
In Actionscript 3 is de object klasse de top-level klasse. Dit wil zeggen dat alle andere klassen deze klasse overerven. De tweede klasse in deze hiërarchie is de EventDispatcher. Actionscript 3 is een scripttaal die volledige gebaseerd is op events en er vanuit gaat dat elk Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
19
object in staat is zelf een event te dispatchen (Loose Coupling) 19 (Weick,1983) wanneer hij iets aan de buitenwereld wil laten weten. Wanneer een klasse zelf niet in staat is om een event te dispatchen is deze klasse afhankelijk van andere klassen om dit in zijn plaats te doen. Dit laatste gaat in tegen de grondregels van geoptimaliseerd OOP. In figuur 4 is deze onderlinge verhouding schematisch voorgesteld. We gaan er vanuit dat klasse 1 een instantie van klasse 2 aanmaakt die op zijn beurt een instantie van klasse 3 aanmaakt. Klasse 1 kan via de eigenschappen en de publieke methode klasse 2 aanspreken. Klasse 2 kan op zijn beurt klasse 3 via dit model aanspreken. Wanneer klasse 2 iets wil laten weten aan klasse 1 (die hoger in de hiërarchie zit) kan hij een event dispatchen. Klasse 1 kan dan beslissen om naar deze event te luisteren. Hetzelfde geldt voor klasse 3. Deze klasse kan een event dispatchen waar zowel klasse 2 maar ook klasse 3 naar kan luisteren. Dit noemt met Event Bubbling (W3C,2000).
Figuur 4: Schematische voorstelling van het OOP model. Dit model toont aan hoe de onderlinge hiërarchie in het OOP model werkt. Wanneer een bovenliggend klasse een onderliggend klasse wil aanspreken kan dit via de methoden en eigenschappen van die klasse. Een onderliggende klasse die de bovenliggende klasse wil aanspreken moet gebruik maken van het DOM event model.
Wanneer we zelf klassen willen definiëren of structuren willen bouwen (engine/processor) dienen we rekening te houden met deze hiërarchie. Een nieuwe klasse zonder superklasse zal automatisch de object klasse als superklasse hebben. Deze klasse is dan niet type-safe en is niet in staat het DOM Event model te volgen en bijgevolg niet conform met de OOP regels.
19
Loose Coupling: Stijl van programmeren waarbij componenten zo veel mogelijk onafhankelijk zijn van elkaar. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
20
3
2D ISOMETRIC MAP SCROLLING TILE BASED GAME ENGINE
Specifiek voor deze opdracht willen wij gebruik maken van een tile-based game engine die in isometrisch perspectief tekent en map scrolling ondersteunt. Na een grondige analyse van bestaande engines in de open source community hebben we vastgesteld dat er geen bestaande engines zijn die van toepassing zijn voor ons project. Hierdoor is het idee en het initiatief ontstaan om zelf een 2D tile engine te schrijven die zowel map scrolling als isometrie ondersteunt. 3.1
TWEEDIMENSIONAAL (2D)
Figuur 5: Tweedimensionale vorm
Met de term 2D of tweedimensionaal doelt men op een object dat slechts 2 meetkundige dimensies heeft, namelijk een lengte en een breedte (figuur 5). Tweedimensionaal kan ook als synoniem voor plat of vlak worden beschouwd daar er nooit een fysische diepte kan zijn. De vorm van een dergelijk object is onbelangrijk voor de tweedimensionaliteit en is onbeperkt in grootte of structuur. Uitgesproken voorbeelden van tweedimensionaliteit zijn een vierkant, een cirkel en een driehoek.
Toch kan dieptezicht aanwezig zijn door een driedimensionaal zicht te suggereren. Dit noemt men isometrische projectie. Isometrische projectie is een vorm van grafische projectie, meer bepaald een vorm van axonometrische projectie. Het is een manier om ruimtelijke figuren in een plat vlak weer te geven. Bij deze methode lijkt het of je schuin van boven en 45° van de zijkant tegen het te projecteren object aan kijkt. Er wordt hierbij geen gebruik gemaakt van perspectief, wat betekent dat lijnen die in de ruimte parallel lopen, op de projectie ook parallel zullen lopen. Bij een Isometrische projectie is de hoek tussen de drie geprojecteerde assen altijd 120° (figuur 6). Dit heeft tot gevolg dat steeds het vooraanzicht, het zijaanzicht en het bovenaanzicht zichtbaar zijn, en dat er relatief weinig vervorming optreedt. (Wikipedia, Figuur 6: Voorstelling van een 2007) axonometrische projectie waarbij alle hoeken tussen de geprojecteerde assen 120° zijn.
Als we dit vertalen naar de praktijk kunnen we vaststellen dat een spel gebaseerd op 2 meetkundige dimensies kan bestaan uit volgende mogelijkheden: Flat 2D Een bovenzicht waarbij alle fysieke eigenschappen in een vlakke stijl worden getekend. Isometrische zicht Een 3D suggestie door middel van een meetkunde projectie. Side Scroller Het spel wordt in zijaanzicht getekend.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
21
Wanneer we de wiskundige definities rond isometrie beschouwen, kunnen we vaststellen dat deze bijzonder ingewikkeld zijn en nooit gebruikt worden in de context van game ontwikkeling. Wiskundige isometrie gaat niet altijd uit van tweedimensionaliteit en gaat ook de projecties in 3D definiëren. In game ontwikkeling hebben we die diepteberekeningen niet nodig daar wij ervoor kiezen om in 2D te werken. Dit wil zeggen dat we enkel de suggestie van diepte wensen te tekenen en niet de diepte zelf. Wanneer we een tilemap in isometrisch perspectief willen tekenen kunnen we uitgaan van een plat tweedimensionaal dambord patroon. Dit dambord patroon vormt de basis van alle berekeningen. We kunnen dus simpelweg alle berekeningen, bewegingen en andere manipulaties uitvoeren op dit platte patroon en achteraf de coördinaten omzetten naar een isometrische suggestie. Omzetten van een vierkant naar een isometrische projectie Allereerst draaien we het vierkant met precies 45° zodat het vierkant op een hoek staat. Vervolgens verminderen we de hoogte met de helft (figuur 7). Op deze manier krijg je een perfecte isometrische tegel. Afbeeldingen kunnen vanzelfsprekend niet zonder meer van een tweedimensionale projectie naar een isometrische projectie getransformeerd worden.
Figuur 7: Transpositie van tweedimensionale projectie naar een isometrische projectie.
Isometrische formules Wanneer we in het dambordpatroon een x- en y-waarde berekenen, weten we dat de x-as horizontaal loopt en de y-as verticaal. Wanneer deze waarden worden getransformeerd naar een isometrische projectie gaan deze assen van plaats veranderen (figuur 8). Maar deze verandering vindt enkel plaats in de projectie, niet in de berekening. We kunnen gewoon de standaard x- en y-waarden gebruiken en deze vervolgens door formules laten omrekenen (tabel 3). 𝒙𝑰𝒔𝒐 = 𝒙 − 𝒚 𝒚𝑰𝒔𝒐 = (𝒙 + 𝒚)/𝟐 Tabel 3: Standaard isometrische formules.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
22
Figuur 8: Theoretische isometrische transitie. Door de gestandaardiseerde isometrische formules toe te passen op lineaire tweedimensionale x- en y-waarden verplaatsen de assen zich naar een isometrische projectie.
3.2
MAP SCROLLING
In een 2D computerspel zijn er twee manieren om beweging te suggereren. De eerste veelgebruikte techniek is de speler zelf lineair doorheen de map te laten bewegen (figuur 9). De speler kan dus, binnen de viewport20, vrij bewegen. Dit houdt in dat het zicht van de speler beperkt is tot datgene wat binnen de viewport zichtbaar is, totdat de viewport wordt hertekend. De map moet enkel hertekend worden wanneer de speler buiten de viewport beweegt waardoor de gemiddelde framerate21 stijgt omdat enkel de speler in realtime hertekend moet worden. Wanneer de speler echter buiten de map beweegt, moet de map, die zichtbaar is in de viewport, volledig hertekend worden. Dit is op tragere platforms moeilijk tot onmogelijk waardoor laadtijden, die als buffer fungeren, moeten worden ingecalculeerd.
Figuur 9: Schematische voorstelling van lineaire beweging. De blauwe pijl duidt een mogelijke beweging aan van de speler. De speler kan dus vrij bewegen in alle richtingen binnen het zichtbare scherm.
20
Viewport: Tweedimensionale rechthoek waarin het spel wordt geprojecteerd, ook wel het venster in het spel genoemd. 21 Framerate: De maat van frequentie waarmee een grafische renderer unieke beelden produceert. Dit wordt vaak uitgedrukt in frames/seconde. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
23
Bij de tweede veel gebruikte techniek om beweging te simuleren gebeurt net het omgekeerde. We centraliseren de positie van de speler en bewegen de map onder de speler door. De speler lijkt dus te bewegen door de verschuiving van de map. Dit systeem laat toe enkel de tegels die buiten de viewport vallen, door de verschuiving van de map, te verwijderen en een reeks tegels bij te tekenen in de richting van de beweging. De speler die op de map staat, gaat in dit systeem mee bewegen met de map en moet dus in tegengestelde beweging worden verplaatst. Hierdoor lijkt het of de speler beweegt en in realiteit beweegt de speler ook op de map. Door de map te verschuiven in de tegengestelde richting van de beweging gaat de speler centraal blijven staan ten op zichte van de viewport.(Figuur 10)
Figuur 10: Schematische voorstelling van lineaire beweging door middel van mapbeweging . De groene pijlen duiden de gecentraliseerde positie van de speler aan. Wanneer de speler naar rechts beweegt wordt de viewport geüpdate in dezelfde richting als de speler. De map zelf beweegt echter in de tegenovergestelde richting. Hierdoor wordt de illusie van beweging gecreëerd.
3.3 TILE BASED Het principe van tilebased engines is ontstaan in een tijd dat er minder RAM geheugen aanwezig was voor de grafische rendering. Het grote probleem was dat de grafische rendering performance te beperkt was om graphics van de wereld alsook de figuren die in deze wereld rondlopen snel en op een vlotte manier op het scherm te tonen. Een tile map bood hier een alternatief aan, aangezien ze in plaats van een volledige wereld in één tekening te stoppen gebruik maakt van verschillende kleinere tiles die samen één geheel vormen. Dit biedt de mogelijk om grote en ingewikkelde werelden met relatief weinig geheugen te tekenen. Een tileMap wordt typisch opgebouwd door gebruik te maken van een matrix (of in de programmeerwereld een 2 dimensionale array). Via een graphic loader wordt elk waarde van elk coördinaat verbonden met een texture22 waarin de tile-afbeelding geladen wordt. Deze 22
Texture: Term voor een computerafbeelding. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
24
waarde kan gekoppeld worden aan bepaalde informatie zoals: terreintype, bewegingsmogelijkheden, snelheid, ... Deze matrix kan aangemaakt worden in een eenvoudige teksteditor maar vaak is het beter om gebruik te maken van een map editor waardoor het gebruik van de mapgrootte en de grafische eigenschappen worden geoptimaliseerd. Tiles kunnen verschillende meetkundige vormen aannemen. Enkele veel gebruikte voorbeelden hiervan zijn een vierkant, een hexagoon en een cirkel.(tabel 4) Voorbeeld Matrix: [1,1,1,1] [1,0,0,1] [1,0,0,1] [1,1,1,1]
Grafische Rendering
Waarden:
1 : Muur, niet bewandelbaar
0: Bewandelbaar
Tabel 4: Matrix vs Tilemap.
3.4
GAME (COMPUTERSPEL)
Een computerspel is een spel dat ontworpen en gespeeld wordt op een computer. De term computer kan in deze context vrij ruim worden geïnterpreteerd daar alles wat een processor, geheugen en een grafische ondersteuning heeft gebruikt kan worden om computerspelen op te draaien. Denk bijvoorbeeld aan de GSM, de PDA, consoles en dergelijke. De Engelse term voor een computerspel, namelijk „game‟, wordt ook steeds vaker gebruikt en werd onlangs omgenomen in woordenboek van Van Dale. Een game is een computerprogramma dat in zeker zin vergelijkbaar is met bordspelen. Een game heeft meestal één of meerdere doel(en) en biedt de gebruiker middelen aan om deze doelen te bereiken. Er bestaan ook games die geen specifiek doel hebben. Een voorbeeld hiervan is het omstreden Second Life, maar deze zijn eerder uitzondering dan regel. Deze doelen kunnen enorm verschillend zijn en hangen vaak af van het type game. Een game en de gameplay worden geprogrammeerd op een engine. 3.5
ENGINE
De engine is de motor van het spel. Hierin worden de mogelijkheden van het spel betreffende beweging, tekenen ... bepaald. De gameplay van het spel wordt in zeer grote mate beschreven door de opbouw van de engine. We onderscheiden 4 typen engines, namelijk Game Engine, Tile Engine, Physics Engine en Particle Engine.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
25
4
FLASH GAME ENGINE
De architectuur van de engine bestaat uit vier grote packages en de resources. Deze componenten hebben elk een specifieke functie in de architectuur en zijn elk van even groot belang voor de correcte werking van de engine (figuur 11).
CORE Collections
Components
Data
IO
Math
Objects
Physics
Rendering
Sound
GLOBAL
GAME Collections
Data
Gameplay
Games
IO
Objects
UI Components
Menu
RESOURCES
Figuur 11: Schematische voorstelling van de architectuur van de engine. De engine en het spel bestaat ui 4 belangrijke packages die elke een specifiek functie hebben. De resources is een verzameling van alle data noodzakelijk voor het functioneren van het spel en de engine.
4.1
CORE
Het eerste package van de architectuur is de Core package. De klassen in dit package zijn een verzameling van voorgedefinieerde klassen en collections die de basis vormen van de engine. Deze klassen, die beschouwd kunnen worden als een collection framework23, zijn zodanig geschreven dat ze een generische herbruikbaarheid aanbieden. De klassen binnen dit package worden onderverdeeld in negen subpackages. 4.1.1 COLLECTIONS Het package collections bestaat uit vier verschillende soorten collections die rechtstreeks door base objecten gebruikt kunnen worden maar ook als superklasse kunnen fungeren. De collection klasse is een niet- type safe base collection klasse die als container fungeert voor displayobjecten of als superklasse kan dienen. Zoals aangehaald is een displayobject de superklasse van alle visuele containers, zoals onder andere de sprite en de movieclip. 23
Framework: Geheel van klassen en componenten die het ontwikkelen van applicaties eenvoudiger maakt en versnelt. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
26
Bijgevolg biedt de klasse in zijn methoden en eigenschappen steeds een displayobject als terugkeerwaarde aan. Dit wil zeggen dat de gebruiker zelf deze terugkeerwaarde moet typecasten24. De objectcollection klasse is exact dezelfde als voorgaande klasse met uitzondering van de terugkeerwaarde. De objectcollection klasse keert in zijn methoden en eigenschappen steeds de top-level klasse, het object, terug. De reden waarom gekozen werd om 2 verschillende klassen te implementeren die ogenschijnlijk dezelfde functionaliteit aanbieden, is dat er een onderscheid gemaakt kan worden tussen de standaardmethoden, het gebruik van het object en het displayobject. Actionscript 3 ondersteunt jammer genoeg standaard geen generics. Dit zorgt voor type safety problemen die zelfs tot inconsistent geheugengebruik kunnen leiden. Een mogelijke oplossing hiervoor is het controleren van het type van het object dat aan de collectie toegevoegd wordt (runtime typechecking25). Deze methode verzekert een typesafe omgeving. In de klasse kan een required type eigenschap aangemaakt worden die gebruikt wordt om het type object dat toegevoegd wordt aan de collectie te controleren (figuur 12).
Figuur 12: De constructor van de GenericCollection klasse. In de constructor wordt een required type meegestuurd. Dit type vormt de basis van de runtime type check.
Bij het toevoegen van een nieuw object wordt gecontroleerd of het type van het object dat toegevoegd wordt, overeenkomt met het requiredtype dat bij de initialisering aan de constructor werd meegegeven (figuur 13). Als dit niet zo is, wordt een type fout verstuurd. De eigenschappen en methoden van deze klassen zijn beschreven voor alle objecten die afgeleidt zijn van de toplevelklasse, het object.
Figuur 13: Runtime type checking in de GenericCollection klasse. Voor een object toegevoegd wordt aan de collectie controleert de functie eerst het type van het object.
De genericdisplaycollection tenslotte, heeft dezelfde functionaliteit als de vorig genoemde klasse met uitzondering van het basistype. Het basistype van deze klasse is het displayobject.
24 25
Typecasten: Operatie waarbij het een datatype expliciet wordt omgezet naar een ander datatype. Typechecking Het controleren van het datatype, dit zowel in runtime als in compiletime. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
27
4.1.2 COMPONENTS Het components package bevat één klasse, de button klasse, die generisch gedefinieerd is. Deze klasse biedt een button in de vorm van een movieclip aan. Adobe heeft standaard een button object in het Actionscript framework geïmplementeerd maar deze heeft beperkingen ten opzichte van de movieclip. Deze button klasse moet gekoppeld worden aan een displayobject uit de bibliotheek. Het voordeel van het gebruik van een movieclip in vergelijking met de standaard button, is dat een movieclip runtime rendering ondersteunt waardoor programmaticaal de button hertekend kan worden.
4.1.3 DATA Het data package bevat alle core klassen die gebruik maken van een vorm van IO26. De PHP klasse is een extensie van de Flash.net.NetConnection klasse waarin extra eigenschappen en gestandaardiseerde methoden worden geïmplementeerd. Dit laat de engine toe de brug naar de mysql databank via een veralgemeende default gateway te maken. 4.1.4 IO De loadmap klasse is een extensie van de Flash.net.URLLoader klasse die het laden van externe bestanden ondersteunt. Deze klasse laadt een gestructureerd .MAP bestand. Dit map bestand moet een tweedimensionale structuur hebben waarbij elke waarde gescheiden wordt van de andere waarden door middel van een “,” en afgesloten moet worden met de letter “x” (tabel 5).
1,2,3,4,5 6,7,8,9,10x Tabel 5: Structuur van een map bestand.
Na het laden keert deze klasse een tweedimensionale array terug die de map voorstelt. Het doorlopen van dit map bestand gebeurt op basis van substrings. De klasse gaat het bestand regel per regel overlopen en zoekt naar “,” en spaties. Het is bijgevolg belangrijk dat deze bestanden steeds correct gestructureerd zijn. De texturelist klasse is een extensie van de Flash.net.URLLoader klasse die een .textures bestand uitleest en dit in een collectie plaatst. Dit .textures bestand is een plat tekstbestand met een opsomming van alles textures die in de map „textures‟ te vinden zijn. Ook de namen van de textures worden zonder extensie opgesomd en van elkaar gescheiden met een “,” (tabel 6).
Texture1,texture2,texture2 Tabel 6: Structuur van een texturelist bestand.
26
IO (input/output) : Verzamelnaam voor alle structuren met betrekking tot communicatie tussen processen. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
28
De LoadTexture klasse is een extensie van de Flash.display.movieClip klasse. De klasse maakt in de constructor een nieuw texturelist object aan waarmee de lijst van de te laden textures wordt opgehaald. Vervolgens worden alle textures die in de lijsten worden gedefinieerd geladen en in een array geplaatst. Deze array wordt later gebruikt om de klasse BitmapCache te initialiseren. De loadXML klasse is de basisklasse voor XML (volgens E4X standaarden) en kan enkel gebruikt worden als superklasse. 4.1.5 MATH Het math package bevat de klasse count, isoalgorithm, position, stringsearch en random, die wiskundige of logische problemen oplossen. De count klasse telt het aantal items op de map van één specifiek type. Het krijgt als parameters de map en een Worldobject mee. De map moet in de vorm van een array gedefinieerd zijn en het Worldobject in de vorm van een string. De isoalgorithm klasse zet een lineair punt om in een isometrisch punt en omgekeerd volgens de gestandaardiseerde formules (tabel 7). xiso = (x – y) yiso = (x + y) /2 Tabel 7: Isometrische formules waarbij geen rekening wordt gehouden met de grootte van een tile.
De position klasse doorzoekt de map naar een specifieke waarde. De map moet in de vorm van een array gedefinieerd zijn en de waarde in de vorm van een string. De terugkeerwaarde van deze functie is het punt waar de waarde het laatst werd gevonden. Dit wil zeggen dat de functie slechts één enkele waarde terugkeert. De random klasse berekent op basis van de map een willekeurige positie. Intern wordt ook gecontroleerd of de positie door de speler bewandelbaar is. De stringsearch klasse ontleedt één element van de map array in verschillende onderdelen (tabel 8). 1. Collision detection De eerste waarde van de string stelt een numerieke waarde tussen 0 en 9 voor die gebruikt wordt voor diepteberekeningen en collision detection. De waarde 0 is gereserveerd voor bewandelbare tiles. De waarde 1 is gereserveerd voor niet-bewandelbare tiles. De waarden 2 tot 9 zijn voorzien maar niet gereserveerd. 2. Worldobject De twee volgende waarden van de string stellen het interactieve object voor. De waarden van 0 tot en met 9 zijn gereserveerd voor de speler De waarden van 10 tot en met 99 zijn gereserveerd voor worldobjects. 3. Texture De laatste 4 waarden zijn gereserveerd voor de texture van de tiles.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
29
0101000 // 0 = de tegel is bewandelbaar // 10 = Standaard Worldobject is het Worldobject met texture 10 // 1000 = Standaard texture is 1000.extensie Tabel 8: Voorbeeld van de werking van de stringsearch klasse De maxtrixwaarde wordt opgedeeld in 3 afzonderlijk waarden.
4.1.6 OBJECTS De objectklasse is een verzameling van voorgedefinieerde superklassen die gestandaardiseerd zijn voor de collecties. Er is bewust niet gekozen om interfaces van deze klassen te maken daar ze weinig nut hebben door de afwezigheid van abstractie. De baseobject klasse is een extensie van de Flash.display.Sprite klasse en beschrijft standaard methoden en eigenschappen die gebruikt worden in zowel de rendering als de collecties. De entity klasse is de superklasse van alle objecten die in de engine en het spel voorkomen. Deze klasse is een extensie van de Flash.display.MovieClip klasse. De geïmplementeerde methoden en eigenschappen mogen niet overschreven worden maar moeten altijd vanuit de superklasse worden opgeroepen. De NPC klasse is de superklasse van alle bewegende objecten in het spel. Deze klasse is een extensie van de eerder genoemde entity klasse en kan bijgevolg gewoon opgenomen worden in de gestandaardiseerde architectuur. 4.1.7 PHYSICS De depthmanager is de basisklasse die standaard diepteberekeningen uitvoert. Deze klasse dient voor meer uitgebreide functionaliteiten als superklasse beschouwd te worden. De depthklasse is een, in Actionscript 3 geïntegreerd, model voor geavanceerde diepteberekeningen en is gebaseerd op bubble sorting en de leeway afwijking. 4.1.8 RENDERING Het rendering package bevat klassen die specifiek geschreven werden om het grafische render proces te optimaliseren en te versnellen. De alphamanager kan op basis van een waarde, in de vorm van een 32-bits integer, een alpha kanaal toevoegen aan de kleur eigenschap van een object. Door het reference model van Actionscript 3 is geen terugkeerwaarde noodzakelijk. De drawing klasse (figuur 14) implementeert vier synchrone call functies die beheerd worden door het DOM model van Actionscript 3.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
30
Figuur 14: De drawing klasse. Deze klasse implementeert 4 synchrone.
Om deze klasse te gebruiken is het noodzakelijk een nieuwe klasse aan te maken die de drawing klasse als superklasse heeft. Vervolgens kan je tot vier call functies overschrijven naar eigen wens (figuur 15). Wanneer je de call functies wil oproepen dien je dit steeds te doen vanuit de superklasse zelf. Dit systeem zorgt voor een efficiënt beheer van de draw calls en biedt ondersteuning voor asynchrone werking.
Figuur 15: Implementatie van een klasse op basis van de drawing klasse. Deze klasse overschrijft 1 call en tekent vervolgens een object door de _draw methode van de super klasse op te roepen.
Het renderen van het spel wordt in principe door de Flash player zelf afgehandeld. De render klasse gaat dan ook alle standaard methoden die betrekking hebben op het renderen van het spel centraliseren om zo een snel en efficiënt beheer van de stage27 te kunnen aanbieden. 27
Stage: De stage is het displayobject met de hoogste hiërarchie. Hierop worden alle andere displayobjecten op geplaatst. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
31
Zowel de resolution klasse als de viewport klasse zijn eigenlijk voorgedefinieerde klassen. De engine verwacht deze klassen precies in deze structuur. Beiden klassen dienen dan ook via het OOP model gebruikt te worden. 4.1.9 SOUND Alhoewel Flash 9 standaard een audio- en videospeler aanbiedt kwamen de specificaties helaas niet overeen met de vooropgestelde vereisten. De sound klasse is gebaseerd op de ingebouwde functionaliteiten maar ondersteunt zowel synchroon als asynchroon geluid. Dit is zeer belangrijk aangezien het afspelen van een FX geluid afhankelijk moet zijn van de snelheid van de interactie en niet van de snelheid van de geluidsverwerking.
4.2
GLOBAL
Het Global package biedt verschillende statische klassen aan die beschikbaar dienen te zijn voor alle game klassen. Het bevat vooral klassen die opsommingen, gestandaardiseerde waarden of typebeperkingen bevatten. De BitmapCache is een statische collectie van alle textures die via de loadmap klasse werden opgehaald. Vooraleer deze klasse gebruikt kan worden dient ze eerst geïnitialiseerd te worden. Vervolgens kan de klasse doorheen de hele engine gebuikt worden als statische container (Figuur 16).
Figuur 16: Voorbeeld van de werking van de statische BitmapCache klasse. Deze klasseis een statische verzameling van textures.
De itemcache klasse is een statische collectie gebaseerd op de core objectcollection klasse. Bij initialisatie gaat deze klasse een weak-typed array converteren tot een collectie van textures. De andere klassen die in dit package zitten zijn elk een verzameling van statische constante stringwaarden die alle mogelijke types voorstellen van een bepaald object (figuur 17).
Een korte opsomming van de andere klassen in dit package: 1. 2. 3. 4. 5.
Item types Missiontypes NPCtypes Texttypes States Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
32
6. Sounds 7. Type
Figuur 17: Voorbeeld van een statische klasse: de ItemType klasse.
4.3
UI (USER INTERFACE)
Om de interactie tussen de gebruiker en de engine zo optimaal mogelijk te laten verlopen wordt er gebruikt gemaakt van een User Interface (UI). Dit package bevat een reeks componenten die gebruikt worden in de UI van het spel. 4.3.1 MENU
Figuur 18: Schermafdruk van het menu.
Het intromenu (figuur 18), dat door de collega‟s van het Departement Beeldende Kunst (opleiding grafische kunst) werd gebouwd, is een movieclip uit de Flash bibliotheek die verbonden is met deze klasse. Via dit hoofdmenu, dat bij de start van het spel wordt getoond, kan een gebruiker een nieuw spel starten, een bestaand spel verder zetten, de credits bekijken of de algemene voorwaarden raadplegen. De klasse die met de movieclip verbonden is biedt enkele eigenschappen aan, volgens de OOP principes, die het hoofdmenu moet delen met de engine. Verder implementeert deze klasse een PHP data connectie waarmee de gegevens van de gebruiker worden opgehaald of weg geschreven.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
33
Het selectiemenu (figuur 19) is een onderdeel van het hoofdmenu. Deze klasse is verbonden met een MovieClip uit de Flash bibliotheek en wordt gebruikt om een karakter te kiezen waarmee vervolgens het spel gespeeld wordt. Deze klasse implementeert standaard enkel het DOM Event model. De visuele kant van dit menu is volledig opgemaakt in de Flash designer op basis van de Flash tijdlijn. Nadat een keuze wordt gemaakt gaat de klasse, die aan de movieclip hangt, een event dispatchen waardoor het hoofdmenu weet dat er een figuur is gekozen.
Figuur 19: Schermafdruk selectiemenu.
van
het
Het frame (figuur 20) is een movieclip die alle user interface objecten die in het spel gebruikt worden verzamelt in één object. Dit object bestaat dus uit verschillende componenten die elk hun eigen movieclip object hebben met de daarbij horende klasse. De volgende onderdelen zijn terug te vinden op het frame:
Score Ingame display Healthbar Message interface Ingame menu Mp3 speler Inventory
Figuur 20: Schermafdruk van het frame
De klasse die aan dit frame gelinkt is kan beschouwd worden als een centrale manager voor alle componenten die op dit frame staan. Verder is dit frame volledig afhankelijk van de gegevens van de gebruiker. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
34
4.3.2 COMPONENTS De display, die een onderdeel is van het eerder vernoemde frame, reageert op het ingame menu. Wanneer de display wordt getoond, wordt het spel in een pauze status gezet en kan de gebruiker interacteren met het menu. De klasse die aan deze movieclip hangt is een extensie van de Flash.display.MovieClip klasse. De energybar movieclip en klasse hebben als doel de huidige energie waarde van de speler grafisch voor te stellen. Deze energiemeter kent als bovengrens 100 en als ondergrens 0. Wanneer de energie waarde van de speler minder dan 0 is verliest hij een leven. De klasse achter deze movieclip berekent de visuele representatie van de energie waarde. Deze klasse wordt niet rechtstreeks gebruikt maar is geïmplementeerd in het frame van waaruit de energie wordt bepaald door de gegevens van de gebruiker. De mp3 (figuur 21)speler is een volledig onafhankelijke audiospeler die geïntegreerd is in het frame. De mp3 speler is volledig gebaseerd op xml waarden van waaruit kanalen en muziek kunnen worden toegevoegd. De sound backbone van deze speler is gebaseerd op de sound klasse uit de core namespace. Ook deze klasse wordt niet rechtstreeks door het spel gebruikt maar is geïmplementeerd in het frame van waaruit deze Figuur 21: Schermafdruk van de mp3 beheerd wordt. speler. De equalizer klasse is een onderdeel van bovenstaande mp3 speler en biedt een visuele representatie aan van het geluidskanaal. De klasse berekent een geluidsspectrum (figuur 22) van het gekozen geluid in de vorm van een bytearray. Vervolgens wordt een ingeladen texture vervormd aan de hand van dit spectrum.
. Figuur 22: Spectrum functie. Deze functie visualiseert een geluidsbestand.
Alle objecten die de speler in het spel opraapt worden automatisch door de engine behandeld. Wanneer aan specifieke voorwaarden voldaan is komen bepaalde worldobjects in de inventory terecht. De inventory (figuur 23) is een verzameling van objecten die de speler kan bewaren en waarmee interactie kan bestaan. De inventory klasse is, zoals alle andere componenten, gekoppeld aan een movieclip waarmee een visuele representatie van de inventory getoond wordt in het frame. Deze klasse wordt niet rechtstreeks gebruikt maar wordt volledige automatisch door de engine gestuurd en met gegevens van de gebruiker gevuld. De elementaire werking van deze klasse kan met onderstaande afbeelding schematisch worden voorgesteld.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
35
Initialisatie
Visuele initialisatie
Bouwen van de inventory
Add item/ remove item
Figuur 23: Schematische voorstelling van de werking van de inventory.
1. De itemarray wordt geïnitialiseerd op basis van de gegevens van de gebruiker. 2. Er wordt berekend hoeveel items effectief aan de movieclip moeten worden toegevoegd. 3. De visuele representatie wordt gebouwd. 4. Na de volledige initialisatie en bouw van de inventory kan de engine items toevoegen en verwijderen. Verder implementeert deze klasse ook methoden die gebruikt worden voor de visuele kant van de inventory ;zoals onder andere scrollen, sorteeralgoritmes, … Om de interactie tussen de gebruiker en het spel optimaal te laten verlopen is er gekozen om een klasse te definiëren, het messageframe (figuur 24), die de standaard NPC interactie ondersteunt. Dit betekent concreet dat er een movieclip is aangemaakt die de mogelijkheid beidt om de mogelijke NPC opties grafisch voor te stellen. De klasse biedt de mogelijkheid om 3 knoppen te definiëren die een bepaalde actie veroorzaken en om een tekstveld te definiëren waarin informatie, die gebruikt kan worden om de speler te informeren, kan geplaatst worden.
Figuur 24: Schermafdruk van het messageframe.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
36
4.4
GAME
Het game package is een verzameling van klassen die gebaseerd zijn op de core maar specifiek geschreven zijn voor dit spel. Dit houdt in dat deze klassen niet generisch zijn en enkel in deze context bruikbaar zijn. Ze kunnen over het algemeen beschouwd worden als hulpklassen voor het uiteindelijke spel. 4.4.1 COLLECTIONS De tileset is een type-safe collectie die specifiek geschreven is voor het benaderen en verzamelen van tile objecten. De engine verwacht dit tile object als terugkeerwaarde en gaat nooit casten op een terugkeerwaarde. Deze klasse is een extensie van de base.Core.Collections.Collection klasse maar voorziet nieuwe methode in plaats van de bestaande super methoden te overschrijven. De reden hiervoor is dat deze methoden meer parameters vereisen dan de standaard super methode (figuur 25).
Figuur 25: AddTile methode van de tileset klasse.
4.4.2 DATA Omdat de engine volledig aanstuurbaar moet zijn vanuit externe data is gekozen voor een php /mysql driven backbone voor het gebruikersbeheer. Dit laat toe om de gebruiker de mogelijkheid te bieden om het spel op te slaan. De phpcon klasse is een extensie van de base.core.data.php en implementeert methoden en eigenschappen, volgens het OOP principe, die betrekking hebben op de gebruiker. Deze klasse is niet generisch en de methodes zijn voorzien voor een specifieke databank. Dit systeem werkt met de AMFPhp engine die als brug fungeert tussen php/mysql en Actionscript 3 (figuur 26).
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
37
MySql
databank PHP 5
Serverside script AMF Php
Brug Actionscript
AMF Php gateway Engine
Php klassen Figuur 26: Schematische voorstelling van de datastructuur van de engine. De php klassen maken via een default gateway een verbinding met de AMFPHP engine die op zijn beurt de verbinding met de mysql databank tot stand brengt via ingebouwd php klassen.
Er werd gekozen om met de AMF(Action Message Format) php engine te werken daar deze de php verbinding met Actionscript centraal beheert. Voor kleine en middelgrote applicaties kan php best rechstreeks geïmplementeerd worden maar voor grotere projecten is een extern centraal beheer sneller en beter. 4.4.3 GAMEPLAY Collision detection(CD) is de Engelse term voor het detecteren van intersectie tussen 2 objecten (figuur 27). Dit betekent dat de engine via het CD systeem controleert of de coördinaten van een specifiek object overeenkomen met de coördinaten van een ander object.
Object A
Object B
Figuur 27: Intersectie tussen 2 objecten.
Doorheen de jaren zijn er veel verschillende soorten CD ontstaan die elke hun eigen vaak ingewikkelde algoritmes hebben. In deze context, tile based isometrie, kunnen we de Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
38
eenvoudigste manier van CD toepassen. In ons model (figuur 28), en dit geldt trouwens voor de hele engine, gaan we uit van een matrix. De map wordt dus bepaald door een .Map bestand in de vorm van een matrix. De waarden in deze matrix hebben een bepaald structuur en worden door de engine ontleed. In die structuur is ook een waarde voorzien waarmee we bepalen of een tegel wel of niet bewandelbaar is door de speler. In ons geval is gekozen voor de waarde 1 als de tile niet bewandelbaar is en de waarde 0 als de tile wel bewandelbaar is.
Figuur 28: Schematische voorstelling van het collision detection model. In dit geval kan de speler enkel naar boven, naar links of naar onder bewegen.
Zoals vermeld dienen alle objecten die in de engine voorkomen af te stammen van de base.core.objecte.Entity klasse. Deze klasse implementeert de volgende 4 eigenschappen (figuur 29) betreffende CD:
Figuur 29: Eigenschappen van de entity klasse. In deze eigenschappen worden de matrixwaarden van de aanliggende tiles bijgehouden.
Deze eigenschappen worden gebruikt om de matrixwaarde van de omringende tiles bij te houden. Vooraleer de speler een bepaalde beweging kan doen gaat de CD processor na of de speler wel naar die specifieke richting mag bewegen . Dit gebeurt door te controleren of de tegel langs de speler in de richting waarin de speler wil bewegen wel bewandelbaar is. Dit systeem is niet bijzonder accuraat maar is in een tweedimensionaal context erg snel en flexibel.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
39
Diepte is een absolute vereiste wanneer we in een tweedimensionaal isometrisch perspectief werken. Alle tiles moeten een afzonderlijke dieptewaarde krijgen omdat deze tiles volgens deze dieptehiërarchie getekend worden. In dit systeem geldt: hoe hoger de diepte, hoe hoger de zichtbaarheid van de tegel. De suggestie van diepte creëren is een relatief eenvoudig proces (figuur 30). Door voldoende diepte buffers in te bouwen tussen de verschillende tiles kunnen we bewegende objecten dynamisch van diepte laten wisselen afhankelijk van de diepte van de omliggende tiles.
Figuur 30: Schematische voorstelling van de diepteverwerking bij een beweging naar rechts.
Zelfs indien er binnen de tiles zelf bewogen wordt of indien het bewegend object groter is dan de tile zal er nooit een probleem zijn. Adobe implementeerde in eerdere versies van Actionscript een standaard depth systeem. Dit systeem was niet type-safe en kon bij slecht gebruik enorme geheugenlekken veroorzaken. Dit oude diepte systeem liet toe oneindig aantal bufferplaatsen te reserveren in de displaylist van de stage zonder hierin objecten te plaatsen. Concreet betekent dit dat je in Actionscript 2 een oneindig aantal layers dynamisch kan aanmaken en deze een willekeurige index kan geven. Helaas is deze eigenschap in Actionscript 3 niet doorgevoerd en is de structuur van de displaylist (figuur 31) helemaal herzien. In Actionscript 3 wordt de stage beschouwd als een soort array. Dit wil zeggen dat er geen lege plaatsen kunnen zijn en dat de indices elkaar moeten opvolgen.
0
• Movieclip
1
• Movieclip
2
• Movieclip
3
• Movieclip
4
• Movieclip
Figuur 31: Schematisch voorstelling van de displaylist. De displaylist kan enkel displayobjecten bevatten en de indices dienen opeenvolgend te zijn.
Voor de diepteberekening van de engine betekent dit dat er geen buffer ingebouwd kan worden en alle indices netjes op elkaar aansluiten.(figuur 32) Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
40
Figuur 32: Aansluitende diepte indices in een tile based omgeving.
Deze situatie zorgt ervoor dat het oorspronkelijk idee niet meer toegepast kan worden. Door de opeenvolging van de indices kan de diepte van de bewegende onderdelen nooit exact bepaald worden en zal er steeds een overlap bestaan. Hiervoor zijn 2 mogelijk oplossingen bedacht:
Buffer bitmaps Allereerst werd er gedacht aan een systeem dat lege bitmaps toevoegt aan indices die gereserveerd moeten worden. Dit systeem is vrij eenvoudig te implementeren maar zorgt voor een sterk performanceverlies daar lege bitmaps door Flash ook gerendered worden Sorteer algoritmes Er bestaan verschillende sorteeralgoritmes die alle tiles aflopen en herindexeren. Dit betekent in de praktijk dat alle zichtbare tiles overlopen moeten worden en opnieuw in runtime hertekend moeten worden. Dit is een haalbaar systeem als de resolutie kleiner is dan 400x300.(figuur 33)
Figuur 33: Bubble Sort algoritme in Actionscript 3.
Omdat geen van de vorige systemen efficiënt genoeg werkt is er dan beslist om een perfect werkend dieptesysteem voorlopig uit te stellen en een benadering ervan te gebruiken. De depth klasse is een extensie van de base.core.physics.DepthManager en implementeert methoden die zowel de diepte van bewegende objecten berekent als de diepte van tiles die bijgetekend worden.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
41
De doelstelling van het prototype van het spel is het de bedoeling objecten te verzamelen die verspreid liggen op de map. De gebruiker kan zo de campus van de PHL virtueel ontdekken. Deze objecten kunnen zowel worldobjects zijn die opgeraapt en gebruikt kunnen worden alsook NPC‟s die interactief informatie geven aan de gebruiker. De engine implementeert een systeem waarbij missies dynamisch verwerkt worden. Dit wil zeggen dat de engine de missies laadt uit een .xml bestand, de missies dynamisch tekent en de gevolgen van de missies dynamisch verwerkt. De mission klasse speelt hierin een belangrijke rol. Deze klasse laadt bij initialisatie één specifieke missie op basis van naam. Vervolgens gaat de klasse de structuur van de missie en de objectieven die hieraan vast hangen volgens het OOP principe delen. De missionobjective klasse is een onderdeel van het missiesysteem en bestaat voornamelijk uit eigenschappen die de verwerking van de missies verbeteren. Deze klasse representeert één objectief uit één missie 4.4.4 IO (INPUT/OUTPUT Het IO package bevat klassen die betrekking hebben op de invoer en uitvoer van data specifiek voor dit spel. Ze zijn niet generisch en zijn enkel bruikbaar in deze context. Er bestaan verschillende klassen in dit package die allen van de base.core.data.xml klasse afstammen en elk een specifieke taak hebben. Ze kunnen beschouwd worden als hulpklassen voor het laden en initialiseren van andere objecten.
LoadInventory Deze klasse verzorgt het laden van de inventory items op basis van de gegevens van de gebruiker. Ze wordt rechtstreeks geïmplementeerd in de inventory klasse. LoadItem Deze klasse laadt een xml met alle item omschrijvingen die de engine ondersteunt. Elke keer als een Worldobject wordt getekend of door speler wordt opgeraapt wordt deze collectie geraadpleegd om de omschrijving van de gevolgen van de actie op te halen. LoadMission Deze klasse laadt een missie aan de hand van de bestandsnaam. Ook hier wordt de klasse rechtstreeks in de mission klasse gebruikt. LoadNpc De loadNPC klasse laadt de standaard NPC‟s. LoadSounds De loadsounds klasse laadt alle geluidsbestanden via een stream 28 model.
De loadmanager verzamelt verschillende klassen die elk een bepaald bestandstype laden in 1 gecentraliseerde klasse. Het voordeel van dit systeem is dat extra laders achteraf naadloos bijgevoegd kunnen worden. De Preloader verwerkt deze dan ook automatisch.
28
Streaming is een techniek waarbij bewegende beelden of geluidsfragmenten in kleinere delen worden opgesplitst. De delen worden afzonderlijk gedownload. (buffer) Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
42
4.4.5 OBJECTS Dit package bevat alle objecten die door het spel worden gebruikt. Over het algemeen spreken we hier over extensies van de base.core.objects.entity klasse. Deze klassen zijn verder uitgewerkt voor één specifiek doel. Ze hebben elke specifieke methoden en eigenschappen bovenop de gestandaardiseerde methoden en eigenschappen gedefinieerd in de super klasse.
Interaction NPC Character WorldObject Tile(figuur 34) Box Item
Figuur 34: SchermAfdruk van de tile klasse. Deze klasse heeft een reeks eigenschappen die specifiek voor dit object van toepassing zijn.
Om het overzicht van het spel te bewaren en de gebruiker de mogelijkheid te geven objecten te situeren is er een minimap (figuur 35) voorzien. Dit systeem werd aanvankelijk in het frame opgenomen en dus ook in realtime getekend. Na uitvoerig testen (grafiek 1) bleek dat dit systeem teveel performance problemen gaf en is er besloten om de minimap achter een sneltoets aan te bieden. Dit laatste laat toe de minimap telkens wanneer ze opgeroepen wordt opnieuw te herinitialiseren en dus ook te hertekenen. De engine kan dan in een pauze status gezet worden waardoor we nooit 2 mappen op het zelfde moment moeten hertekenen. De minimap klasse maakt geen gebruik van de engine voor het tekenen van de map. Ze voorziet zelf een draw call die de map tekent op basis van de viewport.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
43
35 30 25 20
Minimap
15
Geen Minimap
10 5 0 Grafiek 1: Frames per second bij de aanwezigheid en afwezigheid van een realtime minimap.
De minimap kent standaard slechts 3 verschillende types tiles:
Groen: Alle tiles die bewandelbaar zijn door de speler zijn groen gekleurd. Grijs: Alle tiles die niet bewandelbaar zijn door de speler zijn grijs gekleurd. Blauw: Alle tiles die water bevatten of buiten de matrix liggen zijn blauw gekleurd.
De speler wordt op de minimap voorgesteld als een rode bol met een bewegende cirkel rond. Hierdoor kan de gebruiker zichzelf onmiddellijk situeren in het spel. Alle objecten die op de map liggen wordt voorgesteld door een zwarte lichtbol.
Figuur 35: Schermafdruk van de minimap.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
44
De user klasse is één van de meest cruciale klassen van de engine. Deze klasse voorziet een hele reeks eigenschappen en methoden die slecht 1 doel hebben: de gegevens van de gebruiker tijdens het spel bij houden en deze op de juiste plaats injecteren in de engine. Het spel, alsook de engine, haalt dus alle data uit deze user klasse. Hierdoor is het van groot belang dat deze user klasse bij elke verandering de engine op de hoogte stelt van deze verandering. Dit gebeurt door middel van een event. Elke keer een eigenschap van de user klasse verandert gaat de user klasse een event dispatchen die door de engine opgevangen kan worden. Omdat de user klasse bijzonder veel eigenschappen heeft om alle data bij te houden is het bijzonder veel werk om bij de update van elke eigenschap een event te dispatchen. Een oplossing hiervoor werd gevonden in een andere Actionscript bibliotheek, namelijk het Flex framework. Dit framework biedt de objectproxy (figuur 36) klasse aan. Deze klasse gaat alle eigenschappen in het oog houden en bij elke verandering een event doorsturen. Dit gecentraliseerd beheer van events zorgt voor een enorme verbetering van de performance.
Figuur 36: Een objectproxy in de user klasse. Deze klasse beheert alle eigenschappen van de user klasse. Wanneer ze een verandering detecteert in de eigenschappen van de user klasse dispatcht ze een event.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
45
5
PHL ADVENTURE GAME
Het spel zelf is gedefinieerd in 2 klassen: de preload klasse en de game klasse. De preload klasse is verantwoordelijk voor het correct aanleveren van data waarmee de game klasse de engine gebruikt. 5.1
PRELOAD
Voordat het spel wordt gestart moet eerst de juiste data gepreload worden en naar de engine gestuurd worden. Deze data is afhankelijk van de gegevens van de gebruiker. Allereerst wordt het menu geïnitialiseerd en getoond op het scherm. Dit menu is een grafische representatie van de gegevens van de gebruiker. De gebruiker kan in dit menu een nieuw spel starten of een bestaand spel verder zetten. Wanneer een nieuw spel gestart wordt leidt het menu de gebruiker door verschillende schermen om zo de initiële gebruikersgegevens te bepalen. De gebruiker kan onder andere een naam, een wachtwoord, persoonlijke gegevens en een karakter kiezen waarmee het spel wordt gespeeld. Als het nieuw spel wordt aangemaakt legt de engine standaard waarden vast betreffende gameplay. Het aantal afgewerkte missies wordt op 0 gezet, de standaard startscore wordt aan de gebruiker toegewezen, het aantal health en levens wordt bepaald … . Deze gegevens worden vervolgens in de database opgeslaan en op de server wordt een map aangemaakt met data die specifiek voor deze gebruiker is vastgelegd. Als de gebruiker kiest om een bestaand spel verder te zetten dient hij zijn gebruikersnaam en wachtwoord in te geven. Deze gegevens worden door de engine gebruikt om de juiste data uit de database te halen en de correcte mappengroep op de server aan te spreken.(figuur 37)
Gebruiker
User interface
Spel
Engine
Mysql databank
Map
Figuur 37: Schematische voorstelling van de preload klasse. De gebruiker bepaalt de data via de user interface van het spel waarmee de engine werkt.
Nadat het menu de juiste gegevens van de gebruiker heeft gedefinieerd wordt een event gedispatcht naar de preload klasse. Deze laatste weet nu dat de menu klasse klaar is en kan via het OOP model de nodige data uit de menu klasse halen. Op basis van deze data start de Preloader met het 2de proces.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
46
Vervolgens initialiseert de Preloader een object van de de loadmanager klasse. De loadmanager klasse is een verzameling van laders die elke een specifieke taak hebben. Elke lader staat in voor één specifiek resource type. De loadmanager klasse gaat deze laders dan ook sturen met behulp van de gegevens van de gebruiker.
Load Manager
Laad texures
Laad gebruikersgegevens
Laad inventory
Laad map
Figuur 38: Hiërarchische voorstelling van de loadmanager klasse. De loadmanager verzamelt alle laders in één gecentraliseerde klasse.
Allereerst laadt de loadmanager alle textures met behulp van de loadtextures klasse. Zowel de textures van de tiles, van de worldobjects als van de NPC‟s worden door deze klasse geladen. Deze bevinden zich elk in een aparte map met elk een eigen texturelist. Tijdens het laden stuurt de loadmanager constant data naar de preload klasse. Deze laatste weet dus hoe ver de loadmanager precies zit met laden en kan dit dan ook grafisch voorstellen door middel van de preload balk. Als laatste stap in dit proces initialiseert de loadmanager de statische BitmapCache klasse met de geladen textures. Wanneer de textures volledig geladen zijn en de global klassen geïnitialiseerd zijn dispatcht de loadtextures klasse een event dat alles succesvol verlopen is. Hierdoor weet de loadmanager dat hij de volgende lader kan aanspreken: de user klasse. De user klasse is één van de meest essentiële klassen in de engine. Ze voedt de engine met data die noodzakelijk is voor een correcte werking van het spel. Deze klasse bevat dus eigenschappen en methoden die de engine kan aanspreken. De user klasse kent geen hulpklasse voor het laden van data maar gaat zichzelf met data vullen bij initialisatie. Ook de user klasse laat via een event de loadmanager weten dat de user klasse klaar is voor gebruik. Als laatste stap haalt de loadmanager de map op via de loadMap klasse. De map is gebaseerd op een .MAP bestand in de vorm van een matrix die gespecificeerd is per gebruiker. Wanneer de gebruiker een nieuw spel start zal dit een standaard .MAP bestand zijn. Als de gebruiker al een spel heeft opgeslaan is dit een .MAP bestand gedefinieerd in de map van de gebruiker die op de server staat. Als deze laatste stap succesvol is wordt de loadmanager opnieuw gewaarschuwd door middel van een event. Nadat de loadmanager deze laatste event ontvangt dispatcht de loadmanager zelf een event die de preload klasse vertelt dat alle laders succesvol overlopen zijn.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
47
5.2 SPEL Het spel zelf, dat terug te vinden is in de klasse game.as, is een Actionscript 3 bestand met een duizendtal regels dat gebruik maakt van alle eerder opgesomde structuren en zo een spel vormt. Ik ga trachten voornamelijk in theorie de werking van het geheel algemeen te verklaren. 5.2.1 DECLARATIE EN INITIALISATIE Het is van vrij groot belang dat datatypes op de juiste manier worden gedeclareerd. Zo is er een enorm verschil in geheugenverbruik tussen een floating point en 32 bits integer of tussen een object en een string. Actionscript 3 ondersteunt vrijwel alle standaard datatypes. Naast deze primitieve objecten dienen we ook objecten aan te maken die door de engine gebruikt worden. Onderstaande afbeelding toont een reeks objecten die in het spel worden gedeclareerd.
Figuur 39: Declaraties uit de game klasse.
Globale declaratie is natuurlijk iets wat ten alle koste vermijden moet worden aangezien ze aanzienlijk meer geheugen verbruiken daar ze nooit door de garbage collector worden opgeruimd. De enige manier om een globaal gedeclareerde variabele toch te verwijderen is ze gelijk te stellen aan null en alle referenties naar dit object te verwijderen. Helaas zijn globale objecten noodzakelijk omdat sommige objecten nu eenmaal over het hele spel beschikbaar moeten zijn.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
48
Anderzijds is het gebruik van een locale declaratie in een loop 29 ook alles behalve geheugenbesparend. Een mogelijk oplossing hiervoor is het declareren van een globaal object zonder deze te initialiseren. Hierdoor kunnen we dit object in een locale functie initialiseren, gebruiken en vervolgens weer disposen. Dit systeem zorgt ervoor dat hetzelfde object herbruikt kan worden waardoor een aanzienlijke hoeveelheid geheugen wordt bespaard.(figuur 40) Door consequent gebruik van doordachte declaratiemethoden is het mogelijk enorm veel geheugen te sparen en de applicatie optimaal te houden.
Figuur 40: Verschil in declaraties.
Als de game.as klasse wordt opgestart maakt de default constructor een preload.as object aan in het spel zelf. Nadat de preload klasse alle data heeft geladen wordt dit object verwijderd en wordt de functie startgame() opgeroepen. Deze functie gaat alle nodige objecten en event listeners initialiseren. Allereerst moet de stage geïnitialiseerd worden zodat deze correct werkt met de engine. Zo wordt de framerate van de stage op de gewenste hoeveelheid geklokt. De standaard voor webgames in de game industrie verwacht minstens 35 frames per seconde op alle systeem voor een correcte en vlotte gameplay. Door de berekeningen van de engine, het renderen van grafische objecten en andere factoren verliezen we vanzelfsprekend aanzienlijk wat frames per seconde. Om dit te compenseren wordt de FPS geklokt op 45. Dit geeft ons een buffer van 10 frames per seconde. Zoals vermeld heeft de engine specifieke data nodig van de gebruiker. Deze data werd eerder in de preload klasse geladen en kan volgens het OOP principe opgehaald worden. Enkele voorbeelden van data is de map array en de gebruikergegevens. Naast de engine en de stage zelf moeten ook de verschillende objecten die globaal gedeclareerd werden geïnitialiseerd worden.
29
Loop: Een repetitie in een programmeertaal waardoor een of meer statements een aantal keren uitgevoerd worden. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
49
In de eerste initialisatie methode, init(), worden de volgende structurele initialisatie uitgevoerd:
Character Het character stelt de gebruiker voor. Dit object kan door de gebruiker worden aangestuurd. Resolutie In deze eerste initialisatie wordt ook de resolutie ingesteld. In deze context wordt een resolutie van 640 x 480 gebruikt waarbij 640 de breedte van het tekenveld is en 480 de hoogte. User De eigenschappen van de user klasse worden geüpdate. Sound De sound klasse wordt geïnitialiseerd.
In de tweede initialisatie methode, initialiseListeners(), worden alle globale event listeners toegevoegd (figuur 41).
Figuur 41: Initialisatie van de event listeners. Deze listeners zijn essentieel voor de engine omdat deze alle data uit deze event listeners haalt .
De derde initialisatie, initializeNPC(), gaat alle NPC uit een xml laden en deze in een array plaatsen die in de engine geïntegreerd is. De engine kan deze array lezen en verwerkt alle NPC‟s die zich in de array bevinden. De laatste initialisatie, initializeUI(), verzorgt de User interface. De functie gaat het frame en alle componenten die betrekking op de user interface klaarmaken voor gebruik. Ook dit gebeurt op basis van de gegevens van de gebruiker. 5.2.2 DRAW CALL Nadat alle objecten geïnitialiseerd zijn, kunnen we de eerste draw call uitvoeren. Deze functie gaat de map tekenen vooraleer het spel begint. Als eerste stap gaat deze methode de positie van de speler bepalen. Dit is essentieel aangezien de speler steeds gecentraliseerd wordt (figuur 42). Het is dus nodig te weten op welke tegel de speler staat zodat de afwijking ten op zichte van de viewport berekend kan worden. In de volgende stap dienen we de x- en ywaarden van de viewport in te stellen. Aangezien de engine de map tekent en later ook hertekent op basis van de viewport is het belangrijk dat deze berekeningen correct zijn. De vier viewport punten kunnen we exact berekenen met behulp van standaard formules (tabel 9). Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
50
viewPort.start.x viewPort.start.y viewPort.end.x viewPort.end.y
= = = =
char.matrix.x char.matrix.y char.matrix.x char.matrix.y
-(resolution.x/this.TILESIZE)/2 -(resolution.y/this.TILESIZE)/2 +(resolution.x/this.TILESIZE)/2 + (resolution.y/this.TILESIZE)/2
Tabel 9: Formules die de viewport berekenen.
Figuur 42: Schematische voorstelling van de viewport. Om de verschillende punten van de viewport te berekenen vertrekken we vanuit de tile (of matrixwaarde) van de speler, die steeds centraal staat.
We kunnen bijvoorbeeld de linkse bovenhoek van de viewport (viewport.start.x) berekenen door de matrixwaarden van het character te nemen en hiervan het aantal tiles af te trekken ten op zichte van de resolutie (tabel 10).
Vb. Het character staat op positie (20,10) in de matrix en de resolutie is 200 x 100 met een tilegrootte van 20. viewPort.start.x = 20 – (200/20)/2 viewPort.start.x = 15 Tabel 10: Voorbeeld van een berekening van één viewport punt.
Nu zijn de grootte van de viewport en de matrixwaarden van de tiles die binnen de viewport liggen bekend. In de volgende stap wordt de initiële offset, van het character ten op zichte van de viewport, berekend met behulp van formules (tabel 11).
Offset.x = (TileSize*char.maxtrix.x)-(TileSize*char.matrix.y) Offset.y = ((TileSize*char.maxtrix.x)-(TileSize*char.matrix.y))/2 Tabel 11: Formules voor de berekening van de viewport offset.
Vervolgens worden door middel van een dubbele for loop alle tiles getekend die in de viewport liggen. Hiervoor gebruiken we de eerder gedefinieerde viewport x- en y-waarden.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
51
In de loop wordt allereerst op elke coördinaat een tegel getekend. Het tekenen van een tegel wordt door een aparte functie behandeld (figuur 43). Deze functie maakt een nieuw tile object aan en berekent vervolgens s de tileoffset. Deze waarde bepaalt exact de x- en y-waarde, waarop de tegel getekend moet worden. Dit gebeurt met behulp van de eerder gedefinieerde offset waarde. De berekeningen zijn gebaseerd op de gestandaardiseerde isometrische formules die eerder besproken werden. Nadien controleert de functie of de tegelwaarden wel in de matrix liggen. In het geval dat deze tegel in de matrix ligt, haalt de functie alle nodige data uit de matrix met behulp van de eerder besproken stringsearch klasse. De tegel tekent de juiste texture op zichzelf en wordt toegevoegd aan de tileset. In de laatste stap wordt de tegel aan een container toegevoegd: de baselayer. In het geval dat de tegel niet in de matrix ligt wordt een standaard texture gebruikt en worden verder geen specifiek eigenschappen geset.
Figuur 43: De createTile() functie . Deze functie tekent een nieuwe tile op basis van zowel de x- en y-waarden als de richting.
Naast het tekenen van tiles, tekent de draw functie ook het character met behulp van de createCharacter() functie. Deze dient vanzelfsprekend in het centrum van het beeld getekend te worden. De x- en y-waarden zijn dus eenvoudig te berekenen op basis van de resolutie. Ook gaat de functie de npcarray controleren op de aanwezigheid van non playable characters (NPC). Indien er NPC‟s aanwezig zijn, worden deze getekend door middel van de createNpc() functie. Deze functie is gelijkaardig aan de createTile() functie en gaat ook voor elke NPC de tileoffset waarden berekenen. Alle andere eigenschappen die deze NPC‟s bezitten, zijn beschreven in het NPC object zelf en worden dus niet in de collectie opgenomen. Deze functie bepaalt met andere woorden enkel de x- en y-waarden van de NPC. Vervolgens worden de x- en y-waarden van de baselayer correct ingesteld en wordt de baselayer toegevoegd aan de displaylist van de stage. Als allerlaatste stap wordt de diepte van
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
52
het character ingesteld. De draw call (figuur 44) is nu volledig doorlopen en het spel is nu volledig geïnitialiseerd en klaar om te starten.
Figuur 44: De draw call van PHL webgame. De draw functie tekent de initiële map voordat het spel begint.
5.2.3 INTERACTIE EN GAMEPLAY Het spel kent verschillende methoden die als enig doel hebben om de interactie van de gebruiker te verwerken en te visualiseren. Voor elke gebeurtenis of event moet een specifieke actie voorzien worden (figuur 45). Indien dit niet het geval is, zouden zowel de gebeurtenis als de actie zinloos zijn. In de praktijk betekent dit dat de engine reageert op events die door de gebruiker of door de gameplay worden veroorzaakt. Deze events dienen voornamelijk om data te updaten of om bepaalde acties uit te lokken.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
53
Figuur 45: Schematische voorstelling van het actiemodel van de engine.
Gebeurtenis Aangezien de engine volledig event based is, moeten alle objecten die in games.as klasse aan bod komen zelf de engine laten weten wanneer er een gebeurtenis plaats vindt. Dit houdt concreet in dat alle objecten in staat moeten zijn een event te dispacten die op een of andere wijze in de game klasse terecht komen. Dit kan op verschillende manieren gebeuren. Een eerste manier is dat de game klasse zelf luistert naar objecten die in staat zijn om een event te dispatchen. De game klasse gaat dan niet alleen de events van die objecten kunnen ontvangen maar ook alle events die door objecten worden gedispatched die geïnitialiseerd zijn in het object waarop hij luistert (Event bubbling). Een voorbeeld van dit Event bubbling model is het aanklikken van een item in de inventory. Op het moment dat een speler klikt op een item verstuurt dit item zelf een event. Deze event wordt initieel herkend in de Inventory klasse waarvan dit item een visueel child is. De inventory bekijkt het eventobject en voert de nodige handler uit. Tegelijkertijd blijft deze event verder gaan aangezien de inventory een child klasse is van de user klasse. In deze user klasse wordt deze event ook opgevangen en wordt er gecontroleerd wat er met dit specifiek eventobject moet gebeuren. Een tweede manier om een gebeurtenis naar de engine te sturen, is het aanpassen van data die noodzakelijk zijn voor de engine. Een autonome klasse kan de data, die door de game klasse op datzelfde moment wordt gebruikt, aanpassen waardoor de game klasse met nieuwe data zal verder werken. Het is echter ook mogelijk dat een autonome klasse de eigenschappen van een andere klasse gaat aanpassen die door de game klasse gebruikt wordt. (Loose Coupling). Een voorbeeld hiervan is het aanpassen van externe resources zoals de databank, de textures, … of het gebruik van een objectproxy. Behandeling Wanneer een gebeurtenis plaatsgevonden heeft, is het natuurlijk de bedoeling dat deze gebeurtenis wordt omgezet in een actie. Dit gebeurt in de vorm van event handling. Events worden dus via een event listener (5.2.1 Declaratie en initialisatie) verbonden met een handler die het eventobject opvangt en behandelt. In Actionscript 3 krijgt elke eventhandler als parameter het type event mee dat hij behandelt. Dit kan een generisch type zijn zoals het basetype, flash.events.event, maar dit kan ook een specifiek event zijn. Door het gebruik van specifieke events heeft de handler meer mogelijkheden doordat het eventobject een type heeft en bijgevolg beter beschreven is. Eén van de meest voor de hand liggende behandelingen is input. Wanneer de gebruiker via de muis of via het toetsenbord een bepaalde input veroorzaakt is het de bedoeling dat de engine deze herkent en hieraan een actie gaat koppelen. De muis input wordt door Flash standaard ondersteund. Elk displayobject in Actionscript is standaard voorzien van event listeners die naar de nodige events luisteren wanneer een muisactie plaatsvindt. Ook biedt Flash standaard Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
54
een keyboard klasse aan die kan communiceren met hardware en input kan detecteren. Enkel het afhandelen wordt standaard niet geïmplementeerd. Door een event listener op de stage te plaatsen die luistert naar keyboard input kunnen we de input detecteren en doorsturen naar een functie (figuur 46) die deze gaat omzetten naar een actie. Op basis van het KeyBoardEvent object kan de engine via de keycode controleren welke toets werd ingedrukt. Door deze te gaan filteren, koppelt de engine een specifieke actie aan elke toets.
Figuur 46: Keyboard event handler. De handler vangt het event op en ontleedt het eventobject. Op basis van filtering kent de handler een specifieke actie toe.
Een andere belangrijke vorm van behandeling is de reactie van de User Interface op de acties van de gebruiker. Wanneer de gebruiker bepaalde acties uitvoert tijdens het spel worden deze door de game klasse opgevangen en vertaald naar de User Interface. Deze context is een heel ander niveau van behandeling. Als de gebruiker bijvoorbeeld een Worldobject van het type health opraapt treedt een ingewikkeld proces in werking. Allereerst wordt het object herkend door de engine. De engine gaat de functie processItem() raadplegen om te controleren wat er precies met dit object moet gebeuren. Wanneer dit proces doorlopen is, worden twee acties gestart. De eerste actie is het verwijderen van het Worldobject en hertekenen van de tile. De tweede actie is een specifieke actie die verbonden is met het type van het Worldobject, in dit geval health. De engine weet nu dat hij de health van de gebruiker moet updaten en gaat de user klasse aanspreken. In de user klasse wordt de health eigenschap geupdate op basis van de waarden die gedefinieerd zijn in de eigenschappen van het item. Op het moment dat de health eigenschap in de user klasse wordt geupdate, treedt de objectproxy wrapper in de user klasse in werking. Deze herkent een update en dispatcht een event naar de game.as klasse. Deze klasse weet vervolgens, via het eventobject, dat een specifieke user eigenschap werd geupdate. Op dat moment beslist de engine, afhankelijk van het type eigenschap, dat de user Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
55
interface geupdate moet worden. Deze update wordt uitgevoerd en hiermee is het proces afgelopen. Acties Aangezien de engine in staat is events op te vangen (gebeurtenis) en deze ook te verwerken (behandeling) is het essentieel dat hieraan een logische actie wordt gekoppeld. In dit spel zitten een hele reeks acties die samen de gameplay van het spel bepalen. De belangrijkste acties van dit prototype worden dan ook besproken. Eén van de belangrijkste acties is beweging. Zoals vermeld bestaan er in 2D computerspellen twee gangbare manieren om beweging te simuleren, namelijk de speler bewegen of de map bewegen. In dit spel maken we gebruik van de 2de manier. Als eerste stap moet de input van de gebruiker opgevangen worden. Dit gebeurt door middel van een event handler. De engine weet nu wanneer een specifieke toets ingedrukt wordt. Vervolgens stellen de vier variabelen de richting in. Deze worden opnieuw ingesteld elke keer een toets wordt ingedrukt maar ook elke keer een toets wordt losgelaten. Deze manier van werken zorgt voor een flexibelere beweging die wel lineair is maar enorm responsief. De beweging van de speler wordt elke FPS gecontroleerd door een functie movement(). Deze functie controleert of er een toets ingedrukt is en of de engine beweging toelaat. Als de engine bijvoorbeeld in een pauze state zit is beweging niet toegelaten. Indien beweging wel toegelaten is en een toets ingedrukt is die betrekking heeft op beweging roept deze functie de feitelijke beweging op: de move() functie. Deze functie verwacht als parameter een 32 bits integer waarmee de richting aangeduid wordt en een variabele van het type boolean waarmee de Dynamic Tile Swapping functionaliteit wordt toegepast. Allereerst vraagt de functie de collision detection klasse om de nodige berekeningen uit te voeren. De collision detection klasse stuurt de waarden van de tegels die rond het character liggen naar de eigenschappen van het character. De character klasse heeft ook een eigenschap, count, die gebruikt wordt om na te gaan op welke tegel het character zich precies bevindt. Mocht de snelheid van het character, die bepaald wordt door het aantal pixels per beweging, even groot zijn als de grootte van een tile zou deze eigenschap nutteloos zijn. Wanneer dit principe toegepast wordt zijn we zeker dat bij elke beweging het character van tegel verandert, in jargon ook wel tilejump genoemd. Wanneer de snelheid lager is dan de grootte van een tile moet een systeem gebruikt worden dat bijhoudt wanneer de speler van tile verandert. Dit gebeurt in de count eigenschap. Bij elke beweging wordt de count eigenschap verhoogd of verlaagd met de snelheid in pixels. Wanneer deze waarde groter is dan de grootte van een tile of kleiner is dan 0 dan beweegt het character naar een andere tile. Vervolgens gaat de methode nagaan of het character wel in de gevraagde richting kan bewegen. Als dit het geval is wordt de count eigenschap, de speler en de baselayer geüpdate afhankelijk van de richting. Wanneer deze beweging een tilejump veroorzaakt komt het Dynamic Tile Swapping mechanisme in werking. Het Dynamic Tile Swapping (DTS) (figuur 47) mechanisme is een zelf ontworpen mechanisme dat de map in realtime hertekent. Een tilejump wordt veroorzaakt door het character dat van tegel verandert. Als dit gebeurt wordt de baselayer in tegenovergestelde richting verplaatst en het character in de gevraagde richting verplaatst. Hierdoor wordt de illusie van beweging gecreëerd. Door deze manier van bewegen verdwijnt er aan één kant een rij of kolom tegels en moet er aan de tegenovergestelde richting een nieuwe rij of kolom tegels getekend worden (figuur 48).
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
56
Figuur 47: Schematische voorstelling van de werking van het DTS systeem. Dit systeem laat toe om enkel één rij of kolom tiles te verwijderen en één rij of kolom tiles bij te tekenen.
Het DTS systeem verwijdert een rij of kolom tegels die in de tegenovergestelde richting van de beweging staan en tekent een rij of kolom tegels in de richting van de beweging. Ook dit gebeurt met de createTile() functie. Als laatste stap wordt de diepte van het character herberekend. Ook wordt de texture van het character aangepast aan de juiste richting.
Figuur 48: Een onderdeel van de move() functie. Op basis van de richting berekent deze functie de verplaatsing van het object, de map en de viewport. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
57
Een tweede belangrijke actie in de game klasse is het verwerken van worldobjects. Deze worden op de map geplaatst door de tile zelf. De tile heeft een eigenschap oblink waarin de texture van de Worldobject wordt bijgehouden. Wanneer de engine de tile tekent wordt de Worldobject automatisch meegetekend. Dit betekent dat wanneer het character over een object loopt en dit impliciet opraapt, of wanneer de gameplay een Worldobject wil toevoegen aan de map, de oblink eigenschap van de tile veranderd moet worden. Als deze tile dan ook nog zichtbaar is, dient ze in realtime hertekend te worden. Als de tile niet binnen de viewport ligt, kunnen we de matrix gewoon aanpassen waardoor de engine geen verschil merkt. Het oprapen van objecten wordt behandeld door de processItem() klasse. Deze klasse controleert of het type van het opgeraapte item een object is dat hij herkent (figuur 49). Als hij het type herkent, start hij een specifieke actie die voorgedefinieerd is door het item zelf. Nadat deze actie uitgevoerd is wordt de oblink eigenschap leeg gemaakt en wordt de tile hertekend zonder Worldobject met behulp van de replaceTile() methode.
Figuur 49: De processItem() functie controleert het gevonden object en koppelt hieraan een actie.
Het is ook mogelijk dat de gameplay worldobjects wil bij tekenen. In dit geval wordt gecontroleerd of de tile waarop dat Worldobject getekend moet worden binnen de viewport ligt. Indien dit het geval is dan update de gameplay de oblink eigenschap van de tile en gebruikt hij ook de replaceTile() methode om de tegel opnieuw te tekenen. NPC’s zijn objecten of karakters die niet door gebruikers kunnen worden aangestuurd. In deze engine bestaan er 2 soorten NPC‟s : De interactieve NPC en de gewone NPC. Beide NPC varianten zijn kinderen van de NPC base klasse en implementeren dezelfde structuren. Een NPC wordt gedefinieerd door middel van een xml bestand. Dit bestand bevat informatie over de NPC zoals:
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
58
Startpositie De positie waar de NPC spawnt30. Eindpositie (sterfpunt) De positie waar de NPC wordt verwijderd en vernietigd. Path Een reeks coördinaten die de route bepalen die de NPC bewandelt. Tekst De informatie die de NPC aan de gebruiker geeft wanneer er interactie is. Opties De opties die de NPC aan de gebruiker kan geven wanneer er interactie is. Ook de actie die veroorzaakt wordt door deze opties worden hier gedefinieerd
Een NPC is in staat om een bepaalde route te bewandelen. Dit wordt behandeld door de moveNPC() functie die op dezelfde manier werkt als de move() functie die verantwoordelijk is voor de beweging van het character. Ook kan een gebruiker door middel van een trigger met de NPC communiceren. De NPC kan bijvoorbeeld de gebruiker bepaalde opdrachten geven of vitale informatie delen.
Zoals reeds aangehaald, is op de engine een missie systeem gebouwd dat dynamische missies kan laden op basis van xml resources. Deze missies worden gebruikt om de speler doorheen de virtuele campus te leiden. Wanneer de speler een nieuw spel start, wordt de eerste missie geladen. Een missie kan enkel en alleen beginnen wanneer de gebruiker op de juiste manier met het spel communiceert. Een missie kan starten door middel van het oprapen van een Worldobject (impliciet) of door middel van een NPC (expliciet). Deze NPC gaat de gebruiker vragen of hij of zij de missie wilt starten. Indien de gebruiker hier op in gaat, wordt de missie gestart en wordt het eerste objectief op de map geplaatst. Elke missie heeft een willekeurig aantal objectieven die verzameld moeten worden door de gebruiker. Als alle objectieven verzameld zijn, is de missie geslaagd. Als eerste stap in dit proces wordt een Worldobject of NPC op de map geplaatst die verantwoordelijk is voor het starten van de missie. Dit wordt door de initializeMission() functie behandeld. De functie gaat uit het user object het aantal gespeelde missies en objectieven ophalen. Op basis van deze 2 waarden gaat de functie het juiste objectief uit de juiste missie tekenen. Als dit eerste objectief wordt gehaald (startpunt), wordt de engine in een missie state geplaatst waardoor de engine gaat controleren of de gebruiker een objectief heeft verzameld. Deze controle wordt door de doMission() functie uitgevoerd (figuur 50). Deze functie gaat elke frame per seconde na of het character zich op de coördinaten bevindt die overeenkomen met de coördinaten van het actieve objectief. Mocht dit objectief een Worldobject zijn, wordt dit gewoon door de standaardfunctie processItem() behandeld.
30
Spawnen: Verschijnen op de map. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
59
Figuur 50: Een deel van de doMission() functie. Deze functie regelt welk missie met welk objectief aangemaakt moet worden.
Doordat de engine in een missie state zit, gaat deze functie het opgeraapte Worldobject anders behandelen dan wanneer de engine in normale state zou zijn. Deze opgeraapte items worden toegevoegd aan een missie inventory die links bovenaan het scherm terug te vinden is. In het geval dat dit object een NPC is, wordt de interactie tussen de NPC, die de missie representeert, en de gebruiker vanuit het NPC object zelf behandeld. Elke keer als een nieuw objectief gevonden wordt door de gebruiker wordt het user object. Dit proces herhaalt zich tot alle objectieven van één specifieke missie gevonden zijn en de missie geslaagd is.
5.3
RESOURCES
Eerder werd al besproken dat de engine gebruikt maakt van externe data. Deze externe data komt enerzijds uit de mysql databank en anderzijds uit de resource map die voor elke gebruiker is aangemaakt. De data die gecentraliseerd zijn in de databank zijn vooral data die van toepassing zijn op de gegevens van de gebruikers. Er werd gekozen om hiervoor geen xml bestanden te gebruiken maar specifiek een databank model. Dit laat toe om achteraf applicaties te voorzien die rechtstreeks op dit datamodel kunnen gebouwd worden. Gameplay elementen die afhankelijk zijn van de gebruiker worden echter in een persoonlijke map op de server opgeslaan. Door deze data per gebruiker te gaan personaliseren bestaat de mogelijkheid om gameplay elementen op te slaan. In de praktijk betekent dit dat een gebruiker een spel kan verder zetten of opslaan en dat netcode vrij eenvoudig te implementeren is. Naast de data die voorzien wordt in functie van de gebruiker, is er ook data aanwezig op de server die de engine zelf gaat voeden. In deze context spreken we vooral over textures, xml bestanden, muziekbestanden,… Het grote voordeel van het consequent gebruik van externe data is dat het spel, en de engine daarachter, zowel op grafisch vlak als op het vlak van gameplay volledig herbruikbaar is. Het is perfect mogelijk om enkel door xml bestanden, map bestanden en textures aan te passen een volledig nieuw spel te bouwen zonder één regel code te schrijven.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
60
5.4
TOOLKIT
De data die door de engine gebruikt worden moeten een specifieke structuur hebben. Omdat het een vrij ingewikkeld en tijdrovend proces is om testdata in het juiste formaat te krijgen is dan ook besloten om over te gaan tot de ontwikkeling van editors die dit proces aanzienlijk vereenvoudigen. Omdat de map enorm groot kan zijn en enorm veel verschillende tiles kan bevatten is het een bijna onmogelijke taak om een map aan te maken die genoeg variatie kent, groot genoeg is om de tekenprocessen te testen en esthetisch voldoet. Daarom werd beslist om een map editor (figuur 51) te maken. Deze map editor is gebaseerd op de technologie en architectuur van de engine en is volledig in flash geschreven. Ze biedt een intuïtieve interface waarmee in enkele minuten een map gebouwd kan worden. Ook de map editor is volledig gebaseerd op externe data. Zo moet een gebruiker enkel de textures map en het texturelist bestand updaten om een volledig nieuwe tileset te krijgen. Als de map opgeslaan wordt, zet de interne engine de visuele representatie om in een gestructureerd .map bestand. Dit .map bestand kan samen met de textures en texturelist rechtstreeks in de engine geladen worden.
Figuur 51: Schermafdruk van de map editor.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
61
Ook het uitdenken van missies en deze gestructureerd in een xml plaatsen bleek een lastige maar vooral tijdrovende bezigheid. Om de structuur van de xml bestanden te garanderen werd dan ook besloten om een missie editor te maken op basis van het .net framework (figuur 52). Deze editor werkt met een zelfgeschreven xml parser 31 die geoptimaliseerd is voor de missie xml bestanden.
Figuur 52: Schermafdruk van de mission editor.
5.5
ACTIVITEITEN
Gedurende de afgelopen 7 maanden heb ik met 3 collega‟s gewerkt aan dit project. Een echte taakverdeling is er nooit gemaakt en er werd vaak samengewerkt onder het pair programming principe. In hoofdzaak heb ik mij vooral beziggehouden met de core, de architectuur van de engine en de elementaire tekenen- en render systemen. Voor een globale rapportering van mijn wekelijkse activiteiten gedurende de stage verwijs ik graag naar de stageverslagen in de bijlage. ( Bijlage 1 to 6)
31
Parser: Een component van een programma, dat de grammaticale structuur van een invoer volgens een vastgelegde grammatica analyseert en omzet. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
62
6
CONCLUSSIE EN AANBEVELINGEN
“Een software pakket is nooit af”. De laatste versie van de broncode biedt een eerste prototype op basis van een collection engine. Er zijn natuurlijk veel zaken niet geïmplementeerd die wel op het verlanglijstje stonden maar uiteindelijk moeten keuzes gemaakt worden. Onze missie was om op het einde van deze stageperiode een prototype af te leveren die betreffende performance op het zelfde niveau zit als de standaarden van de game industrie. Van in het begin van dit onderzoeksproject zijn er veel problemen geweest. Een eerste belangrijk probleem was de afwezigheid van een grondige kennis van ECMA script en het DOM event model hierachter. Andere problemen waren vooral technisch van aard. Zo kent de Flash runtime environment enorme beperkingen waardoor we verplicht waren terug te grijpen naar oude geheugenbesparende technieken. Ook kent Actionscript 3 zelf veel beperkingen ten op zichte van conventionele programmeertalen waardoor soms actief gewerkt moest worden aan work arrounds. Een ander groot probleem was de sandbox environment van de flash player die het gebruik van hardware niet toelaat waardoor enkel gebruik gemaakt kan worden van de CPU 32 cycles. Het diepteprobleem is het enige probleem dat helaas niet opgelost is geraakt. De conventionele diepte algoritmes zijn te traag om in realtime uit te voeren en door de interne structuur van de displaylist is zelfs het schrijven van een work arround zo goed als onmogelijk. Uiteindelijk is er dan gekozen om een benadering van het diepte systeem te gebruiken maar dit systeem is niet waterdicht. Uiteindelijk is er een prototype afgeleverd dat een basis aanbiedt waarop in de toekomst verder gebouwd kan worden. Dit prototype is gebouwd volgens de OOP pincipes en volledig conform de ECMA voorschriften betreffende het DOM event model. De engine is volledig afhankelijk van externe resources die beheerd kunnen worden door de toolkit. Deze resources zorgen ervoor dat de engine niet alleen flexibel maar ook herbruikbaar is. Adobe heeft laatst een beta versie van Flash player 10 publiek gemaakt. Deze zou in de toekomst GPU 33ondersteuning bieden en dit opent vele deuren voor dit project. Zo zou de rendering volledig door de GPU kunnen behandeld worden waardoor de CPU efficiënter gebruikt kan worden voor berekeningen. Hiermee zou ook impliciet het diepte probleem kunnen opgelost worden. Ook ECMA is momenteel aan het werken aan de opvolger van ECMA script 3, namelijk ECMA script 4. Deze laatste zou nieuwe structuren implementeren zoals generics, methode overloading, record types, nieuwe datatypes,… Tenslotte kan ik enkel besluiten dat de eerste fase van dit onderzoeksproject afgelopen is. Het prototype is operationeel en dit kan nu als een blauwdruk gebruikt worden voor toekomstige versies. De engine zou volledig generisch herschreven kunnen worden en eventueel in de opensource community terecht komen. Verder bieden de nieuwe technologieën van Adobe enorm veel mogelijkheden, die wij helaas niet tot onze beschikking hadden.
32 33
CPU (Central Processing Unit): Centrale verwerkingseenheid van de computer. GPU (Graphics Processing Unit): Processor van de videokaart. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
63
7
BESLUIT
Een stage wordt vaak beschouwd als de laatste stap in het educatief systeem. Aan de hand van een stage tracht een onderwijsinstelling studenten klaar te stomen voor de arbeidsmarkt. Studenten maken kennis met de verschillende aspecten van het bedrijfsleven en leren hoe ze vanuit hun studierichting de overstap moeten maken naar een vaste baan. Door de speciale aard van mijn stage ben ik niet in dit model terecht gekomen. Als stagiair in het Onderzoeksinstituut voor Toegepaste Informatica heb ik wel van een andere kant van de informatica wereld mogen proeven, namelijk onderzoek. Onderzoek en alles wat daar rond zit is natuurlijk een heel ander verhaal dan de stereotype bedrijfsstages. Het geweldige aan onderzoek is dat je op zelfstandige basis iets kan creëren, van niets tot een werkend geheel. Natuurlijk bestaat de mogelijkheid dat een onderzoek door diverse redenen in duigen valt maar net dat maakt het interessant en uitdagend. Het project en de stage die aan dit onderzoek vast hingen, lagen ook volledig binnen mijn interesses, namelijk game ontwikkeling. Ik zag dit onderzoeksproject dan ook enerzijds als echte uitdaging maar anderzijds ook als een aanvulling van mijn kennis. De samenwerking met de stagebegeleider en alle andere mensen van het onderzoekscentrum is uitstekend verlopen. Mijn stagebegeleider heeft ons het vertrouwen en de verantwoordelijkheid gegeven om zelfstandig dit project tot een goed einde te brengen.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
64
REFERENTIES
J. Carmack, ‟Quakecon 2007 keynote‟, http://www.quakecon.org/ G. Grossman, E Huang, „Actionscript 3 overview‟, http://www.adobe.com/devnet/actionscript/articles/actionscript3_overview.html Kirupa, „Isometric movement‟, http://www.kirupa.com/developer/isometric/key_movement.htm M. Lamont (university Kentucky), „Bubble sorting‟, http://linux.wku.edu/~lamonml/algor T. PA, „Tile Based games‟, http://www.tonypa.pri.ee/tbw/start.html K. Patch, „Web game reveals market sense‟, http://www.trnmag.com F VanGeirt, „Hoofdgame draaiboek‟, 2008 W3C, „Document object model events‟, http://www.w3.org/TR/DOM-Level-2Events/events.html#Events-flow-bubbling J. Weeks, „Matrix math‟, http://www.gamedev.net/reference/articles/article877.asp K. Weick, „The Management of Change among Loosely Coupled Elements‟, 1982 Wikipedia, „Isometric projections‟, http://en.wikipedia.org/wiki/Isometric_projection
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
65
BIJLAGEN 1. 2. 3. 4. 5. 6. 7.
Stageverslag 1 Stageverslag 2 Stageverslag 3 Stageverslag 4 Stageverslag 5 Stageverslag 6 CDPHL
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
66
BIJLAGE 1
ACTIVITEITENVERSLAG 1 In opdracht van het TINFO onderzoekscentrum werk ik binnen deze stage aan een 2D Isometrische game engine die als platform dient voor de PHL webgame. Deze stage is dus vooral bedoeld als onderzoek naar de grenzen en de mogelijkheden van Flash Actionscript 3 en game architecturen. Tijdens de projectperiode is er al gewerkt aan de core en content engine en het is de bedoeling aan het eind van deze stage een speelbare demo te hebben. Ik heb deze afgelopen 2 weken volgens het principe van „Extreme programming‟ samengewerkt met mijn collega Désiré Jooken. OVERZICHT WERKZAAMHEDEN Werkzaamheden Architectuur
Rendering
Dynamic tile swapping mechanisme
Depth
.Net Wrapper
Omschrijving De originele architectuur is herbedacht en wordt herschreven. De oorspronkelijke architectuur is door de eigenschappen van de Actionscript (ECMA) compiler niet mogelijk. De render/draw klasse is herschreven op basis van Isometrische algoritmes. Ze voorziet ook de rendering van zowel 2D als Isometrische 2D (2,5D). Deze klasse tekent de initiële map en zorgt ook voor de realtime rendering van het spel. Op basis van het line clipping principe is dit Dynamic tile swapping mechanisme herschreven maar momenteel is dit systeem stabiel maar nog niet efficiënt genoeg. Dit systeem is een onderdeel van de render klasse en zorgt voor het bijtekenen en verwijderen van tegels op basis van de viewport waarden. De diepteberekening is herschreven volgens het Z-sorting algoritme. Dit systeem zorgt voor de 3D suggestie en wordt in realtime herberekend op basis van de positie van de speler. Opmaken van een .Net (C#) wrapper klasse in XML standaarden voor uitwisseling met de flash backbone. Deze klasse zal later uitgebreid worden als render backbone voor de algoritmische berekeningen om zo de client applicatie zo weinig mogelijk geheugen te laten gebruiken.
OVERZICHT PROBLEMEN Problemen Benchmark Flash
Input
Omschrijving De 4 versies van de engine zijn uitvoerig getest op performance. De statistieken tonen aan dat 3 van de 4 versies ondermaats presteren. Door de beperkingen van de Flash Sandbox kunnen we geen hardware resources aanspreken, uitgezonderd de CPU, waardoor we via programmeertechnieken geheugen moeten sparen. De inputklasse werkt onjuist en moet herzien worden.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
67
VERDER VERLOOP
In de komende 2 weken is het de bedoeling de core engine volledig af te werken om dan te kunnen beginnen aan de implementatie van de Content engine (zie mijn 2 collega‟s). Na dit proces zou de bouw van het spel kunnen starten. BESLUIT
Door de aard van de stage, namelijk onderzoek, en de vrijheid die ik van Mr. Van Geirt krijg heb ik de mogelijkheid om te experimenteren met verschillende game architecturen en programmeertechnieken. Dit alles wordt wel uitvoerig gedocumenteerd en zal uiteindelijk in het stageverslag worden opgenomen. Verder is het gebruik van de „Extreme programming‟ techniek zeer efficiënt en werken we toch een sneller workflow dan wanneer we individueel programmeren.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
68
BIJLAGE 2
ACTIVITEITENVERSLAG 2 De afgelopen 2 weken is er verder gewerkt aan de core van de engine zodat in de loop van de volgende weken gestart kan worden met de bouw van het spel zelf. OVERZICHT WERKZAAMHEDEN Werkzaamheden Architectuur Rendering
UI Minimap
Geluid World Objects
Omschrijving De architectuur is voor de laatste keer volledig herschreven met het oog op herbruikbaarheid, flexibiliteit en snelheid. De core render klasse is herschreven naar een enkele super klasse die instaat voor de visuele rendering. Enkel deze klasse kan en mag toegang hebben tot de stage waarop gerendered wordt. De user interface en ook de menu interfaces zijn gebouwd en voor een groot deel geïntegreerd. De minimap wordt in realtime getekend gebaseerd op - en volgens de principes van de game core zelf. Helaas kan de minimap niet getoond worden in de interface vanwege performance problemen. Een sound klasse werd toegevoegd aan de core zodat synchroon of asynchroon geluid kan toegevoegd worden aan het spel. Interactiviteit met de speler die de mogelijkheid heeft om game objecten op te rapen en deze in een inventory bij te houden voor gebruik. Ook de worldobjecten worden getekend op basis van matrixwaarden.
OVERZICHT PROBLEMEN Problemen Depth Flash
Actionscript 3
Omschrijving Het depthalgoritme is onjuist en moet herzien worden. Door de beperkingen van de Flash Sandbox kunnen we geen hardware resources aanspreken, uitgezonderd de CPU, waardoor we via programmeertechnieken geheugen moeten sparen. De afwezigheid van constructor overloading in Actionscript 3 zorgt voor een dalend flexibiliteit van de broncode.
VERDER VERLOOP
Als alles volgens planning verloopt is het de bedoeling om vanaf volgend week te starten met de ontwikkeling van het spel zelf. Dit zal gebeuren volgens het draaiboek van Mr. Van Geirt. Ook wordt verwacht dat de graphics, geleverd door departement Beeldende kunst, volgende week opgeleverd worden.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
69
BESLUIT
Op enkele kleine technische problemen na is de engine klaar voor de ontwikkeling van een spel. Verwacht wordt dat deze technische problemen in de volgend week zullen opgelost worden om zo de core zo goed als bugvrij te houden.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
70
BIJLAGE 3
ACTIVITEITENVERSLAG 3 De afgelopen 3 weken is er verder gewerkt aan enkele core componenten en aan enkele basis gameplay objecten. OVERZICHT WERKZAAMHEDEN
Werkzaamheden Architectuur
User Inventory
Minimap
Geluid OOP
Omschrijving Verschillende base klassen, zoals de render klasse en de alphamanager, zijn verwijderd en vervangen door ingebouwde klassen. Dit heeft als resultaat de refresh rate van de engine stabieler is De user klasse is herschreven en is nu een centaal data object die de game klas voedt. De inventory klasse is een subklasse van de user geworden en wordt ook als dusdanig benaderd. De user klasse biedt de nodige eigenschappen aan zodat de inventory klasse deels beschikbaar is door de user klasse. Het systeem dat de minimap update en tekent is volledig herzien. De minimap wordt niet meer in realtime getekend maar wordt enkel hertekend bij het oproepen. Dit zorgt voor een stabielere framerate en een snellere performance. De geluidsklasse is geoptimaliseerd voor een samenwerking met een statische Sounds klasse. Alle core en game klassen zijn herbekeken en herschreven volgens OOP principes. Zo werden polymorfismen, encapsulatie en overerving geïntegreerd.
OVERZICHT PROBLEMEN
Problemen Depth Events Actionscript 3
Omschrijving Het depth algoritme is nog steeds onjuist. De OOP hiërarchie zorgt soms voor een overkill aan events. De afwezigheid van constructor overloading in Actionscript 3 zorgt voor een dalend flexibiliteit van de broncode aangezien verschillende functies moeten voorzien worden voor eenzelfde functionaliteit
VERDER VERLOOP
De graphics die aangeleverd worden door het departement Kunst laten nog steeds op zich wachten waardoor we nog steeds geen render controles hebben kunnen uitvoeren. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
71
Ook de animaties en interfaces die door het departement Kunst zouden worden aangeleverd lijken niet beschikbaar voor de deadline. Verder zijn mijn collega‟s begonnen met de integratie van geautomatiseerde missies op basis van xml. BESLUIT De meeste technische problemen (op de depth - algoritmes na) zijn opgelost en er wordt nu volop gewerkt aan de aflevering van een speelbaar spel.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
72
BIJLAGE 4
ACTIVITEITENVERSLAG 4 De afgelopen 2 weken is er gewerkt aan de implementatie van de gameplay. OVERZICHT WERKZAAMHEDEN Werkzaamheden Missions
Gebruiker UI Optimalisatie
NPC World Objects
Omschrijving Een flexibel mission systeem op basis van xml data. Dit systeem is voorzien van een editor om op snelle wijze veel missies te kunnen aanmaken. Een Multi gebruiker omgeving waarin data gesaved kan worden per gebruiker. De user interface en ook de menu interfaces zijn gebouwd en voor een groot deel geïntegreerd. De core broncode is geoptimaliseerd voor sneller framerate door het opschonen van de code en het gebruik van minder geheugen belastende structuren De npc klasse is uitgebreid met een interactieve NPC die gebruikt kan worden in de missie context. De interactiviteit met de worldobjects versus de gebruiker eigenschappen is grotendeels uitgewerkt. (score/health/levens/…)
OVERZICHT PROBLEMEN Problemen Depth Graphics
Omschrijving Het depthalgoritme is nog steeds onjuist en moet herzien worden. Er zijn nog steeds geen bruikbare graphics aangeleverd waardoor het render systeem nog steeds geen valabele tests heeft kunnen ondergaan.
VERDER VERLOOP
Momenteel zitten we achter op schema door de afwezigheid van graphics. Hierdoor gaan de vooropgestelde doelstelling ongetwijfeld moeilijk of zelfs niet haalbaar zijn. De volgende weken gaat er verder gewerkt worden aan het Multi-gebruikers systeem, het missionsysteem en de User Interface.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
73
BESLUIT
De meeste technische bugs zijn ondertussen verholpen (met uitzondering van de depth). De eerste gameplay elementen zijn met succes geïmplementeerd. Het is nu enkel wachten op de graphics om de visuele kant van de game te kunnen inkleuren want een game is maar zo goed als zijn graphics of gameplay.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
74
BIJLAGE 5
ACTIVITEITENVERSLAG 5 De afgelopen twee weken is er vooral gewerkt aan de User Interface en de laatste gameplay systemen. OVERZICHT WERKZAAMHEDEN Werkzaamheden Architectuur UI
Handleiding Geluid Code optimalisatie
Omschrijving 2 generic type safe collection klassen zijn toegevoegd als aanvulling op eerdere collecties. De nieuwe user interface, aangeleverd door onze collega‟s van het departement beeldende kunst, zijn aangepast en geïntegreerd in de engine. Sommige onderdelen zijn door het ontbreken van vitale componenten nog niet functioneel maar wel al visueel geïntegreerd. De handleiding (in HTML formaat) voor de core is volledig in orde. Op basis van de bestaande sound klasse is een mp3 speler geïmplementeerd die verschillende kanalen en liedjes bevat. De volledige broncode is nagezien op onjuistheden, omslachtige denkpistes en formaat. De broncode is verder ook volledige geoptimaliseerd voor flash player 9.
OVERZICHT PROBLEMEN Problemen Depth
Graphics
Preloader
Omschrijving Het depthalgoritme is nog steeds onjuist. Dit probleem werd uitgebreid besproken in de opensource communities die flash Actionscript rijk is maar ook daar moesten ze ons het antwoord schuldig blijven. Opnieuw zijn er weinig tot geen graphics opgeleverd. De weinige graphics die wel opgeleverd werden waren jammer genoeg weer in een verkeerde resolutie en in een foute hoek uitgeknipt. Door het ontbreken van deze graphics kan er helaas niet verder gewerkt worden aan de gameplay. Door de structuur van de engine kan deze niet worden gepreload door een externe swf.
VERDER VERLOOP
In de komende weken gaat er verder gewerkt moeten worden aan de handleiding van het spel zelf zodat hier later sneller op ontwikkeld kan worden. Ook gaan er mogelijk nog graphics opgeleverd worden die dan verwerkt moeten worden in de engine. Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
75
BESLUIT
De engine is volledig klaar voor verder ontwikkeling. De meeste bugs zijn eruit gehaald en de gameplay aspecten zijn geïmplementeerd.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
76
BIJLAGE 6
ACTIVITEITENVERSLAG 6 De afgelopen twee weken werd er volop gewerkt aan het afleveren van een speelbaar prototype op basis van de zelfgeschreven engine. Dit houdt in dat de hoofdbezigheid de laatste 2 weken vooral lag in het testen van de software. OVERZICHT WERKZAAMHEDEN Werkzaamheden Debug
UI
Handleiding
Omschrijving De engine en het prototype van het spel werden onderworpen aan een uitgebreide test. Hierdoor werden nog enkel structurele bugs gevonden die volledig opgelost zijn. Het menu, dat aangeleverd werd door de collega‟s van beeldende kunst, is volledige operationeel. Enkel de mogelijkheid om een karakter te kiezen is nog niet volledig geïmplementeerd aangezien de graphics die dit zouden moeten ondersteunen ontbreken. De handleiding (in HTML formaat) voor de core is volledig in orde. Deze handleiding is bedoeld als blauwprint voor latere documentatie wanneer de engine uitgebreid zou worden.
OVERZICHT PROBLEMEN Problemen Depth Graphics Preloader
Omschrijving Het depthalgoritme is nog steeds onjuist. Tijdens de stage werd geen valabele oplossing gevonden. De engine is in grote lijnen klaar maar door de afwezigheid van graphics is er geen consequent gebruik van stijl. Door de structuur van de engine kan deze nog steeds niet worden gepreload door een externe swf. Ook voor dit probleem werd geen oplossing gevonden.
BESLUIT
Het project is ondertussen afgelopen en er is een prototype van het spel beschikbaar dat een duidelijk beeld schetst van de mogelijkheden die de engine nu kent maar ook de mogelijkheden die in de toekomst nog verder uitgewerkt kunnen worden. De engine op zicht is vrij generisch geschreven maar is nog steeds verre van afgewerkt. Verschillende game structuren zouden in de toekomst verplaatst moeten worden naar de core en generisch herschreven moeten worden.
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
77
BIJLAGE 7
Deze cd bevat volgende digitale bijlagen:
Abstract Stagerapport Draaiboek Broncode Html documentatie van de engine
Steven Houben - Onderzoek naar en ontwikkeling van een 2D webgame: Phl Adventure
78