Min orlov går på hæld. Jeg har haft fri siden slutningen af november, men på mandag er jeg tilbage på pinden. Med så mange ugers fritid, og skulle man tro, at jeg ville have tid nok til at skrive et par indlæg, men tiden er gået med husprojekter, hygge med ungerne, to gange skoldkopper samt jul og nytår, så det er ikke blevet til særlig meget. Mine tekniske stunder de seneste uger har været få, og det er lang tid siden, jeg har haft gang i WinDbg.
Jeg har dog fået ny bærbar, en Dell Studio 15 med i7 CPU, hvilket får Process Explorer til at vise ikke mindre end otte kerner! Det, synes jeg stadig, er ret cool. Desværre er DDR3 RAM stadig ufattelig kostbar, så jeg nøjes indtil videre med 4 GB, men med 64 bit Windows 7 installeret er jeg klar til at opgradere, når prisen per GB ikke længere konkurrerer med prisen på Beluga kaviar.
Derudover har jeg fået læst Chris Smiths glimrende Programming F#. Der er meget at holde af ved F#: Kompakt syntaks, immutable variable som standard, fantastisk model for asynkron programmering, typer med enheder, glimrende udviklingsmiljø og let integration til andre .NET sprog.
Sidst men ikke mindst fik jeg lavet mit andet Xbox-spil til min søn, Asbjørn, og det vil jeg bruge dette indlæg på at dele med jer.
Rammerne for spillet
Jeg vidste, at jeg ikke havde tid til det helt store, så jeg satte en deadline for projektet på otte timer. På otte timer skulle jeg lave det hele: Grafik, lyd, kode og test. Det vil med andre ord sige, at vi på spilskalaen befinder os meget tættere på gamle bip-bip-spil end på nyeste inkarnation af Call of Duty. Jeg er sikker på, at de til sidstnævnte har brugt mere end otte timer på blot at lave teksturer til vægge.
Hvis man kan leve med det begrænsede ambitionsniveau, er det glade budskab til gengæld, at man faktisk snildt kan lave noget på blot otte timer.
Fra mit første forsøg med at lave et spil til Asbjørn vidste jeg, at det skulle være simpelt. Meget simpelt. En Xbox-kontroller er stor og har mange knapper, og når man blot er to år, er der grænser for hvor meget, man kan på en gang. Ergo skal styringen være ukompliceret. Ligeledes må der heller ikke foregå for meget på en gang, så jeg endte med et ”fang de æbler, der falder ned fra himlen”-spil. Den slags var sjovt i de tidlige 80ere, så mon ikke jeg kunne underholde en toårig for en stund.

Indhold
Min søns yndlingsbamse er en Ugly Doll, som han af uvisse årsager har døbt Bambum. En oplagt kandidat til spillets hovedperson, så Bambum blev fotograferet og fritlagt i Photoshop. Jeg klippede derefter ben og ører af det stakkels tøjdyr og med de afklippede dele samt en nytegnet mund, kunne jeg lave et par simple animationer.
Derefter skulle jeg bruge en baggrund. Det var let. En blå gradient og lidt græs. Voila. Dertil kom et lille skilt til at vise point samt cifrene 0-9 i løs vægt.
Skyerne var lidt mere tricky. Jeg tegnede to skyer i Photoshop og endte med at kode min egen fattigmands partikeleffekt. Det vil sige, at jeg tager et par bitmaps og manipulerer dem, mens jeg tegner dem. Det giver en glimrende ”skyer, der driver hen over himlen”-effekt.
Sidst men ikke mindst skulle jeg have et æble, så Google, fritlæg, reducer størrelse og få minutter senere var det på plads. Alt i alt endte jeg med 21 grafikfiler.
Lydene var ligeledes lige ud ad landevejen: Windows Recorder og en mikrofon. Tre variationer over ”ups!” samt tre glædesudbrud, og så var den næsten i hus. Desværre optager Windows Recorder i WMA og XNA kræver WAV, så Google måtte igen komme til undsætning med en Free WMA Converter.
Og så skulle der kodes.
Forudsætninger
For at bruge XNA, skal man installere XNA Game Studio, som er en gratis udvidelse til Visual Studio. Hvis man kan klare sig med kun at lave Windows-spil, er der ikke brug for mere. Til Xbox 360-spil kræves desuden et komponent på Xboxen. Det kan også hentes gratis, men desværre skal man derudover have en Creator’s Club Premium-licens for at kunne overføre spil til konsollen.
Den koster ca. $100 per år, og det er i mine øjne en stupid ide at tage penge for den slags. Bevares, der følger også adgang til diverse ressourcer og mulighed for at uploade sine spil til Microsofts XNA community, så andre kan prøve det. Jeg kan til nøds forstå, hvorfor de vil have penge for rettigheden til at uploade til Arcade, men det er bare fjollet, at sætte den slags forhindringer for at folk kan lege med teknologien.
Når man så har betalt og bandet over det, går alting som en leg. Forbind Visual Studio til Xboxen via lokalnettet og kør og debug kode direkte. Det bliver ikke meget lettere. Jeg vil dog anbefale, at undgå Xboxens ustabile, trådløse netværk. Ikke alene giver det diverse problemer under udviklingen, men fordi Microsoft partout vil verificere, at man har føromtalte licens, kræver afvikling af spillet også konstant adgang til Xbox Live, hvilket bare ikke fungerer særlig godt med deres trådløse net. På et kablet net spiller det bare.
Kode
XNA kommer med en lang række brugbare typer. Game-klasse har som standard sat de væsentligste elementer op. Der er metoder til indlæsning af resourcer, opdatering af tilstand og tegning af skærmen. Det eneste, man skal gøre, er således at fylde metoderne ud efter behov. Det kræver ikke særlig meget kode, at lave mit lille spil, men der er et par elementer, der tåler kommentarer.
Når man tegner billeder på skærmen, skal man angive billedets centrum. For baggrundsbilleder og andre elementer, der ikke skal manipuleres, kan man blot bruge den simpleste overload af Draw-metoden. Den benytter øverste venstre hjørne af billedet som omdrejningspunkt. Billeder, der skal roteres, skaleres eller på anden måde manipuleres, er ofte bedre tjent med at have centrum i billedets centrum. Ved at sætte centrum på Bambum-billedet kan jeg således let skabe illusionen af bevægelse ved simpelthen at dreje billedet en anelse i flyveretningen. Den slags muligheder sparer en for at skulle lave en del bitmaps.
Desværre er der ingen direkte værktøjer i XNA til registrering af kollisioner, så det er man nødt til at kode selv. Der er masser indlæg på nettet om hvordan dette kan gøres, men jeg valgte en quick’n’dirty-løsning. Jeg udregner blot længden for en vektor mellem Bambums centrum og ditto for hvert æble. To grænseværdier afgør hvorvidt Bambum åbner munden for at spise et æble, og om han faktisk har spist æblet. Det er ikke så nøjagtig som det kunne være, men i praksis fungerer det fint, og det var let at implementere.
For at mindske udviklingstiden er det lettest at udvikle til Windows og så lave et Xbox-projekt, når man har noget, der fungerer. Sidstnævnte klarer XNA Studio for en, men følger man den strategi, er der et par udfordringer med at håndtere input. Hvis man ikke lige har en kontroller på sin PC, kommer man til at skrive kode, der kan håndtere input fra både keyboard og Xboxens controller. Det er lidt trælst, og det er ikke helt nemt at få de to til at opføre sig nogenlunde konsistent, så det kræver som regel lige et par forsøg.
Hvorfor 2D?
Med en samlet udviklingstid på blot otte timer er 2D-spil et indlysende valg, men selv hvis man har mere tid til rådighed, er det et godt valg for hobbyprojekter. Logistikken i 2D-spil er ret overskuelig. De kræver kun en samling bitmaps. De kan findes på nettet eller produceres uden de store sværdslag i et væld af programmer. Jeg brugte Photoshop, men mindre kostbare applikationer kan klare opgaven lige så godt. Flere indiespil har tilmed med stor succes brugt håndtegnede figurer og baggrunde. Der er altså mange muligheder, og forhindringerne er overkommelige.
Går man fra 2D til 3D, ændrer forudsætningerne for spillet sig radikalt. Der er stadig brug for et væld af bitmaps til teksturer, men derudover skal man kunne frembringe 3D-modeller. Det er langt mere omstændeligt end at lave bitmaps og værktøjskassen bliver mange gange mere kompliceret og kostbar. De nødvendige applikationer koster i de fleste tilfælde en formue, og indlæringskurven for eksempelvis 3D Studio Max eller Maya er lang og stejl sammenlignet med, hvad der skal til for at komme i gang med XNA.
Holder man sig til 2D, er det en overkommelig opgave, at lave alle elementerne selv.
Indtryk
Jeg vil ikke prale af koden til mit spil. Jeg har taget en del smutveje, og jeg ved, at det kan laves pænere og mere vedligeholdelsesvenligt. Min eneste undskyldning er, at hverken jeg eller andre skal arbejde videre med koden. Desværre er jeg langt fra den eneste, der koder XNA på den måde. En overvejende del af de eksempler, jeg har set, har desværre været udført forfærdelig rodet.
Heldigvis synes selve XNA framework-koden at være skruet væsentlig mere elegant sammen, men da dokumentationen endnu er ret sparsom, ender man ofte med at sidde og læse andres sla^h^h^hikke så pæne kode.
Selv med disse forbehold in mente, må jeg indrømme, at jeg er ret begejstret for XNA. Der er enkelte elementer, jeg gerne så udvidet og forbedret, men det ændrer ikke ved, at det overordnede indtryk er rigtig godt. Det er utrolig let at komme i gang med, og man kan hurtig få skabt synlige resultater. Sidstnævnte finder jeg særdeles motiverende. Det er let at afprøve ideer, så ofte sidder man bare og leger sig frem til nye features og ideer. Der går meget hurtigt, ”jeg skal liiiige” i den, og inden man får set sig om, er klokken blevet alt for mange.
Prøv det. Man behøver ikke engang at have børn for at synes, at det er sjovt.








