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!
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!
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:
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!