Studerende

Lav spil med HTML5

Der er begyndt at dukke en masse spil op baseret på HTML5.

Her er en introduktion til, hvordan du kan lave dine egne.

På det seneste er der dukket en masse spil og game engines op, der er baseret på HTML5. Det lækre ved at lave spil med HTML5 er, at de er umiddelbart tilgængelige i spillerens browser og derfor fungerer (stort set) ens på alle platforme, inklusive mobiler og tablets. Derfor er det et oplagt valg, hvis man gerne vil gøre det let for sine spillere at prøve sin kreation og hverken har tænkt sig at lave en version til hver platform eller betale for en licens til en professionel game engine.

Processen
Spiludvikling starter med en idé. Den kan være helt original eller en variation over nogle kendte spil eller genrer. Nu ville det være fristende straks at sætte sig og begynde at kode det. Gør man det, vil der hurtigt dukke ting op, man ikke lige havde overvejet. Det giver lappeløsninger og spildt tid. I stedet kan det anbefales at starte med at lave skitser og teste idéerne løbende med små spilbare prototyper, eksempelvis i form af små brætspil. Når idéen har taget form som noget overskueligt og spilbart, kan det kodes med simpel såkaldt placeholdergrafik, måske bare kasser i forskellige farver. Hvis der er aspekter af spillet, hvor det ikke er lysende klart, hvordan de skal kodes, kan det ofte betale sig at lave en lille, digital prototype af det aspekt. Så kan man lave et lille isoleret program med det. Når man er nået frem til et gameplay, der virker, kan man udskifte placeholdergrafikken med animationer, lyd osv.

Et simpelt spil
For at få en idé om, hvor man kan starte med HTML5, så lad os lave et simpelt spil. Det enkleste, jeg kunne komme på, var ”Pong”. Der er en bold. Der er to bander – en i toppen af skærmen og en i bunden. Der er to padler – en i højre side og en i venstre. De to spillere styrer hver en paddel. Hvis bolden passerer en spillers paddel og ryger ud af skærmen bagved, får modspilleren et point. Bolden gives så op igen midt på banen.

Grafik
Med HTML5 kom et par nye tags til, som gør grafisk spiludvikling muligt. Det måske vigtigste hedder Canvas og giver en tegneflade, som man kan tegne på ved hjælp af JavaScript. Derudover kom der et Audio-tag, så vi kan få lyd på vores spil.
Start med en html-side, med <!doctype html> i toppen, som fortæller browseren, at indholdet er HTML5. Og put en <canvas id=”canvas”> ind på siden.
I JavaScript kan du få en drawing context til din Canvas således:

var canvas, context;
window.onload = function() {
  canvas =  document.getElementById(”canvas”);
  context = canvas.getContext(”2d”);
}

For at skabe illusionen af bevægelse gentegner vi hele skærmen hurtigere, end øjet kan følge med. Helst et helt tal gange 30 gange i sekundet, fordi det er den typiske frekvens for skærme. Det kan JavaScripts asynkrone timerfunktion, setInterval, hjælpe os med. Indsæt følgende i din window.onload-funktion:

var framesPerSecond = 60;
setInterval(render, 1000/framesPerSecod);

Her er render en funktion, som tager sig af at slette indholdet af skærmen og tegne alle spilobjekter. Dem er der tre af, en bold og to padler.

var ballPosition = [100, 100];
var leftPaddle = 50, rightPaddle = 50;

function render() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.fillRect(ballPosition[0],ballPosition[1],10, 10);
  context.fillRect(30, leftPaddle, 30, 100);
  context.fillRect(canvas.width-60, rightPaddle, 30, 100);
}

Ja. Bolden er en kasse. Det skyldes udelukkende, at der ikke er en enkelt kommando til at tegne en cirkel, samt den begrænsede spalteplads her. Kig f.eks. på html5canvastutorials.com for alt om at tegne med Canvas.

Animation og kollision
Nu vil vi godt have bolden til at flyve rundt efter reglerne i ”Pong”. Vi kunne begynde at skrive videre på vores render-funktion, men ofte er det en god idé at have rendering og spil-logik i to adskilte loops. Så kan man justere spillets hastighed og framerate (billeder per sekund) uafhængigt af hinanden. Så tilføj rask til window.onload:

var updatesPerSecond = 60;
setInterval(update, 1000/updatesPerSecod);

Idéen er at give bolden en hastighed. I hvert update lægges hastigheden til boldens position. Hvis bolden støder ind i top, bund eller en paddel, vender vi retningen af den komponent af hastigheden, der er vinkelret på forhindringen. Ryger bolden ud i en side, scorer modparten et point. Lad os give venstre spiller nr. 0 og højre nr. 1.

var ballVelocity = [1, 1];

function update() {
  //rammer bolden venstre paddel, så send den mod højre
  if(ballPosition[0] < 60 && ballPosition[0] > 30 &&
     ballPosition[1] < leftPaddle+100 && ballPosition[1] > leftPaddle) {
    ballVelocity[0] = 1;
  }

  //ryger bolden ud til venstre, så scorer højre spiller.
  if(ballPosition[0] < 0) scoreGoal(1);

  //læg hastigheden til positionen i begge retninger
  for(var i=0; i<2; i++)
    ballPosition[i] += ballVelocity[i];
}

Du må selv udfylde hullerne for højre paddel, top, bund og når højre spiller scorer. I scoreGoal kan du give den heldige spiller point, evt. vise dem i en tekstboks, og give bolden op ved at flytte den ind i midten igen.

Input
Nu bliver spil, der spiller sig selv, ofte kedsommelige i længden. Lad os styre den ene paddel med mus eller touch, afhængig af om vi er på en pc eller mobil/tablet. Tilføj følgende til window.onload:

context.canvas.onmousemove = move;
context.canvas.addEventListener(’touchmove’, move, false);

Derefter kan vi definere funktionen move, som placerer padlen i samme højde som musen:

function move(event) {
  rightPaddle = event.pageY - canvas.offsetTop - 50;
}

Du kan få lidt modstand ved at tilføje følgende til update:

var sign = function(n) { return n >= 0 ? 1 : -1 }
leftPaddle += sign(ballPosition[1] - 50 - leftPaddle)*0.5;

God fornøjelse.