Programmering är roligt!

Mikael skriver om programmering, systemadministration och mycket annat!

Kolla in min bok: Spelprogrammering med HTML5 och JavaScript

Kategorier 

2013-09-14
CodeMirror

Idag har jag suttit och programmerat en del JavaScript, och då använt CodeMirror: Ett färdigt bibliotek som gör att man kan få en komplett editor på sin vanliga hemsida. Projektet som jag jobbat med ska ha en sådan, och därför kändes det naturligt att använda Codemirror.

Jag måste säga att CodeMirror är ett riktigt bra OpenSource-projekt som verkligen fungerar bra! Det är superenkelt att komma igång, och det finns massvis att features som man kan använda. Efter ett tag känns det verkligen som att man har en riktigt kod-editor inne på sin hemsida.

På spelprogrammeringslaboratoriet: www.spelprogrammering.nu/koda använder jag CodeMirror, och i det nya projektet som jag ska ha tillsammans med Internetfonden så blir det också CodeMirror. Detta kommer jag återkomma till flera gånger på bloggen, så att ni alla kan få följa hur arbetet fortskrider! Vi har redan startat lite med projektet, och det känns verkligen jättebra!

Maila din kommentar till mikael@tylmad.com, så lägger jag in den under inlägget.
2013-09-01
Ormar, tentakler och atan2

Vad är den gemensamma faktorn mellan ormar, tentakler och atan2? För att förklara detta ska jag först berätta lite om tangens, och om ett litet problem som programmerare ibland stöter på.

Lite matematik: Tangens för en vinkel är kvoten av motstående och närliggande katet i en rätvinklig triangel. Alltså, om du har följande triangel:

...så är tangens för vinkeln A = a/b. Om man är ute efter att räkna ut vinkeln, och känner till både a och b, kan man använda sig av inversen av tangens, som också kallas för arcus tangens. Arcus tangens av a/b blir vinkeln A.

Antag nu att vi har punkten (1, 1) på ett koordinatsystem och vill ta reda på vinkeln från x-axeln till denna.

På de flesta lite mer avancerade miniräknarna, eller i nästan alla programmeringsspråk, kan man nu använda funktionen atan, och skicka med kvoten y/x till denna. 1/1 = 1, och atan(1) = 0.79 rad = 45 grader. Vad händer nu om vi har punkten (-1, -1) och vill göra samma sak?

Problemet är att -1/-1 = 1, och atan kommer säga att vinkeln är 45 grader igen, men vi vet att vinkeln är mycket större (närmare bestämt 225 grader, eller -135 grader om man går medurs från x-axeln). Lösningen på detta kan vara att man inspekterar sidorna noga innan man använder atan, och i förväg bestämmer vilken kvadrant den resulterande vinkeln kommer befinna sig i, men detta kan vara bökigt och det är lätt att det smyger in fel om man inte tänker efter.

Nu kommer funktionen atan2 till användning! De flesta programmeringsspråk innehåller atan2, och den anropas alltid med två argument: Först y-koordinaten och sedan x-koordinaten. Funktionen inspekterar koordinaterna åt dig, och returnerar den korrekta vinkeln. Om punkten ligger ovanför x-axeln blir vinkeln positiv, annars blir den negativ. Det ovanstående problemet blir nu löst eftersom atan2(-1, -1) = -2,36 rad = -135 grader.

Med atan2 blir det enkelt att göra exempelvis en orm och en tentakel som följer muspekaren! Båda är roliga exempel på när matematik kan åstadkomma häftiga realistiska effekter!

Maila din kommentar till mikael@tylmad.com, så lägger jag in den under inlägget.
2013-05-08
Kardioider och nefroider

Kardioider och nefroider är spännande former som man skapar på ett relativt enkelt sätt. Båda bygger på samma princip: Man har en cirkel och låter en annan cirkel rulla runt. På kanten på cirkeln som rullar sätter man fast en penna. Om den rullande cirkeln är lika stor som cirkeln i mitten kommer pennan att rita en kardioid. Om den rullande cirkeln har hälften så stor radie så kommer pennan rita en nefroid. På wikipedia kan man hitta denna förklarande bild:

Här ser man tydligt hur den snurrande cirkeln ritar upp en kurva, som till slut blir en komplett nefroid. En kardioid blir mer som ett hjärta, vilket förklarar namnet (efter grekiskans καρδία, vilket betyder hjärta).

Det går också att bygga kardioider och nefroider genom att rita många cirklar efter varandra, och det visar sig att detta är ett ypperligt tillfälle att använda polära koordinater. Jag demonstrera först hur man kan göra nefroider:

Vi börjar med att tänka oss ett antal polära koordinater som tillsammans bildar en cirkel:

För varje polär koordinat ritar vi nu en cirkel, vars mittpunkt befinner sig på koordinaten, och vars radie sträcker sig till x-axeln.

Det blir en del cirklar. Notera nu hur utkanten av hela denna figur blivit en nefroid. Det blir ännu tydligare om vi tar bort axlarna och ökar antalet cirklar.

För att skapa en kardioid följer vi en likartad metod. Vi börjar ännu en gång med ett antal polära koordinater som tilsammans bildar en cirkel:

Nu ska vi än en gång rita en cirkel för varje koordinat. Denna gång ska dock koordinaten vara på cirkelns rand, och cirkeln ska positioneras mitt emellan koordinaten och den allra första koordinaten. För att tydliggöra detta visar jag nedan hur det ser ut med fyra koordinater, som är längre från varandra:

Den allra första punken ligger på (2, 0) och syns inte i bilden ovan. Du kan dock ana att de tre följande punkterna alla har samma avstånd till origo, och således följer en cirkel. Om vi nu fortsätter hela vägen runt får vi följande resultat:

Att utkanten på denna figur är en kardioid blir tydligare när vi tar bort axlarna och ritar ännu fler cirklar.

Alla bilder i detta inlägg har jag skapat med väldigt lite JavaScript-kod. Nefroiden kan man exempelvis bygga på detta sätt:

<script src="http://spelprogrammering.nu/simple.js">

  function start()
  {
    var r = 1;
   
    for (var v = pi/50; v<2*pi; v += (pi/50))
    {
      var y      = r*sin(v);
      var radius = abs(y);

      math.polarRing(v, r, radius);       
    }
  }

</script>

Det är bara att ta ovanstående kod, spara den som en .html fil och köra igång den i webbläsaren. Kardioiden gjorde jag en lite längre lösning på, men fortfarande relativt lite kod:

<script src="http://spelprogrammering.nu/simple.js">

  function start()
  {
    var r = 2;
    var step = pi/20;
    p0 = {x: r, y: 0};
    
    for (var v = step; v<(2*pi); v += step)
    {
      var x = r*Math.cos(v);
      var y = r*Math.sin(v);
      
      var radius = distance(p0.x, p0.y, x, y)/2;
      
      var l = sqrt(r*r - radius * radius);
      
      var angle = v / 2;
      if (v > pi)
        l = -l;
      
      math.polarRing(angle, l, radius);
    }
  }

</script>

Kardioider och nefroider kan man hitta lite varstans i vår värld, jag rekommenderar wikipedia-artiklarna som kvällslektyr. För gymnasieelever kan detta också fungera som en övning i både matematik och programmering. Som avslutning får ni här en färglagd kardioid:

Maila din kommentar till mikael@tylmad.com, så lägger jag in den under inlägget.
2013-04-09
Skapa online-pussel med jQuery

JavaScript-biblioteket jQuery lämpar sig utmärkt om man snabbt vill göra ett peka-och-klicka spel. Jag gav några elever uppdraget att skapa online-spel för små barn, och första idén blev att göra pussel.

Steg ett var att för hand rita de motiv som pusslen ska baseras på. Ett av dessa pussel skulle bli en vacker solnedgång, och resultatet blev (efter att ha skannats) följande:

Vi laddade sedan in bilderna i en dator och efterbehandlade de lite. Prefekt tillfälle att träna på hur man använder Gimp! I Gimp är det dessutom enkelt att skära ut pusselbitar ur originalbilderna. Solnedgången fick följande bitar:

Tanken är nu att pusselbitarna ska finnas blandade runt om på skärmen, och i mitten ska det finnas en svartvit, svagt utsuddad version av det färdiga pusslet så att man får lite hjälp att lösa pusslet. Bakgrundsbilden kan också Gimp hjälpa oss med:

Nu är det dags att börja programmera! Vi börjar med lite enkel HTML-kod. En grundregel med HTML är att man ska få med all data som en sida/applikation ska innehålla, men hålla sig från att skriva in beteende och design. Därför är det helt korrekt att nu börja vårt pusselspel med att fylla HTML-koden med alla bilder som pusslet består av:

<!DOCTYPE html>
<html lang="sv">
  <head>
    <meta charset="utf-8" />
    <title>Ett pussel!</title>
  </head>
  <body>
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella_svartvit_bakgrund.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella1.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella2.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella3.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella4.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella5.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella6.png" />
  </body>
</html>

Detta är ännu inte så imponerande. Du kan se resultatet här:
http://mikael.tylmad.com/files/2013/04/pussel_steg1.html.

För att positionera den svartvita-bakgrunden lite bättre kan vi lägga till lite CSS, och vi passar på att ge hela sidan ett trevligare intryck.

<!DOCTYPE html>
<html lang="sv">
  <head>
    <meta charset="utf-8" />
    <title>Ett pussel!</title>
    <style>
      html
      {
        background-color: black;
      }
      #bakgrund
      {
        position: fixed;
        top: 50%;
        left: 50%;
        margin-top: -219px;
        margin-left: -367px;
        z-index: -1;
      }
    </style>
  </head>
  <body>
    <img id="bakgrund" src="http://mikael.tylmad.com/files/2013/04/Isabella_svartvit_bakgrund.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella1.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella2.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella3.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella4.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella5.png" />
    <img src="http://mikael.tylmad.com/files/2013/04/Isabella6.png" />
  </body>
</html>

Visserligen en lite enkel och kanske ful lösning för att centrera den gråa bakgrunden på skärmen, men det fungerar :-)
http://mikael.tylmad.com/files/2013/04/pussel_steg2.html.

För att nu lägga till intelligens till pusselspelet behövs jQuery samt jQuery UI. Dessa bibliotek används extremt mycket numera på nätet, och inkluderas bäst i koden genom att man använder deras egna CDN:er. För att få jQuery UI att fungera bra på enheter med petskärm behövs biblioteket jQuery UI Touch Punch. Detta får man ladda hem och lägga på samma plats som HTML-filerna.

Totalt behövs alltså tre inkluderade filer:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
<script src="http://mikael.tylmad.com/js/jquery.ui.touch-punch.min.js"></script>

Koden som behövs för att nu göra våra pusselbitar flyttbara är totalt en rad lång.

<script>
  $(".pusselbit").draggable();
</script>

Här väljer vi ut alla HTML-element som tillhör klassen pusselbit och gör dem dragbara. I HTML-koden kommer vi givetvis behöva ge bilderna rätt klass, men hela den resulterande koden blir fortfarande väldigt simpel:

<!DOCTYPE html>
<html lang="sv">
  <head>
    <meta charset="utf-8" />
    <title>Ett pussel!</title>
    <style>
      html
      {
        background-color: black;
      }
      #bakgrund
      {
        position: fixed;
        top: 50%;
        left: 50%;
        margin-top: -219px;
        margin-left: -367px;
        z-index: -1;
      }
    </style>
  </head>
  <body>
    <img id="bakgrund" src="http://mikael.tylmad.com/files/2013/04/Isabella_svartvit_bakgrund.png" />
    <img class="pusselbit" src="http://mikael.tylmad.com/files/2013/04/Isabella1.png" />
    <img class="pusselbit" src="http://mikael.tylmad.com/files/2013/04/Isabella2.png" />
    <img class="pusselbit" src="http://mikael.tylmad.com/files/2013/04/Isabella3.png" />
    <img class="pusselbit" src="http://mikael.tylmad.com/files/2013/04/Isabella4.png" />
    <img class="pusselbit" src="http://mikael.tylmad.com/files/2013/04/Isabella5.png" />
    <img class="pusselbit" src="http://mikael.tylmad.com/files/2013/04/Isabella6.png" />

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
    <script src="http://mikael.tylmad.com/js/jquery.ui.touch-punch.min.js"></script>
    <script>
      $(".pusselbit").draggable();
    </script>
  </body>
</html>

Testa att lägga pusslet:

http://mikael.tylmad.com/files/2013/04/pussel_steg3.html.

Nästa naturliga steg är att vidareutveckla designen på sidan och kanske ha några olika pussel som man kan lägga. Det skulle också vara snyggt med lite mer JavaScript-kod som exempelvis slumpar ut pusselbitarna på skärmen varje gång man laddar ett pussel, och som kanske inser när pusslet är färdigt. Jag återkommer!

Maila din kommentar till mikael@tylmad.com, så lägger jag in den under inlägget.