qr code

Loopar och listor med Processing

Loopar och listor med Processing

Vi ska gå igenom hur man gör en loop och hur man gör en indexerad lista i Processing. Dessa begrepp har motsvarigheter i Scratch.

Loopar i Scratch
loop i Scratch

Tre sätt att upprepa i Scratch. Blocket för-alltid kan sägas motsvara draw-funktionen i Processing. Blocken repetera och repetera-tills har motsvarigheter i Processing som skrivs med kod.

Listor i Scratch
listor i Scratch

Exempel på indexerade listor i Scratch. Man kan sätta in element i listan från början eller med hjälp av kodblock när programmet körs. Man kan komma åt element i en lista genom att ange ett index. På motsvarande sätt kan man göra indexerade listor i Processing genom att skriva kod.

När du skriver kod för dessa strukturer i Processing är koden inte specifik för Processing utan bygger på den syntax som används av det bakomliggande programmeringsspråket. Om du använder Processing som bygger på Java är det alltså Java-syntax som används. Vi använder här en Javascript-version av Processing (Javascript-biblioteket p5.js) och använder därför Javascript-syntax. Inom Javascript finns det många olika sätt att skriva kod, vi följer de rekommendationer som beskrivs i boken Javascript: The Good Parts av Douglas Crockford.

Loopar

Att upprepa kod kallas för att iterera. En upprepning kallas för en iteration eller en loop.

Du finns olika strukturer för iteration i Javascript. Vi kommer att gå igenom for-satser och while-satser.

for-satser

För att skriva en for-sats skriver du först ordet for följt av ett par parenteser. Mellan parenteserna ska det in tre delar kod som separeras av semikolon. Därefter skriver du in den kod som ska upprepas, denna kod innesluts av måsvingar.

for ( <startvärde> ; <villkor> ; <upp- eller nedräkning> ) {
	// kod som upprepas
}

En for-sats använder sig i standardfallet av en variabel som är ett tal. Om variabeln är ett heltal som inte står för något speciellt i koden, är det vanligt att variabelnamnet i används.

  • Koden för <startvärde> är att i tilldelas ett startvärde.
  • Koden för <villkor> är en olikhet som innehåller variabeln i. Koden upprepas så länge denna olikhet är sann.
  • Koden för <upp- eller nedräkning> är att variabeln i ökar eller minskar med något tal.
Exempel 1

Följande kod gör en uppräkning som visas i konsolen.

function setup() {
	var i;
	createCanvas(windowWidth, windowHeight);
	background(100);
	for (i = 0; i < 10; i = i + 1) {
		print("i = " + i);
	}
}

function draw() {

}

Ändra i koden så att det blir en nedräkning. Byt for-satsen till följande kod:

for ( i = 9 ; i  >= 0 ; i = i - 1 ) {
	print("i = " + i);
}

Även om du inte vill använda variabeln i i den kod som upprepas, behövs den för att hålla reda på hur många gånger koden ska upprepas. Byt for-satsen till följande kod:

for (i = 0; i < 10; i = i + 1) {
	ellipse(random(width), random(height), 20);
}

För denna kod, som ritar ut tio slumpmässigt placerade cirklar, spelar det ingen roll om det är en uppräkning eller nedräkning, värdet på variabeln i används inte inuti for-satsen.

Testa att rita ut fem slumpmässigt placerade cirklar genom att

  • ändra på koden för <villkor>,
  • ändra på koden för <upp- eller nedräkning>.

I och med att det är så vanligt att man förändrar en variabel med något av de fyra räknesätten, finns det speciella tilldelningsoperatorer för sådana förändringar. Dessa operatorer gör koden något kortare.

Tilldelningsoperatorer för förändringar.
operator exempel motsvaras av
+= v += 2 v = v + 2
+= v -= 2 v = v - 2
*= v *= 2 v = v*2
/= v /= 2 v = v/2
Exempel 2

Följande kod ritar upp nio vertikala linjer över ritområdet.

function setup() {
	var x;
	createCanvas(windowWidth, windowHeight);
	background(100);
	for (x = width/10; x < width; x += width/10) {
		line(x, 0, x, height);
	}
}

function draw() {

}

Ändra i koden så att det istället ritas upp 100 jämnt fördelade vertikala linjer.

while-satser

Med en while-sats upprepar du någon kod så länge något villkor är uppfyllt.

while ( <villkor> ) {
	// kod som upprepas
}

Inuti en while-sats måste det finnas kod som förändrar villkoret så att det så småningom inte längre är uppfyllt, annars får du en oändlig loop.

Exempel 3

Med denna kod är det två variabler som förändras, x-koordinaten och radien. Det ritas större och större cirklar tills en cirkels kant når ritområdets kant.

function setup() {
	createCanvas(windowWidth, windowHeight);
}

function draw() {
	var x, radie;
	background(100);
	x = mouseX
	radie = 10;
	while (x + radie < width) {
		ellipse(x, mouseY, 2 * radie);
		x += 5;
		radie += 1;
	}
}

Lägg märke till att om du för muspekaren tillräckligt nära den högra kanten av ritområdet, ritas det ingen cirkel alls. Om villkoret inte är uppfyllt från början, genomlöps while-satsen inte alls.

Testa att ändra radien så att den ökar med två procent i varje steg, istället för att addera ett till radien.

Det finns också en variant av en while-sats som garanterat alltid genomlöps minst en gång, en så kallad do-while-sats. För att se till att loopen genomlöps minst en gång kontrolleras villkoret i slutet av loopen. Loopen skrivs som

do {
	// kod som upprepas
} while ( <villkor> );

Nästlade loopar

Du kan skriva en loop inuti en annan loop, då får du en nästlad loop. Nästlade loopar är användbara för att hantera objekt som befinner sig i rader och kolonner.

Exempel 4

Om du vill rita upp fem cirklar längs en rad kan du använda följande kod:

function setup() {
	var x, y;
	createCanvas(windowWidth, windowHeight);
	background(100);
	y = 100;
	for (x = 100; x <= 500; x += 100) {
		ellipse(x, y, 20);
	}
}

Om du nu istället för att rita en cirkel för varje x-koordinat vill rita fyra cirklar placerade i en kolonn, kan du byta ut den kod som ligger inuti for-satsen till en ny for-sats.

function setup() {
	var x, y;
	createCanvas(windowWidth, windowHeight);
	background(100);
	for (x = 100; x <= 500; x += 100) {
		for (y = 100; y <= 400; y += 100) {
			ellipse(x, y, 20);
		}
	}
}

När du skriver nästlade for-satser är det enklare att läsa koden om den är indenterad. Flytta några rader i koden åt vänster så att koden blir mer svårläst (klicka på backspace i början på en rad). Klicka sedan på ctrl + b för att snygga till koden igen.

Med objekt som befinner sig i ett rutnät kan det finnas flera egenskaper som beror på var i rutnätet objektet befinner sig. Du kan använda två variabler rad och kolonn och loopa över dessa. För att ange koordinaterna för varje objekt skriver du sedan uttryck i dessa variabler. Andra egenskaper kan också definieras med hjälp av uttryck i variablerna rad och kolonn.

Exempel 5

Följande kod ritar upp cirklar i ett rutnät

function setup() {
	var kolonn, rad;
	createCanvas(windowWidth, windowHeight);
	background(100);
	for (kolonn = 0; kolonn < 5; kolonn += 1) {
		for (rad = 0; rad < 4; rad += 1) {
			ellipse(100 + kolonn * 100, 100 + rad * 100, 20);
		}
	}
}

Vi kan se till att det blir olika färger för varje kolonn. Genom att lägga till kommandot fill i den yttre for-satsen blir cirklarna rödare och rödare ju längre åt höger de ritas.

function setup() {
	var kolonn, rad;
	createCanvas(windowWidth, windowHeight);
	background(100);
	for (kolonn = 0; kolonn < 5; kolonn += 1) {
		fill(kolonn * 50, 0, 0);
		for (rad = 0; rad < 4; rad += 1) {
			ellipse(100 + kolonn * 100, 100 + rad * 100, 20);
		}
	}
}

Flytta på kommandot fill så att den ligger i den inre for-satsen. Se till att den gröna färgen ökar längs raderna.

färgat rutnät

Listor

En indexerad lista inom programmering kallas för array på engelska. Om du vill googla på hur listor i Javascript fungerar är det alltså ordet array du ska googla på.

En indexerad lista i Javascript använder sig av hakparenteser för att innesluta element i listan. Om du redan från början vet vilka element som ska ligga i listan och om listan är kort, kan du lägga in alla element i listan direkt efter att du deklarerat vad listan ska heta.

Med denna kod deklareras två variabler, sedan tilldelas de varsin lista där varje element är en textsträng respektive ett tal:

var land, tal;
land = ["Sverige", "Norge", "Danmark", "Island", "Finland"];
tal = [50, 150, 250, 350, 450];

Det går också att göra tilldelningen samtidigt som man deklarerar variablerna. Tänk på att i en variabeldeklaration används komma-tecken mellan variablerna.

var land = ["Sverige", "Norge", "Danmark", "Island", "Finland"],
	tal = [50, 150, 250, 350, 450];

Inom programmering brukar man börja räkna med talet noll. Det första elementet i en lista har index noll, det andra index ett, osv. För att komma åt ett element med index tre, skriver du listans namn följt av en trea mellan hakparenteser. Koden

var land = ["Sverige", "Norge", "Danmark", "Island", "Finland"],
	tal = [50, 150, 250, 350, 450];
print("Landet med index tre är " + land[3] + ".");
print("Talet med index noll är " + tal[0] + ".");

ger utskriften:

Landet med index tre är Island.
Talet med index noll är 50.

Om du inte vill fylla i hela listan direkt när du deklarerar den, kan du börja med att i deklarationen ange att variabelnamnet är en lista. Däreftet kan du tilldela listelement i koden med hjälp av hakparenteser.

var land, tal = [];
land = ["Sverige", "Norge", "Danmark", "Island", "Finland"]
tal[0] = 50;
tal[1] = 150;
tal[2] = 250;
tal[3] = 350;
tal[3] = 450;

Det hade inte gått att använda hakparenteser till vänster om likhetstecknet på rad tre om inte variabeln tal varit en lista. Att variabeln är en lista syns i variabeldeklarationen tal = [].

Det är mycket vanligt att man loopar över en lista med hjälp en for-sats. Eftersom talen i listan tal ökar med 100, går det att göra tilldelningarna med hjälp av en loop. Vi måste då också deklarera ett index, exempelvis i, som används i loopen.

var land, tal = [], i;
land = ["Sverige", "Norge", "Danmark", "Island", "Finland"];
for (i = 0; i < 5; i += 1) {
	tal[i] = 50 + 100 * i;
}

Tänk på att om en lista innehåller fem element så har det sista elementet index fyra eftersom vi börjar räkna på noll.

Exempel 6

Testkör koden

function setup() {
	var land, x = [], y, i;
	land = ["Sverige", "Norge", "Danmark", "Island", "Finland"];
	for (i = 0; i < 5; i += 1) {
		x[i] = 50 + 100 * i;
	}
	y = 100;
	createCanvas(windowWidth, windowHeight);
	background(100);
	for (i = 0; i < 5; i += 1) {
		text(land[i], x[i], y);
	}
}

Ändra deklarationen av variabeln y så att den också blir en lista.

Ta sedan bort tilldelningen

y = 100;

och lägg istället in tilldelningen

y[i] = 100 + 50 * i;

innanför den första for-satsen. Ändra utskriften i den andra for-satsen till:

text(land[i], x[i], y[i]);

Testkör koden!

Egenskapen length

Varje lista i Javascript har en egenskap kallad length som håller reda på hur många element listan har. Du kommer åt egenskapen length genom att använda punknotation, dvs listans namn följt av en punkt och därefter ordet length.

Koden

var land;
land = ["Sverige", "Norge", "Danmark", "Island", "Finland"];
print("Listan innehåller " + land.length + " element.")

ger utskriften:

Listan innehåller 5 element.

Egenskapen length kan användas som villkor i for-satser. På så vis fungerar loopen även om du förändrar listans innehåll.

function setup() {
	var land, i;
	land = ["Sverige", "Norge", "Danmark", "Island", "Finland"];
	createCanvas(windowWidth, windowHeight);
	background(100);
	for (i = 0; i < land.length; i += 1) {
		text(land[i], 100, 100 + 50 * i);
	}
}

Det element som befinner sig på sista plats i en lista minLista har index minlista.length - 1. I Javascript kan man i koden utöka en lista genom att lägga till ett element efter det sista elementet, dvs på platsen med index minlista.length.

Exempel 7

Två listor används för att lagra x- och y koordinater. Från början är listorna tomma. Varje gång användaren klickar med musen lagras muspekarens koordinater i respektive lista, dvs listorna utökas.

var x = [], y = [];

function setup() {
	createCanvas(windowWidth, windowHeight);
}

function draw() {
	var i;
	background(100);
	for (i = 0; i < x.length; i += 1) {
		ellipse(x[i], y[i], 50);
	}
	ellipse(mouseX, mouseY, 20);
}

function mouseClicked() {
	x[x.length] = mouseX;
	y[y.length] = mouseY;
}

Testkör och klicka med musen för att utöka listorna.

Du kan också lägga till ett element i slutet av en lista med hjälp av list-metoden

<listnamn>.push(<nytt element>) vilken skrivs med punktnotation efter en listas namn.

Ersätt koden som lägger till en x-koordinat med koden:

x.push(mouseX);

Ersätt på motsvarande sätt koden som lägger till en y-koordinat.

Slumptalsgenerera heltal

Om du vill slumpa fram något element ur en lista kan du använda funktionen random för att slumptalsgenerera ett index. Problemet är att en listas index måste anges som ett heltal och funktionen random genererar ett flyttal (dvs ett decimaltal). Du måste därför avrunda det slumptalsgenererade talet innan du använder det som listindex. Det finns tre sätt att avrunda ett flyttal.

  • Funktionen round(<tal>) avrundar till närmsta heltal.
    Kommandot round(5.1) ger talet 5 och kommandot round(5.9) ger talet 6.
  • Funktionen floor(<tal>) avrundar neråt.
    Kommandot floor(5.9) ger talet 5 och kommandot floor(-5.9) ger talet -6.
  • Funktionen ceil(<tal>) avrundar uppåt.
    Kommandot ceil(5.1) ger talet 6 och kommandot ceil(-5.1) ger talet -5.

Om du vill slumptalsgenerera ett heltal x så att 0 ≤ x < 5, kan du använda kommandot floor(random(6)). Om du vill slumpa fram ett index i en lista använder du denna konstruktion och listans egenskap length.

Exempel 8

Följande kod

function setup() {
	var land;
	land = ["Sverige", "Norge", "Danmark", "Island", "Finland"];
	createCanvas(windowWidth, windowHeight);
	background(100);
	text(land[floor(random(land.length))], 100, 100);
}

slumptalsgenererar ett index i listan och visar ett land.

Testkör koden många gånger för att se hur ett land slumpas fram.

Heltalsdivision

Det kan tyckas märkligt att man så ofta inom programmering börjar räkna på noll istället för ett. I många sammanhang är det emellertid praktiskt att börja räkna på noll. Ett sådant sammanhang är när man använder så kallad heltalsdivision för att hantera indexerade listor.

Med heltalsdivision använder man resten och kvoten vid division av två heltal. Om \(20\) heltalsdivideras med \(6\) är kvoten \(3\) och resten \(2\), vilket kan skrivas som

\[\frac{20}{6} = 3 + \frac{2}{6}\]

eller om man vill undvika bråktal som

\[20 = 3\cdot 6 + 2.\]

De flesta programmeringsspråk har någon operator för att beräkna resten vid heltalsdivision. I Javascript används symbolen % för att beräkna resten. Denna operator kallas för modulusoperatorn.

Koden

print(20 % 6);

ger utskriften

2

dvs resten då 20 heltalsdivideras med 6.

Resultatet av att använda modulusoperatorn är alltid ett tal som är större än eller lika med noll och strängt mindre än det tal man dividerar med.

Resten vid heltalsdivision med tre.
i 0 1 2 3 4 5 6 7
i % 3 0 1 2 0 1 2 0 1

Om man har en lista med tre element kan man använda heltalsdivision med tre för att få tal som fungerar som index till listan.

För en lista med godtyckligt antal element kan man stega sig igenom listan och börja om från början genom att använda heltalsdivision och egenskapen length.

Exempel 9

Följande kod

var land, index;

function setup() {
	createCanvas(windowWidth, windowHeight);
	land = ["Sverige", "Norge", "Danmark", "Island", "Finland"];
	index = 0;
}

function draw() {
	background(100);
	text(land[index], 100, 100);
}

function mouseClicked() {
	index = (index + 1) % land.length;
}

stegar sig igenom listan och börjar sedan om från början.

Testkör koden och klicka många gånger med musen.

Koden inuti mouseClicked-funktionen fungerar även om du skulle lägga till eller ta bort ett land. Hade du använt koden

index = (index + 1) % 5;

hade du behövt ändra i koden varje gång du ändrade listans innehåll.

Modulusoperatorn kan användas för att göra någonting varannan, var tredje, eller var nte gång för något heltal n. Detta är användbart om man i draw-funktionen vill rita upp någonting långsamt.

Exempel 10

Följande kod slumptalsgenererar ellipser var femte gång draw-funktionen genomlöps.

function setup() {
	createCanvas(windowWidth, windowHeight);
	background(100);
}

function draw() {
	if (frameCount % 5 == 0) {
		fill(random(256), random(256), random(256));
		ellipse(random(width), random(height), random(50), random(50));
	}
}

Testa att göra uppritningen ännu långsammare genom att rita ellips var tionde eller var tjugonde gång.

Det går att göra draw-loopen långsammare genom att i setup-funktionen ange hur många frames per second (fps) draw-funktionen ska använda sig av. För att göra detta använder du funktionen frameRate(<fps>). Om du exempelvis anger

frameRate(30);

i setup-funktionen, kommer draw-funktionen att gå hälften så snabbt som i normalfallet. I normalfallet används 60 fps. I många fall vill man dock inte göra draw-funktionen långsammare eftersom då allting går långsamt.

Exempel 11

Ladda upp några bilder till OpenProcessing som ska animeras.

Om du inte har några bilder kan du högerklicka på dessa tre och ladda ner dem till din dator.

streckgubbe 1 streckgubbe 2 streckgubbe 3

Följande kod lägger in bilderna i en indexerad lista och ritar upp en animerad rörelse samt en boll som rör sig:

var bild = [], index, x, y;

function setup() {
	createCanvas(windowWidth, windowHeight);
	bild[0] = loadImage('stickyFigure1.png');
	bild[1] = loadImage('stickyFigure2.png');
	bild[2] = loadImage('stickyFigure3.png');
	imageMode(CENTER);
	index = 0;
	x = 0;
	y = 350;
}

function draw() {
	background(255);
	image(bild[index], x, y, 75, 125);
	ellipse(x, y - 100, 50);
	if (frameCount % 7 == 0) {
		index = (index + 1) % bild.length;
	}
	x = (x + 3) % width;
}

Kommandot

imageMode(CENTER);

ser till att positionen för varje bild är centrerad.

Bilden ritas ut med bredden 75 och höjden 125 vilket är hälften så stor som den är.

Bilden byts var sjunde gång draw-funktionen genomlöps. Bollen och bilden rör sig dock varje gång draw-funktionen genomlöps.

Förflyttningen sker genom att x-koordinaten ökas med tre, x-koordinaten kan bli maximalt width - 1, därefter börjar rörelsen om från vänster kant.

Programmeringsuppgifter

Uppgift 1

Olika for-satser

Utgå ifrån koden i Exempel 1. När du skriver ut i konsolen kan du antingen bara använda variabeln i, som i koden nedan:

print("i = " + i);

eller ett uttryck i variabeln i. För att inte blanda ihop addition med konkatenering av textsträngar, är det säkrast att placera uttrycket mellan parenteser, som i koden nedan:

print("värdet av uttrycket = " + (2*i + 1) );

Gör program som ger följande utskrifter i konsolen. Använd konkatenering av textsträngar för att få rätt utskrifter.

a )
i = 3
i = 6
i = 9
i = 12
i = 15
b )
i = -5
i = 0
i = 5
i = 10
c )
i = 100
i = 90
i = 80
i = 70
i = 60
d )
3/2 = 1.5
2/2 = 1
1/2 = 0.5
0/2= 0
-1/2 = -0.5
-2/2 = -1
-3/2 = -1.5
e )
0*0 = 0
1*1 = 1
2*2 = 4
3*3 = 9
4*4 = 16
f )
17 + 2*35 = 87
17 + 2*40 = 97
17 + 2*45 = 107
17 + 2*50 = 117
17 + 2*55 = 127
17 + 2*60 = 137
17 + 2*65 = 147

Uppgift 2

Rutnät

Utgå ifrån koden i Exempel 2. Lägg till en for-sats till i koden så att ett rutnät ritas upp av linjerna. Rutnätet ska dela in ritområdet i 50✕50 rektangelformade rutor.

rutnät

Uppgift 3

Visa elva cirklar

Gör ett program som visar elva cirklar bredvid varandra. Använd en for-sats. En cirkel ska visas där muspekaren är. Fem cirklar ska vara till vänster om cirkeln vid muspekaren och fem till höger. Cirklarna ska inte ha någon kant. Cirklarna ska tangera varandra.

Dra med musen!

Uppgift 4

Mindre och mindre cirklar

Gör en variant av programmet i Exempel 3 som börjar med att rita en stor cirkel vid muspekaren och sedan ritar mindre och mindre cirklar åt höger tills en cirkels kant når ritområdets högra kant. Bestäm själv hur stor cirkel du börjar med samt hur x-koordinaten och radien ska förändras.

Dra med musen!

Uppgift 5

Ellipsmönster

Gör ett program som ritar flera ellipser vid muspekaren. Se till att den första ellipsen har stor bredd och liten höjd. Gör en loop där bredden minskas och höjden ökas, sedan ritas en ellips. Avsluta loopen när bredden är tillräckligt liten. Bestäm själv om du vill färglägga ellipserna.

Dra med musen!

Uppgift 6

Rita julgransgirlang

Gör ett ritprogram som ritar ut 50 slumpmässiga sträckor som alla utgår ifrån muspekarens position när användaren håller musknappen nedtryckt. Använd funktionen

line(<x1>, <y1>, <x2>, <y2>);

för att rita en sträcka. Den första positionen ges av muspekaren. Den andra position ska ligga på ett slumpmässigt avstånd i x-led och ett slumpmässigt avstånd i y-led ifrån muspekaren. Sträckorna kommer då att ritas upp så att de ligger innanför en rektangel.

Färglägg sträckorna på valfritt sätt. Det är kantfärgen som används när en sträcka ritas.

Se till att användaren kan sudda över hela ritområdet genom att klicka på valfri tangent.

Rita med musen! Klicka på valfri tangent för att sudda!

Uppgift 7

Visa 11✕11 cirklar

Gör ett program som visar 11✕11 cirklar intill varandra i ett rutnät. Använd en nästlad for-sats. Den mittersta cirkeln ska visas där muspekaren är.

Dra med musen!

Uppgift 8

Rutor med text

Placera ett valfritt antal rektanglar i ett rutnät. Skriv en rad text i varje triangel som visar vilken rad rektangeln befinner sig. Skriv på motsvarande sätt vilken kolonn varje rektangel befinner sig. Testkör programmet och ändra på de två texternas positioner tills de ligger inuti respektive rektangel.

Inom programmering brukar man börja en uppräkning med talet noll. På så vis är den översta raden rad noll. Välj själv om du vill börja uppräkningen med ett eller noll.

rutor med text

Uppgift 9

Multiplikationstabell

Gör ett program som visar en multiplikationstabell. Välj själv hur tabellen ska se ut.

multiplikationstabell

Uppgift 10

Slumpa land och huvudstad.

a )

  • Gör två indexerade listor: en lista med länder och en lista med motsvarande huvudstäder.
  • Deklarera en variabel index globalt (dvs överst i programmet). Se till att index får ett slumptalsgenererat värde i början av programmet.
  • Lägg in kod som slumptalsgenererar ett nytt index när användaren klickar i ritområdet.
  • Se till att det hela tiden visas en text som berättar vad huvudstaden heter i det aktuella landet.

Testkör ditt program!

b )

Texten kommer inte alltid att ändras när du klickar i ritområdet. Detta beror på att det nya slumpmässiga värdet ibland blir samma som det gamla index-värdet. Om du garanterat vill ha ett nytt index varje gång användaren klickar, kan du använda en do-while-loop på följande sätt:

var nyttIndex;
do {
	nyttIndex = floor(random(land.length));
} while (nyttIndex == index);
index = nyttIndex;

Lägg in denna ändring i din kod och testkör sedan ditt program igen.

Klicka!

Uppgift 11

Cirklar i listor.

Följande kod visar en cirkel med blå färg när muspekaren befinner sig på cirkeln. På engelska kallas detta för en hover effect.

var x, y, radie;

function setup() {
	createCanvas(windowWidth, windowHeight);
	radie = 100;
	x = 200;
	y = 200;
}

function draw() {
	background(100);
	if (dist(mouseX, mouseY, x, y) < radie) {
		fill(0, 0, 255);
	} else {
		fill(255);
	}
	ellipse(x, y, 2 * radie)
}

Utgå ifrån koden för Exempel 7. Se till att cirklarna också får en hover effect så att den cirkel användaren håller musen över ritas i en annan färg. Du kan till vissa delar kopiera koden för hover effect men utritandet måste ske i en loop och du måste se till att listelement används istället för variablerna x och y. Om du vill kan du också ge varje cirkel en slumpmässig radie som lagrar en tredje lista.

Klicka och dra med musen!

Uppgift 12

Cirklar och sträckor.

Utgå ifrån koden för Exempel 7. Se till att ingen kantfärg ritas. Nu ska cirklarna sammanbindas så att att det ritas en sträcka mellan varje cirkel och nästa cirkel i listan. För den sista cirkeln i listan ska det ritas en sträcka till den första cirkeln. Använd kommandot

line( < x1 > , < y1 > , < x2 > , < y2 > );

för att rita sträckor. Du kan använda en if-else-sats inuti loopen som ritar sträckorna, en if-else-sats som kollar om räknaren är lika med sista index (dvs om i == x.length-1) eller inte. Det går också att ange index för den andra punkten med hjälp av modulusoperatorn, då behövs ingen if-sats och koden blir kortare. Om du alltid använder modulusoperatorn för att komma åt nästa element i en lista, fungerar detta även om "nästa element" är det första elementet i listan.

Klicka!

Uppgift 13

Välj genom att klicka.

Gör tre cirklar vars positioner lagras i en två listor, en för x-koordinaten och en för y-koordinaten. Se till att cirklarna ritas upp in draw-funktionen. Välj själv vilka positioner cirklarna ska ha.

Deklarera en variabel valtIndex globalt. Se till att valtIndex har värdet -1 när programmet startar.

Lägg in en mouseClicked-funktion nederst i programmet. När användaren klickar på en cirkel ska valtIndex få det index den valda cirkeln har. För att kontrollera om användaren klickar på en cirkel måste du loopa över alla cirklar och kontrollera om muspekaren är över den aktuella cirkeln, i sådana fall ska valtIndex få det aktuella index-värdet.

Se till att den cirkel som är vald ritas i en annan färg.

Testkör ditt program. När programmet fungerar ska du kunna lägga till fler positioner i listorna och programmet ska fortfarande fungera. Du ska också kunna ändra på koordinaterna för cirklarna i efterhand.

Klicka för att välja cirkel!

Uppgift 14

Orm

Gör ett program som ritar upp 50 cirklar för de senaste 50 muspositionerna.

Gör två listor för x- och y-koordinater. Från början ska listorna vara tomma. Lägg in en loop i draw-funktionen som ritar upp alla cirklar. Från början ritas ingenting alls.

Varje gång användaren rör musen över ritområdet ska de två listorna förändras.

Gör en mouseMoved-funktion längst ner i programmet.

function mouseMoved() {
	// kod 
}

Lägg in kod som lagrar de första 50 muspositionerna i listor. Du kan använda frameCount och lägga in positioner i listorna om frameCount är mindre än 50. Testkör ditt program. De första 50 positionerna ska ritas upp.

Om frameCount inte är mindre än 50 ska det inte läggas in nya värden i listorna däremot ska listornas värden förändras. Gör en loop som låter

x[0] få värdet x[1]

x[1] få värdet x[2]

x[x.length-2] få värdet x[x.length-1]

Se till att y-koordinaterna förändras på motsvarande sätt. Efter loopen ska det sista listementet i båda listorna få de värden som ges av muspekarens position.

Dra med musen!