Visuell programmering i Processing

I dag holdt jeg en liten innledning og workshop om visuell programmering hos Norsk Telemuseum på Kjelsås. Jeg ønsket å vise fram programmeringsmiljøet rundt Processing og var også innom forskjellige emner jeg mener er viktig i dagens IT-landskap. I hovedsak orienterte dette seg om data og interfaces, eller data og dingser som jeg kalte det. En artikkel på det kontekstuelle kommer snart, men inntil videre kan du forsøke deg på oppgavesettet jeg lagde til den praktiske gjennomføringen av kurset. Jeg tror denne praktiske delen godt også kan fungere som en del 1 i serien “lær programmering med processing”.

 

Et enkelt program:
Syntaks introdusert: Kommentarer, print(), println(), size().

+ Start opp processing
+ Skriv en åpningskommentar på toppen av programmet ved å sette inn //. Alt som følger etter disse tegnene fram til linjeskift vil ikke bli prosessert. Dersom du ønsker flere linjer med kommentarer kan du bruke /* i begynnelsen av kommentarblokken og avslutte med */
+ Klikk på play-knappen for å åpne sketsjen. Hva dukket opp. Klikk på x-symbolet i vinduet som åpnet.

+Skriv kommandoen size(x,y) i programmet. Denne kommandoen tar to parametere. X angir bredden og y angir høyden i pixler. Erstatt x og y med nummere. Forsøk forskjellige tall og se resultatet ved å klikke på play etter å ha endret et av tallene. Normalt sett skal variblene være mellom 1 og 1200, avhengig av oppløsningen støttet av datamaskinen. Du må avslutte en kommando med et semikolon.

+ Skriv ut en tekst til terminalen ved å bruke kommandoen print() og println(). Dette kan være en tekststreng, et nummer eller tegn. Tegn og tekststrenger må termineres, dette gjøres ved å sette et hermetegn i hver ende.

Resultat:

//Dette er en kommentar
/* Vi kan også kommentere
over flere linjer med kode */

size(200,300);
print(“Dette er en commando fra programmet”);
println(“Hello World!”);
print(“Dette skal komme på en ny linje”);

Variabler
Syntaks introdusert: int, float, String, char, boolean, +, -, /, *
+ Nå har du laget ditt eget lille program. Forsøk nå å bytt ut nummerene fra size med variabler. Variablene skriver du ved å først initialisere dem med datatype og navn for deretter å sette en verdi til dem. Variabler er plassholdere for verdier.

int x = 200;

 int y = 500; 

+ Opprette et par nye int-variabler. Velg navn selv, men følg
navnekonvensjonene som bestemmer at en variabel skal begynne med liten bokstav og ikke ha mellomrom. Sett disse til forskjellige tall og forsøk og opprett nye variabler ved å utføre matematiske funksjoner på eksistrerende variabler inn i nye.

+ Opprett en variabel for en tekststreng og skriv en velkomstmelding til denne (Bruk type String i stedet for int). Deklarer variablene på toppen av dokumentet og referer til det nedover. Bruk regneartene til å legge verdier inn i nye variabler. Eksempel:

int i = 10;

String k = “Dette er en tekststreng”; 

int j = 5;

int k = i* j;

println(k);

Vi har hittil benyttes oss int og String (String skrives med stor forbokstav, mens alle andre datatyper vi bruker her skrives med små bokstaver). int er kort for integer (heltall), og String er en tekststreng, som også kan være tall som ikke kan regnes på. I tillegg bruker vi float som er flyttall (eks 1.2), char som er enkelttegn og boolean som true eller false. Forsøk å utfør følgende kode, og gjett hva du får:

int a = 3;

int b = 2; 

int c = a / b; 

println(c);

+ Forsøk å endre a eller b og c til float. Hvilket svar får du nå.
+ Opprett en variabel boolean og sett denne til false eller true. Hva skjer? Skriv denne ut.

Resultat:

// Variabler for size-kommandoen

int x = 200;

int y = 500;

// Tekst

String tekst = “Dette er en hilsen”

boolean test = false;

println(test);

//Variabler for å teste verdier

int i = 10;

int j = 5

int k = i* j;

println(k);

//Variabler for å teste heltall og flyttallsdivisjon

int a = 3;

float b = 2;

float c = a / b;

println(c);

//Dette er en kommentar

/* Vi kan også kommentere over

flere linjer med kode */

size(x,y);

print(“Dette er en commando fra programmet”);

println(tekst);

print(“Dette skal komme på en ny linje”);

 

Punkter, linjer og firkanter i Processing
Syntaks introdusert: point(), line(), rect().

Nå som du har kjennskap til variabler og funksjonskall i programmering kan vi begynne å more oss med funksjonaliteten i Proessing. Funksjonene point(), line(), og rect() tegner det de heter. Point tar to verdier, x og y som blir punktets koordinater på lerretet. Line tar fire argumenter, de to første er x og y for utgangspunktet og de to siste er x og y for sluttpunktet. Rect tar også fire argumenter: x, y, bredde og høyde.

size(500,500);

rect(10,10,50,50);

rect(20,60,200,100);

rect(200,400,70,70);

line(0,0,500,500);

line(0,500,500,0);

I denne introduksjonen tar vi bare for oss en 2D kontekst. I denne konteksten refererer vi til posisjoner som i et kartesiansk rom. Utgangspunktet for koordinatene er øvre venstre hjørne. Derfor vil høyere tall på x aksen bevege objektet mot høyre, og høyere tall på y aksen nedover. Dette kan du selv forsøke ved å endre på nummerene i koden ovenfor. Fra dette eksempelet kan du også se hvordan objektene blir tegnet til lerretet. Dersom et objekt er tegnet og et nytt objekt seinere skal være i samme område blir det siste tegnet over det første.

For å skape en kode det er lettere å endre (selv om Processing programmer aldri burde bli så lange at all oversikt blir borte) kan du bruke height og width, som er konstanter satt av programmet. Disse er også reserverte ord i programmet. La oss teste dette ved å endre på koden for de to siste linjene i eksempelet over.

line(0,0,width,height);

line(0,height,width,0);

Å tegne punkter er ganske kjedelig på dette tidspunktet, men frykt ikke, om litt kommer du til å kunne tegne punkter på en annen måte, noe som gjør det mye morsommere.

 

Variabler og if/else
Syntaks introdusert: if, else, blokker.
+ Nå begynner det å bli en del kode, så nå kan du enten opprette en ny fil eller fjerne all teksten ved å markere koden du allerede har og fjerne denne på samme måte som i en tekstbehandler.
+Opprett en if-blokk. Den ser omtrent ut som dette:

if(logisk spørring) {

// Gjør noe dersom logisk spørring er tilfelle

} else {

// Gjør noe annet dersom det ikke er tilfelle

}

En logisk spørring resulterer i en boolean verdi som kan være enten true eller false. For enkelhetsskyld opprett en boolean variabel og sett denne til true. Referer til denne i if(variabel). Disse logiske spørringene etterfølges av en blokk. Tenk på denne blokken som en inndeling av kode som gjennomføres. Du kan gjøre så mye du ønsker i blokken, og denne kan bestå av en kommando eller hundre, men husk å start og slutt blokken med krøllparanteser.

boolean test = false;

if(test) { 

print(“Denne kommer ikke til skrives ut ”); 

println(“Kan du finne ut hvorfor?”);

Det hele blir mer interessant når du kan teste på verdier i de logiske spørringene. Typiske spørringer for tall er ==,eller en kombinasjon av disse.
 int i = 50; 
 if(i == 20 ){  
 println(“Hvordan kan du få skrevet ut dette?”); 
 } 

Her kan du se at = og == er to forskjellige. Den første setter er verdi til en variabel og den andre tester om to verdier er de samme.

+ Forsøk nå å lage en egen if-else forgrening der du skriver ut noe dersom en verdi er sann og noe annet dersom dette ikke er tilfelle.

 

Løkker
Syntaks introdusert: for, while.

Løkker er et nyttig redskap for å gjøre en handling mange ganger. De består gjerne av en logisk spørring, en blokk og en endring. Den enkleste løkka er while(), som til norsk kan oversettes til mens. Så for å oversette den syntaktiske meningen kan du si at en while løkke går mens spørringen er sann.

//setter variabelen i 
int i = 0; 
//mens i er mindre enn tusen 
while(i < 1000){ 
//Denne har du ikke sett ennå, men her skriver vi ut 
//verdien av i 
println(i++); 
// i++ er kortform for i = i+1 
} 

+ Hvis du vil være litt vågal kan du nå forsøke å endre i++ til i. Gjett hva som skjer først og deretter test det. Litt av moroa med å programmere er at uansett hvor mange feil du gjør skjer det ikke noe veldig alvorlig.

Den andre formen for løkker er for()-løkker. Disse er litt mer avanserte enn while, og ser typisk slik ut:

for(int i = 0; i < 100; i++ ){ }

Hvis du tenker på hva slags funksjoner som en løkke typisk inneholder, er alle disse implementert i en for-løkke. Vi kan forstå en for-løkke som for(startvariabel; utgangskriterie; inkrement) { blokk }. Når en variabel blir opprettet innenfor en blokk er den usynlig utenfor. Deklarer derfor variabler du ønsker å aksessere igjennom hele programmet utenfor en løkke, eller funksjon. I eksempelet ovenfor ser du at i blir deklarert i den logiske spørringen.
+ Forsøk å skriv ut verdien av i nedenfor den siste krøllparantesen. Hva skjer? Hva skjer dersom du deklarerer i ovenfor for-løkka?

+ Tegn et stort antall geometriske gjenstander i Processing ved hjelp av løkker. Forsøk å endre noen av parameterene ved å trekke inn iteratoren i løkka i tegnefunksjonene.

 

Funksjoner
Syntaks introdusert: funksjoner, void

Å kunne skrive kode er vel og bra, men når koden blir lengre oppstår det et behov for å abstrahere vekk alle detaljer. Hvis du bruker, som vi har gjort tidligere i heftet, bokstaver som variabelnavn kommer du ganske raskt til å gå tom, dessuten kan det være vanskelig å huske mange navn. En annen fordel ved å lage metoder er at disse kan kalles fra hvilket som helst sted i programmet. Dette gjør det enkelt å hoppe fram og tilbake i koden.

Metoder deklareres med
returtype navn(argument1, argument2, argumentN){
//Her skriver du innmaten
}

Returtyper kan være alle datatyper, eller ingenting. Dersom du bruker en datatype må du bruke utrykket return samt en verdi eller variabel som inneholder data av typen oppgitt.
Denne funksjonen tar to argumenter av typen heltall og returnerer et heltall med summen av disse to tallene.

int plusser(int tall1, int tall2){ return tall1 + tall2; }

Denne funksjonen returnerer en sannhetsverdi av et heltall om hvorvidt dette tallet er et partall. Denne funksjonen introduserer et nytt tegn % – modulo – Dette utrykket returnerer rest ved divisjon. Premisset er at et partall som deles på to ikke skal returnere en rest. If grenen tester om dette er sant og returnerer true hvis dette er tilfelle.

boolean isPartall(int tall){

if(tall %2 == 0){

return true;

} else {

return false;

}

 

setup() og draw()
Syntaks introdusert: setup(), draw(), noLoop().

Processing har to funksjoner du som programmerer skriver. Disse heter setup() og draw(). Selv om du kan lage et program uten disse, kan det være en fordel å stykke programmets funksjonalitetet, som ikke allerede har sin egen funksjon, inn i disse blokkene. I setup() skriver du kode som eksekveres en gang i begynnelsen av programmet. Her kan du plassere size() metoden samt andre definisjoner og kall som ikke trengs å være en del av draw()-loopen.

I draw() skriver du all funksjonalitetet som kjøres for å tegne. Skal du lage geometriske figurerer er det lurt å gjøre dette her. Denne funksjonen kjører helt til du kaller noLoop(). Du kan også kalle noLoop() i setup() for å la programmet kjøre kun en gang.

Verken setup() eller draw() returnerer en verdi og tar derfor returneringstypen void.

Et godt utgangspunkt kan se slik ut:

void setup {

size(200,200);

noLoop();

}

 

void draw() {

point(width/2, height/2);

}

Dette lille programmet setter en prikk midt på skjermen.

 

Farger
Syntaks introdusert: color(), background(), fill(), stroke(), noFill(), noStroke()

Farger kan få prosjektet til å se mye flottere ut, og kan også være en effektiv måte å gruppere forskjellig informasjon. Processing støtter forskjellige typer farger, men her bruker vi RGB-baserte farger hvor hver av verdiene settes til et tall mellom 0 og 255.

color() brukes for å sette en farge til en variabel av typen color. F.eks
color c1 = color(0,0,255);
Dette gjør det enkelt å referere til farger senere i programmet og slik gjøre det enkelt å holde en fargeplan. Du kan bruke fargevariabler eller fargeverdier igjennom programmet
background() tar en farge og setter denne til bakgrunnen. For å lage en applikasjon der ting skrevet til lerretet ikke blir der i neste runde av draw() må du kalle background() i draw. Det kan være lurt å la background være det første som blir kalt i draw().

Objektene du tegner på skjermen i Processing er litt som ting i Photoshop og andre steder, de har en linje som følger formen og innmat. Du kan sette hvilken farge disse har ved å kalle fill() og/eller stroke() før du tegner en form. Fargene du setter med disse metodene vil være der til du setter de på nytt.

Siden vi allererede har vært igjennom blokker og løkker la oss tegne noen farger. Denne lille kodesnutten kommer til å tegne rødt, grønt og blått i steg fra svart (0) til full farge (255)

/* Skriver ut fargene i RGB-fargebånd. Går i steg på 2px per verdi fra 0 til 255, 

skriver ut hver farge i 50 pixler brede remser. */ 

 

void setup() { 

size(3*50, 3*255); 

// Setter størrelsen til antall bånd 

//* 3 og antall steg *3. 

noStroke(); 

//Bruker ikke rand-farging 

background(255); 

//I utgangspunktet hvit farge 

noLoop(); 

// Programmet eksekverer og stopper. Draw kun kalt en gang. 


 // Tegner rødt
 void draw() { 
 for(int r = 0; r < 255; r++){
 fill(r,0,0); 
 rect(0,r*3,50,3); 

 // Tegner grønt 
 for(int g = 0; g < 255; g++){
 fill(0,g,0); 
 rect(50,g*3,50,3); 

// Tegner blått 
for(int b = 0; b < 255; b++){
 fill(0,0,b); 
 rect(100,b*3,50,3); 
} 

 

Mus

La oss returnere til punktene. Disse ønsket vi å ikke tegne selv siden de er veldig små, og du først ser morsomme resultater når du har mange av dem.

+ Skriv en setup() funksjon som setter størrelsen til 500×500 pixler. Husk å ikke ta med kallet til noLoop(). Ta deretter å skriv en draw() funksjon som plasserer en prikk midt på skjermen. Bytt nå ut prikkens x-koordinat med mouseX og prikkens y-koordinat med mouseY. Beveg musepekeren rundt på skjermen.

+ Forsøk å skrive bakground(155) i begynnelsen av draw() funksjonen. Hva skjer? Ta den vekk. Hva skjer nå?

 

Arrays og online ressurser

Et annet viktig element innen programmering er arrays. Denne kan være av alle datatyper og er en organisert samling av data. Gå inn på processing.org og se etter array i dokumentasjonen.

+ Forsøk å opprett en array med 10 forskjellige tekststrenger. Skriv deretter ut verdien av hver av disse ved hjelp av en for-løkke og println. NB: Dette er vanskelig. Se om du finner ut hvordan du kan gjøre dette ved hjelp av google, eller kontakt meg.

 

Jeg håper å komme tilbake med mer Processing-kode snart, men i mellomtiden anbefaler jeg tutorialene som ligger ute på Processing.org. Temaer jeg ønsker å dekke neste gang inkluderer å lese til og fra fil, XML og objektorientering.

 

Bildet er tatt fra Flickr brukeren blprnt. Det er lisensiert under en Creative Commons lisens. 


1 thought on “Visuell programmering i Processing”

Leave a Reply

Your email address will not be published. Required fields are marked *