Ennen kuin ryhdymme määrittelemään funktioita ja piirtämään
animaatioita, meidän täytyy tutustua Processing-ohjelmoinnin
funktioihin setup()
ja draw()
. Kun kirjoitetaan
Processing-ohjelmia, jotka toimivat ns. aktiivisessa tilassa
- funktion
setup()
sisällä tehdään valmistelevat toimenpiteet, kuten piirtoikkunan koon asettaminen - funktion
draw()
sisällä piirretään.
Seuraava esimerkki havainnollistaa näiden funktioiden käyttämistä.
void setup ()
{
// alustavat toimenpiteet
size (400, 400); // asetetaan ikkunan koko
noLoop (); // ei piirretä animaatioita (vielä)
}
void draw ()
{
// piirtäminen
rect (200, 100, 150, 50);
}
Jos halutaan kirjoittaa omia funktioita tai piirtää animaatioita, täytyy käyttää Processing-kielen funktioita
setup()
jadraw()
. Ensimmäisessä tehdään alustavat toimenpiteet, toisessa piirretään. Jos ei piirretä animaatioita, funktiossasetup()
kannattaa viimeisenä antaa komentonoLoop()
, joka keventää tietokoneen kuormaa.
Kaikki aiemmissa esimerkeissämme käytetyt piirtokomennot kuten
size()
ja rect()
ovat Processing-ohjelmointikielen
funktioita. Kohdat, joissa funktiota käytetään ohjelmassa ovat
funktiokutsuja. Funktioita on valmiina suuri joukko, ja ohjelmoija
voi kirjoittaa niitä lisää.
Edellisessä esimerkissä on määritelty funktio setup()
. Katsotaanpa
tarkemmin, mistä funktion määrittely koostuu.
void setup ()
{
size (400, 400);
noLoop ();
}
Kaikkein mystisin on ensimmäinen rivi. \[ \underbrace{\texttt{void}}_\text{paluuarvo “tyhjä”} \overbrace{\texttt{setup}}^\text{funktion nimi} \underbrace{\texttt{()}}_\text{ei parametreja} \] Ensimmäinen rivi kertoo, että
- funktio ei anna tuloksena lukua tms. eli paluuarvo on tyhjä: englannin kielen sana void tarkoittaa tyhjää
- funktion nimi on
setup
- funktio ei tarvitse mitään lisätietoja eli parametreja toimiakseen: sulkujen sisällä ei ole mitään.
Jokaisella funktiolla on nimi. Funktiolla voi olla lisäksi
- paluuarvo eli luku tms. jonka funktio antaa tuloksena
- parametreja eli lähtötietoja, jotka funktio tarvitsee toimiakseen; esimerkiksi funktio
size()
tarvitsee parametreina piirtoikkunan leveyden ja korkeuden.
Ensimmäisen rivin jälkeinen osa on funktion runko, joka kirjoitetaan lauselohkon sisään.
{
size (400, 400);
}
Funktion määrittelyssä on seuraavat osat:
paluuarvon_tyyppi nimi (parametrit) { funktion runko }Tässä kappaleessa funktioilla ei ole paluuarvoa, eli paluuarvon tyyppi on aina
void
.
Piirretään alla oleva kuva, jossa on päällekkäisiä ympyröitä eri kohdissa piirtoikkunaa.
void setup ()
{
size (400, 400);
noLoop ();
}
// funktiolla ei paluuarvoa, parametreina kaksi liukulukua
void piirraYmpyraPari (float x, float y)
{
final float HALKAISIJA = 30; // kunkin ympyrän halkaisija
final float SADE = HALKAISIJA / 2.0; // kunkin ympyrän säde
ellipse (x, y - SADE, HALKAISIJA, HALKAISIJA); // ylempi ympyrä
ellipse (x, y + SADE, HALKAISIJA, HALKAISIJA); // alempi ympyrä
}
void draw ()
{
// voimme käyttää määrittelemäämme funktiota piirtämisessä
piirraYmpyraPari (100, 150); // ympyräpari kohtaan (100, 150)
piirraYmpyraPari (200, 100);
piirraYmpyraPari (300, 190);
}
Koska ympyröiden piirtäminen halutaan tehdä moneen kertaan epäsäännöllisissä kohdissa, sitä varten kannattaa kirjoittaa funktio.
- Annetaan funktion nimeksi
piirraYmpyraPari
. - Funktio tarvitsee kaksi lähtötietoa eli parametria: ympyräparin
keskikohdan \(x\)- sekä \(y\)-koordinaatin. Annetaan näille
nimiksi
x
jay
. Molemmat ovat liukulukuja eli tyyppiäfloat
. - Funktio ei anna tuloksena mitään lukua, eli sillä ei ole
paluuarvoa. Niinpä paluuarvon tyyppi on
void
.
Ohjelmakoodi näyttää seuraavalta.
<<funktio-ympyraparit>>
Toisinaan funktioiden nimet esitetään tekstissä muodossa
piirraYmpyraPari()
ilman paluuarvon tai parametrien tyyppejä tai parametrien nimiä. Joskus myös tyypit sekä parametrien nimet mainitaan tyyliinvoid piirraYmpyraPari (float x, float y)
Mistä tiedetään, etteivät kahdessa eri funktiossa olevat samannimiset muuttujat mene keskenään sekaisin?
Muuttujan näkyvyysalueella tarkoitetaan sitä ohjelman osaa, jossa muuttujaa voidaan käyttää. Muuttujan näkyvyysalue on se lauselohko, jossa muuttuja määritellään, sekä lauselohkon sisällä olevat muut lauselohkot.
Kaikkien lauselohkojen ulkopuolella määritellyt muuttujat ovat ns. globaaleja muuttujia ja näkyvät kaikissa lauselohkoissa.
Samat säännöt pätevät myös vakioille.
Parametrien näkyvyysalue on sen funktio runko, jonka ensimmäisellä rivillä parametrit määritellään.
Alla olevassa ohjelmakoodissa on kaksi funktiota, joissa molemmissa
määritellään muuttuja n
. Kukin muuttuja n
näkyy vain oman
funktionsa rungossa, joten ne ovat käytännössä kaksi eri muuttujaa.
Sama pätee molempien funktioiden parametreihin x
ja y
.
// tikkataulun halkaisija on globaali vakio, joka näkyy kaikissa
// funktioissa
final float TAULUN_H = 70;
void setup ()
{
// alkuasetukset
size (800, 500);
colorMode (HSB, 100);
noStroke (); // ei ääriviivoja
noLoop ();
}
// piirretään yksittäinen tikkataulu parametreina annettuun kohtaan
void piirraTikkataulu (float x, float y)
{
final float N = 10; // tikkataulun sisäkkäisten ympyröiden lukumäärä
final float ASKEL = TAULUN_H / N; // ympyröiden halkaisijoiden ero
// seuraavaksi piirrettävän ympyrän halkaisija
float ympyranHalkaisija = TAULUN_H;
for (int n = 1; n <= N; n++)
{
if (n % 2 == 1)
fill (100);
else
fill (0);
ellipse (x, y, ympyranHalkaisija, ympyranHalkaisija);
ympyranHalkaisija -= ASKEL;
}
}
// piirretään lkm tikkataulua siten, että ensimmäisen keskikohta on
// (x, y) ja muut ovat siitä oikealle
void piirraTikkatauluRivi (int lkm, float x, float y)
{
float kpX = x; // tikkataulun keskipisteen x-koordinaatti
for (int n = 1; n <= lkm; n++)
{
piirraTikkataulu (kpX, y);
kpX += TAULUN_H;
}
}
void draw ()
{
piirraTikkatauluRivi (3, 100, 100);
piirraTikkatauluRivi (6, 50, 200);
piirraTikkatauluRivi (4, 350, 300);
piirraTikkataulu (70, 400);
}
Ohjelmoijat käyttävät funktioita mm.
- usein tarvittujen toimintojen automatisointiin (esim. tikkataulun piirtäminen useaan eri kohtaan tai peräti useassa eri ohjelmassa)
- ohjelmakoodin selkiyttämiseen (yksittäisen tikkataulun piirtämisen erottaminen tikkataulurivin piirtämisestä).
- Alla on määritelty funktio
piirraS()
. Kopioi koodi Processing-ohjelmaan ja kirjoita funktiodraw()
, jossa kutsutaan funktiotapiirraS()
useaan kertaan, sekä funktiosetup()
, jossa määritellään piirtoikkunan koko ja kutsutaan funktiotanoLoop()
.void piirraS (float x, float y) { colorMode (HSB, 100); final float H = 10, S = H / 2; fill (100); ellipse (x - S, y, H, H); ellipse (x + S, y, H, H); fill (0); ellipse (x - S, y, S, S); ellipse (x + S, y, S, S); }
- Alla olevassa ohjelmassa on virhe, joka johtuu vakion
näkyvyysalueesta. Kopioi koodi Processing-ohjelmaan ja korjaa
virhe.
void setup () { final float VARISAVY = 20; size (400, 400); colorMode (HSB, 100); background (VARISAVY, 100, 100); noLoop (); } void draw () { fill (VARISAVY + 20, 100, 100); rect (100, 100, 100, 100); }
- Määrittele funktio
void piirraYmpyra (float x, float y)
joka piirtää ympyrän, jonka keskipiste on kohdassa
(x, y)
. Ympyrän halkaisija on 20. Käytä kirjoittamaasi funktiota yhdessä funktioidensetup()
jadraw()
kanssa alla olevan tyyppisen kuvan piirtämiseen. Voit valita piirtoikkunan koon sekä ympyröiden paikat vapaasti.void setup () { size (400, 400); noLoop (); } void piirraYmpyra (float x, float y) { final float HALKAISIJA = 20; ellipse (x, y, HALKAISIJA, HALKAISIJA); } void draw () { piirraYmpyra (40, 90); piirraYmpyra (120, 100); piirraYmpyra (150, 170); piirraYmpyra (350, 300); }
- Määrittele funktio
void piirraNelioPari (float x, float y)
joka piirtää kaksi neliötä vierekkäin siten, että vasemmanpuoleisen neliön vasen yläkulma on kohdassa
(x, y)
. Käytä kirjoittamaasi funktiota yhdessä funktioidensetup()
jadraw()
kanssa alla olevan tyyppisen kuvan piirtämiseen. Neliön sivun pituus on 20. Muut mitat voit valita vapaasti.void setup () { size (400, 400); noLoop (); } void piirraNelioPari (float x, float y) { final float SIVU = 20; rect (x, y, SIVU, SIVU); rect (x + SIVU, y, SIVU, SIVU); } void draw () { piirraNelioPari (50, 100); piirraNelioPari (300, 30); piirraNelioPari (250, 270); }
- Määrittele funktio
void piirraRasti (float x, float y, float varisavy)
joka piirtää rastin kohtaan
(x, y)
käyttämällä värisävyävarisavy
. Jos rastin keskikohta on pisteessä(x, y)
, niin vasen yläkulma on kohdassa(x - 10, y - 10)
. Piirrä funktion avulla alla olevan kaltainen kuva, jossa on erivärisiä rasteja mustalla taustalla.void setup () { size (400, 400); colorMode (HSB, 100); background (0); noLoop (); } void piirraRasti (float x, float y, float varisavy) { final float S = 10; stroke (varisavy, 100, 100); line (x - S, y - S, x + S, y + S); line (x - S, y + S, x + S, y - S); } void draw () { piirraRasti (30, 50, 0); piirraRasti (300, 350, 17); piirraRasti (70, 200, 62); piirraRasti (300, 50, 35); }
- Alla olevan ohjelman pitäisi piirtää viisi pystyriviä ympyröitä,
mutta pystyrivejä piirretäänkin vain yksi. Kopioi koodi
Processing-ohjelmaan ja korjaa virhe.
int n; void setup () { size (400, 400); noLoop (); } void draw () { for (n = 1; n <= 5; n++) piirraPystyrivi (n * 20); } void piirraPystyrivi (float x) { final float HALKAISIJA = 10; for (n = 1; n <= 10; n++) ellipse (x, n * HALKAISIJA, HALKAISIJA, HALKAISIJA); }
-
void setup () { size (600, 400); noLoop (); } <<funktio-silmat>> void draw () { piirraS (50, 50); piirraS (400, 100); piirraS (300, 200); }
- Vakio
VARISAVY
täytyy siirtää globaaliksi vakioksi, jotta se näkyy molemmissa funktioissa.final float VARISAVY = 20; void setup () { size (400, 400); colorMode (HSB, 100); background (VARISAVY, 100, 100); noLoop (); } void draw () { fill (VARISAVY + 20, 100, 100); rect (100, 100, 100, 100); }
-
<<funktio-ympyra>>
-
<<funktio-vierekkaiset-neliot>>
-
<<funktio-rasti>>
- Muuttuja
n
täytyy määritellä erikseen funktioissadraw()
japiirraPystyrivi()
.