Det finns kontrollstrukturer som återfinns i alla strukturerade programmeringspråk. Man brukar tala om de tre grundläggande kontrollstrukturerna:
Vi ska gå igenom selektion. En selektion kan också kallas för en villkorssats.
Vi ska också gå igenom olika sätt att hantera händelser. För händelsestyrda program, vilket de flesta moderna program är, är händelsestyrning ett grundläggande begrepp.
En villkorssats används om programmet ska utföra olika saker beroende på om något villkor är sant eller falskt. Det är också mycket vanligt att man kallar villkorssatser för if-satser eller if-else-satser.
Villkorssatser i Processing har samma struktur som om-block och om-annars-block i Scratch.
För att koden ska vara lättare att läsa, indenteras den kod som ligger inuti villkorssatsen.
Måsvingarna används för att stänga in flera enkla satser. Om en villkorssats bara använder sig av en enda sats, går det bra att inte använda måsvingar. Med följande kod ska bara en sats utföras om poängen är noll:
if (poäng == 0)
text("Bu!", 100, 100);
Om du i efterhand kommer på att flera satser ska utföras om något villkor är sant, måste du i efterhand lägga till måsvingar. För nybörjare kan det vara bra att alltid använda måsvingar till villkorssatser, även om det bara är en enkel sats som ska utföras. Med måsvingar blir det inga nybörjarfel om villkorssatsen måste ändras.
Om du använder Windows eller Linux, ser du vilka knappar på tangentbordet som ger måsvingar. Måsvingarna finns i det nedre högra hörnet på tangenterna 7 och 0. För att skriva en måsvinge klickar du på Alt Gr samtidigt som du klickar på 7 eller 0. Andra specialtecken fungerar på liknande sätt.
Om du använder Mac får du ingen hjälp av tangentbordet. För att skriva specialtecken med en Mac, se sidan Backslash och andra specialtecken på en Mac.
En variabel som bara kan anta värdet sann eller falsk kallas för en boolesk variabel. I Processing används värdena true
och false
för booleska variabler. Booleska variabler kan användas som villkor i villkorssatser
Det finns två fördefinierade booleska variabler mouseIsPressed
och keyIsPressed
som håller reda på om musknappen är nedtryckt respektive om någon tangent är nedtryckt.
Gör ett enkelt ritprogram med följande kod:
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
}
function draw() {
if (mouseIsPressed) {
ellipse(mouseX, mouseY, 20);
}
}
Lägg till kommandot
print(mouseIsPressed);
i draw-funktionens if-sats. Testkör programmet för att se vilka värden som skrivs ut i konsolen.
Eftersom likhetstecknet används för att tilldela variabler värden, används dubbla likhetstecken för logisk likhet. Det finns flera jämförelseoperatorer i OpenProcessing.
operator | jämförelse |
---|---|
== |
lika med |
!= |
skilt från |
< |
mindre än |
> |
större än |
<= |
mindre än eller lika med |
>= |
större än eller lika med |
En jämförelse är antingen sann eller falsk och fungerar därför som villkor till en villkorssats.
Det finns tre logiska operatorer i Processing: och, eller, inte.
operator | logisk operation |
---|---|
&& |
och |
|| |
eller |
! |
inte |
Gör en studsande boll genom att lägga in följande kod:
let x, y, ySteg;
function setup() {
createCanvas(windowWidth, windowHeight);
x = width/2;
y = height/2;
ySteg = 5;
}
function draw() {
background(100);
if (y > height || y < 0) {
ySteg = -ySteg;
}
y = y + ySteg;
ellipse(x, y, 20);
}
Lägg till en variabel xSteg
och se till att bollen studsar också studsar i x-led.
Prioritetsordningen är sådan att först beräknas aritmetiska operationer, sedan jämförelser och sist logiska operationer. På så vis fungerar följande kod:
if (y + 5 > height || y - 5 < 0) {
//kod
}
Först beräknas y + 5
och y - 5
, sedan utförs större än och mindre än, sist utförs logiskt eller.
En villkorssats i sin enklaste form ser till att något utförs om ett villkor är sant.
if (<villkor>) {
// Kod som utförs om villkor sant.
}
En villkorssats kan också förgrena sig till två alternativ.
if (<villkor>) {
// Kod som utförs om villkor sant.
} else {
// Kod som utförs om villkor falskt.
}
Om du vill ha flera förgreningar kan du använda else if
konstruktioner.
if (<villkor1>) {
// Kod som utförs om villkor1 sant.
} else if (<villkor2>) {
// Kod som utförs om villkor1 falskt och villkor2 sant.
} else if (<villkor3>) {
// Kod som utförs om villkor1 och villkor2 är falska
// men villkor3 sant.
} else {
// Kod som utförs om alla villkor är falska.
}
En villkorssats kan innehålla ett godtyckligt antal else if
men högst ett else
.
Testa att rita tre olika färger med följande kod:
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
noStroke();
}
function draw() {
if (mouseX < width/3) {
fill(255, 0, 0);
} else if (mouseX < 2*width/3) {
fill(0, 255, 0);
} else {
fill(0, 0, 255);
}
ellipse(mouseX, mouseY, 20, 20);
}
I Scratch finns det flera block som används för att kolla om en sprajt rör en färg, annan sprajt eller kant. I Processing måste programmeraren själv programmera alla kollisioner. För att kontrollera om en position är vid kanten kan man använda att alla x-koordinater i ritområdet är begränsade av 0 och width
, y-koordinaterna begränsas av 0 och height
.
Kommandot dist(<x1>, <y1>, <x2>, <y2>)
beräknar avståndet mellan punkterna (x1
, y1
) och (x2
, y2
). Avståndet mellan punkter kan användas för att kolla om muspekaren befinner sig på en cirkel.
Följande kod upptäcker om muspekaren befinner sig på en cirkel:
let x, y, radie;
function setup() {
createCanvas(windowWidth, windowHeight);
x = width/2;
y = height/2;
radie = 100;
}
function draw() {
background(100);
ellipse(x, y, 2*radie, 2*radie);
if (dist(mouseX, mouseY, x, y) < radie) {
text("Innanför", 100, 100);
} else {
text("Utanför", 100, 100);
}
}
Testa koden!
Lägg till kommandot
ellipseMode(RADIUS);
i setup-funktionen och ändra i koden för ellipsen så att programmet fortfarande fungerar.
Att upptäcka kollision mellan muspekare och rektangel är något besvärligare.
Utgå ifrån följande kod för att upptäcka kollision med rektangel:
let x, y, bredd, höjd;
function setup() {
createCanvas(windowWidth, windowHeight);
x = width/2;
y = height/2;
bredd = 200;
höjd = 100;
}
function draw() {
background(100);
rect(x, y, bredd, höjd);
if (mouseX > x && mouseX < width) {
text("Innanför", 100, 100);
} else {
text("Utanför", 100, 100);
}
}
Lägg till kod i if-satsens villkor så att texten "Innanför" bara visas då muspekaren befinner sig innanför rektangeln.
En händelse i Processing är exempelvis när användaren klickar på en tangent eller musen. En del händelsehantering kan hanteras inuti draw-funktionen med hjälp av variablerna mouseIsPressed
och keyIsPressed
. Det finns också funktioner för händelsehantering som ligger utanför draw-funktionen.
Det finns fyra funktioner för att hantera mushändelser: mouseMoved()
, mouseDragged()
, mouseReleased()
och mouseClicked()
Testa följande kod:
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
}
function draw() {
ellipse(mouseX, mouseY, 20, 20);
}
function mouseReleased() {
print("Du släppte upp musen.");
}
Lägg på liknande sätt till två funktioner mouseMoved()
och mouseDragged()
som skriver ut lämpliga meddelanden i konsolen. Testa ditt program för att se vad skillnaden är mellan dessa två händelser.
Alfanumeriska tangenter är sådana tangenter som skriver ut någon symbol om man exempelvis använder en ordbehandlare. Andra tangenter skriver inte ut något utan har speciella funktioner, exempelvis kontrolltangenten, piltangenter, tab, m.fl.
För att upptäcka händelsen att en alfanumerisk tangent trycks ner, kan du använda funktionen keyTyped()
som utlöses exakt en gång när en alfanumerisk tangent trycks ner. Den tangent som tryckts ner lagras i variabeln key
.
Testa följande kod:
let meddelande;
function setup() {
createCanvas(windowWidth, windowHeight);
meddelande = "";
textAlign(CENTER);
}
function draw() {
background(100);
text("meddelande = " + meddelande, width/2, height/2);
}
function keyTyped() {
meddelande = meddelande + key;
}
Testkör koden och se vad som händer om du klickar på alfanumeriska tangenter. Vad händer om du klickar på enter, tab, och piltangenter?
För att kontrollera vilken alfanumerisk tangent som tryckts ner kan du jämföra key
med valfritt tecken innesluten av citationstecken eller apostrof.
För att upptäcka alla sorters tangenttryckningar kan funktionen keyPressed()
användas, vilken utlöses precis en gång när någon tangent trycks ner.
För icke-alfanumeriska tangenter används variabeln keyCode
. För att ta reda på vilken icke-alfanumerisk tangent som tryckts ner, kan du jämföra keyCode
med något av följande:
BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW
Testa följande kod:
function setup() {
createCanvas(windowWidth, windowHeight);
}
function keyTyped() {
if (key == "a") {
print("Du skrev a");
}
}
function keyPressed() {
if (keyCode == ENTER) {
print("Du klickade på enter.");
}
}
Testkör koden och se vad som händer om du klickar på lilla a respektive stora A.
Om du vill upptäcka att en bokstav tryckts ner men inte bryr dig om huruvida det är en stor eller liten bokstav, kan du jämföra key
med en stor bokstav i funktionen keyPressed()
. Lägg till följande kod i keyPressed()
:
if (key == "B") {
print("Du skrev b");
}
Testa sedan att klicka på b och på B.
Om du vill kunna styra ett objekt genom att hålla två tangenter nere samtidigt, kan du använda funktionen keyIsDown(<tangentkod>)>
inuti draw-funktionen.
Testa följande kod:
let x, y;
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
x = width/2;
y = height/2;
}
function draw() {
ellipse(x, y, 20, 20);
if (keyIsDown(LEFT_ARROW)) {
x = x - 5;
}
if (keyIsDown(RIGHT_ARROW)) {
x = x + 5;
}
if (keyIsDown(UP_ARROW)) {
y = y - 5;
}
if (keyIsDown(DOWN_ARROW)) {
y = y + 5;
}
}
Testkör koden och prova att styra med två tangenter samtidigt.
Den fördefinierade variabeln frameCount
håller reda på hur många gånger draw-funktionen genomlöpts. Det går att stänga av draw-metoden när den genomlöpts ett visst antal gånger med kommandot noLoop()
. Koden
if (frameCount == 60) {
noLoop();
}
stänger av draw-funktionen efter 60 tickningar.
Funktionen draw genomlöps ungefär 60 gånger per sekund, andelen frames per second (fps) är 60. Du kan göra så att draw-funktionen tickar långsammare genom att använda funktionen frameRate(<fps>)
. Exakt hur ofta draw-funktionen tickar beror på hur snabb datorn är.
Om du vill mäta tid exakt, kan du använda funktionen millis()
vilken mäter hur många millisekunder det gått sedan programmet startade.
Följande kod visar hur en enkel timer kan göras:
let start, stopp;
function setup() {
createCanvas(windowWidth, windowHeight);
start = -1;
stop = -1;
textSize(32);
}
function draw() {
background(100);
if (start == -1) {
text("Klicka på mellanslag två gånger!", 100, 100);
}
if (stop != -1) {
text("Det tog "+stop +" millisekunder.", 100, 200);
}
}
function keyTyped() {
if (key == " ") {
if (start == -1) {
start = millis();
} else {
stop = millis()-start;
start = -1;
}
}
}
Testkör koden. Om du inte vill visa en massa decimaler kan du avrunda med hjälp av funktionen round(<tal>)
Funktionen millis()
mäter tid med hjälp av datorns klocka. Det finns flera funktioner som med hjälp av datorns klocka kan ta reda på vilket år det är eller vilken månad, dag, timme, minut, sekund det är. Funktionerna är:
year()
, month()
, day()
, hour()
, minute()
, second()
Rita ellipser eller rektanglar
Gör ett program som ritar en rektangel om man trycker ner någon tangent och annars ritar en ellips. Använd en if-else-sats och den fördefinierade booleska variabeln keyIsPressed
.
Färglägg Tysklands flagga
Tysklands flagga har dimensionerna 3:5, dvs om höjden är 3 längdenheter så är bredden 5 längdenheter. Flaggan är indelat i tre lika stora horisontella band. Det översta bandet är svart. Det mellersta bandet är rött med RGB-färgen (221,0,0). Det nedersta bandet är gult med RGB-färgen (255,206,0).
Se till att ritområdet har rätt dimensioner. Lägg in kod som ritar en ellips i rätt färg beroende på let muspekaren befinner sig så att flaggan ritas ut när man drar med musen över ritområdet. Använd en villkorssats med en else if
konstruktion.
Färglägg Sveriges flagga
Sveriges flagga har dimensionerna 10:16, dvs om höjden är 10 längdenheter så är bredden 16 längdenheter.
Den blå färgen är RGB-färgen (0, 106, 167) och den gula RGB-färgen (254, 204, 0).
De horisontella fälten är i förhållandet 5:2:9, dvs 5 längdenheter blått, 2 längdenheter gult, 9 längdenheter blått (från vänster till höger).
De vertikala fälten är i förhållandet 4:2:4, dvs 4 längdenheter blått, 2 längdenheter gult, 4 längdenheter blått.
Se till att ge ritområdet har rätt dimensioner. Börja sedan med att lägga in kod som ritar de horisontella fälten med korrekta färger. Använd samma struktur som i koden nedan fast fyll i kod för villkoret och för färgsättningen. För att skriva det villkor för muspekarens x-koordinat som ger gul färg kan du använda lämpliga jämförelser och en och-operator (och-operatorn skrivs &&
). Testkör din kod!
if (<villkor för x-koordinat som ger gult>) {
// gul färg
} else {
// blå färg
}
Det mellersta horisontella fältet ska alltid vara gult oavsett vilken y-koordinat musen har. De blå horisontella fälten ska däremot antingen vara gula eller blå beroende på y-koordinaten. Lägg nu in en if-sats inuti din ursprungliga if-sats. En if-sats inuti en if-sats kallas för en nästlad if-sats. Det går att använda samma princip med en logisk och-operator för y-koordinaten (vilken ger gul färg) men prova istället att använda en logisk eller-operator (eller skrivs ||
) vilken ger villkoret för blå färg.
if (<villkor för x-koordinat som ger gult>) {
// gul färg
} else {
if (<villkor för y-koordinat som ger blått>) {
// blå färg
} else {
// gul färg
}
}
Testkör ditt program och se till att flaggan ritas ut med korrekt färgsättning.
Enkelt ritprogram
Utgå ifrån Exempel 1 och lägg till funktionalitet så att användaren kan välja färg och ändra på cirkelns storlek.
Gör en variabel som används för cirkelns storlek och se till att denna kan ändras av användaren genom att exempelvis klicka på pil upp eller ned.
Låt användaren välja mellan några färger exempelvis genom att klicka på 'r' för röd osv.
Du kan exempelvis utgå ifrån denna struktur som placeras längst ned i programmet.
function keyTyped() {
if (key == "r") {
// kod för färgen röd.
}
}
function keyPressed() {
if (keyCode == UP_ARROW) {
// kod för större storlek
}
}
Studsande boll
Utgå ifrån Exempel 2. Gör en variabel för cirkelns radie så att denna lätt kan ändras. Ändra i olikheterna som får bollen att studsa så att bollen studsar när bollens kant rör ritområdets kant. Testkör ditt program med en stor radie så att det tydligt syns att studsarna är korrekta.
Studsande sprajt
Utgå från kod för en studsande boll men ändra på koden så att en bild används istället för en uppritad cirkel.
En bild är rektangelformad. Hur ska jämförelserna göras så att bilden studsar när bildens kant rör ritområdets kant?
En klocka
Använd de inbyggda funktionerna för tidmätning till att visa dagens datum och en klocka. Du konkatenerar text du själv skriver med funktionsvärden genom att använda tecknet +
, exempelvis som i koden:
text("Det är just nu år " + year() + ".", width*0.5, height*0.25);
Se till att texten är horisontellt centrerad genom att skriva
textAlign(CENTER);
i setup-funktionen.
Koden för att visa texterna ska ligga i draw-funktionen så att de hela tiden uppdateras.
Pricka studsande boll
Utgå ifrån kod för en studsande boll. Gör om denna kod till ett spel som ger spelaren poäng varje gång spelaren klickar på bollen. Spelet ska fungera så här:
frameCount
och en villkorssats för att visa instruktionen. Bestäm själv hur länge instruktionen ska visas. Denna kod ska ligga i draw-funktionen.mouseClicked
genom att nederst i programmet lägga till följande kod:
function mouseClicked() {
// kod som utförs vid musklickning
}
Gör en villkorssats inuti mouseClicked
som kontrollerar om muspekaren befinner sig på bollen och öka i sådana fall poängen. Kod för att upptäcka kollisionsdetektering visas i Exempel15.
frameCount
. Bestäm själv efter hur lång tid spelet ska avslutas. När detta händer ska något sorts resultat visas, exempelvis "Du fick 3 poäng". Du stänger av draw-funktionen med kommandot noLoop();
. Välj själv om poängen ska visas under spelets gång eller bara på slutet. På tio sekunder
För att mäta tid kan du använda funktionen millis()
vilken mäter hur många millisekunder det gått sedan programmet startade.
Gör ett program som låter användaren klicka på en cirkel. Vid varje träff ska cirkeln få en ny slumpmässig position och användaren ska få en poäng. Användaren har tio sekunder på sig att samla poäng. Använd variabler för cirkelns position och radie. Du behöver även en variabel för att räkna poäng. Använd funktionen millis()
för att mäta hur många millisekunder det gått sedan programmet startat.
I och med att cirkeln byter position varje gång användaren klickar på den, går det bra att räkna poäng i draw-funktionen genom att använda variabeln mouseIsPressed
. Utgå exempelvis från följande kod:
let x, y, r, poäng;
function setup() {
createCanvas(windowWidth, windowHeight);
x = random(width);
y = random(height);
r = 50;
poäng = 0;
textAlign(CENTER);
}
function draw() {
background(100);
ellipse(x, y, 2 * r);
text("Poäng = " + poäng, width * 0.2, height * 0.2);
if (mouseIsPressed) {
// Kod för träff.
// Vid träff ska användaren få poäng och cirkeln en ny position.
}
// Kod för att kontrollera om det gått tio sekunder.
// Efter tio sekunder ska resultat visas och draw-funktionen stängas av.
}
Modellera gravitation
Låt en boll falla till marken. Använd två variabler för bollens position och en variabel för bollens hastighet i y-led. Se till att bollen startar någonstans i den övre delen av ritområdet och att hastigheten i y-led är noll från början.
Så länge bollen befinner sig ovanför den nedre kanten ska den accelereras neråt, annars ska y-koordinaten sättas så att bollen placeras precis vid nedre kanten och hastigheten i y-led sättas till noll. Använd en if-else-sats med en lämplig olikhet för att avgöra när bollen är vid den nedre kanten eller inte.
Se till att bollen börjar om med hastigheten noll vid muspekarens koordinater när användaren klickar med musen i ritområdet.
Dämpad studsning
Utgå ifrån kod som låter en boll falla vid marken. Ändra i koden så att hastigheten inte sätts till noll när bollen rör vid marken utan byter tecken så att bollen rör sig uppåt. För att programmet ska fungera måste du efter att du ändrat tecken på hastigheten se till att y-koordinaten ändras så att den får en första knuff upp ifrån nedre kanten, annars kommer den att fastna vid den nedre kanten.
För att se till att studsen dämpas kan du istället för att byta tecken multiplicera hastigheten i y-led med -0.9 eller liknande negativt tal. Testa olika dämpningsfaktorer.
Observera att med denna kod kommer bollen troligen inte att sluta studsa.
Modellera hopp
Utgå från kod för en boll som faller till marken. Byt kod för musclickning så att användaren kan hoppa genom att klicka i ritområdet. Vid ett hopp ska bollen få en hastighet i riktning uppåt, sedan ska positionen ändras direkt så att bollen kommer ovanför nedre kanten.
Lägg till en variabel för hastigheten i x-led och se till att denna har värdet noll från början. Lägg till en funktion keyPressed
längst ner i programmet och lägg in kod som ger bollen en hastighet åt höger eller vänster när användaren klickar på höger respektive vänster piltangent. Se slutligen till att bollen studsar i sidorna genom att lägga till lämplig kod i draw-funktionen.