Kurssin viimeisimmän version löydät täältä: O1: 2024
Luku 2.7: Käynnistyksiä ja käyttöliittymiä
Tästä sivusta:
Pääkysymyksiä: Miten kirjoitan ja tallennan kokonaisen Scala-ohjelman? Mistä Scala-sovelluksen suorittaminen alkaa? Miten luen näppäimistösyötettä sovelluksen käyttäjältä? Nyt kun olen laatinut käsitteellisen mallin pelimaailmasta, miten määrittelen graafisen käyttöliittymän, joka tekee tämän maailman näkyväksi?
Mitä käsitellään? Sovelluksen käynnistysolio (App
).
Näppäimistösyöte (readLine
). Graafisten käyttöliittymien alkeita
(o1.View
).
Mitä tehdään? Enimmäkseen ohjelmoidaan ohjeiden mukaisesti.
Suuntaa antava työläysarvio:? Reilu tunti.
Pistearvo: A60.
Oheisprojektit: Ave (joka luodaan itse), Odds, Pikkusovelluksia (uusi), FlappyBug.
Johdanto
Olet luonut olioita ja kutsunut metodeita. Metodien kutsuminen tapahtunut lähinnä REPLissä, joka sopii siihen tarkoitukseen hyvin. Kuitenkaan REPLiin kirjoitetuista käskyistä ei muodostu kokonaisuutta, joka jäisi talteen, jonka voisi kätevästi myöhemmin ajaa uudestaan, jota voisi muokata tai jonka voisi kopioida jonkun toisen käytettäväksi. Näitä tarkoituksia varten on ohjelma tallennettava tiedostoon.
Kokeillaan.
Perinteikäs ohjelma
Jo muinaiset roomalaiset aloittivat kunkin uuden ohjelmointikielen tai muun ohjelmointiteknologian opettelun käyttämällä sitä ns. "Hello, World" -ohjelman tekemiseen. Tällainen ohjelma yksinkertaisesti tervehtii käyttäjää.
Laaditaan ja tallennetaan nyt ohjelma, jossa on pari Scala-kielistä käskyä ja jonka voi määrätä suoritettavaksi haluttaessa. Käytetään vaikkapa näitä tulostuskäskyjä:
println("Ave, Munde!")
println("No avepa ave sinnekin!")
Luo tätä kokeilua varten Eclipsessä uusi projekti:
- Varmista (oikean yläkulman nappuloilla), että olet Eclipsen Scala-perspektiivissä etkä esimerkiksi Java-perspektiivissä.
- File ‣ New ‣ Scala Project
- Kirjoita projektille nimeksi vaikkapa Ave.
- Valitse Create separate folders for sources and class files, jos tämä asetus ei jo ole valittuna.
- Paina Finish. Ave-projekti näkyy nyt Eclipsen Package Explorerissa.
Luo uusi tyhjä kooditiedosto:
- Klikkaa oikealla napilla Ave-projektin sisällä olevaa
src
-kansiota ja valitse New ‣ File. (Jos moista ei löydy, valitse: New ‣ Other ‣ General ‣ File.) - Siirry kohtaan File name ja kirjoita sinne:
Ave.scala
- Paina Finish. Tiedosto näkyy nyt projektin sisällä ja avautuu myös Eclipsen editoriin.
Ensimmäinen yritys kirjoittaa tervehdysohjelma:
- Kirjoita yllä olevat tulostuskäskyt luomaasi tyhjään tiedostoon ja tallenna.
- Havaitse: Eclipse koristelee koodin joulun väreillä, ja Problems-välilehti kertoo tarkemmin: Errors: expected class or object definition. Mistä on kyse?
Virheilmoituksen taustalla on se, että emme ole jäsentäneet sovellustamme kelvolliseksi olio-ohjelmaksi. Kun laadimme Scala-sovellusta, on määriteltävä olio, joka toimii suorituksen "lähtöpisteenä". Tuo olio voi sitten aktivoida (kutsua) muita ohjelman osia.
Esimerkiksi GoodStuff-projektissa oli käynnistysoliona GoodStuff
-niminen
yksittäisolio, josta käsin käynnistit sovelluksen ainakin luvussa 1.2. Käynnistysolio
löytyy myös Pong-projektista nimellä PongApp
. Tervehdyssovellukseltamme tällainen
lähtöpiste kuitenkin vielä puuttuu.
Käynnistysolio
Kirjoitetaan käynnistysolio. Tässä sille aihio:
object IkiomaSovellukseni extends App {
// Tämä on käynnistysolio.
// Tänne käskyt, jotka suoritetaan, kun sovellus ajetaan.
}
App
-tietotyypille
on määritelty. Olio edustaa nyt sovellusta kokonaisuutena ja
tarjoaa mahdollisuuden käynnistää sovellus.Tässä vaiheessa kurssia voit siis ajatella näin: extends App
tarkoittaa, että olio
toimii sovelluksen käynnistysoliona. Myöhemmin (esim. luvussa 7.2) osoittautuu, että
extends
-sana on muissakin yhteyksissä hyvin käyttökelpoinen.
Kokonainen pikkuruinen Scala-ohjelma
Suuremmassa ohjelmassa luokkia ja yksittäisolioita voi olla kymmeniä, satoja tai enemmän. Tervehtivään miniohjelmaamme tarvitsemme vain yhden olion, jonka sisään tulostuskäskyt kirjoitetaan ja joka myös toimii käynnistysoliona.
Muokkaa Ave.scala
-tiedostoa niin, että sen sisältö on tällainen:
Sisennysvinkki
Eclipsessä saa sisennykset laitettua kätevästi valitsemalla
sisennettävät rivit ja painamalla tabulaattorinäppäintä.
Sisennysten poistaminen onnistuu vastaavasti: Shift+Tab
.
object Ave extends App {
println("Ave, Munde!")
println("No avepa ave sinnekin!")
}
Nyt ohjelman voi ajaa esimerkiksi valitsemalla Ave.scala
-tiedoston ja sitten
Run ‣ Run As ‣ Scala Application. Kokeile. Huomaa, että tulosteet
ilmestyvät Eclipsen Console-välilehdelle, joka on alhaalla REPLin lähellä.
(Tuo oli sama tapa, jolla käynnistit GoodStuffin ja Pongin luvussa 1.2. Vaihtoehtoisia tapoja esiteltiin siellä.)
Olet nyt tehnyt kokonaisen Scala-sovelluksen. Lähetä se tällä lomakkeella.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Syötteen lukeminen
Äsken laadittu ohjelma tuottaa aina saman tulosteen, eikä ohjelman käyttäjällä ole mahdollisuutta vaikuttaa sen toimintaan ohjelma-ajon aikana tai muutenkaan. Useimmat käytännön sovellusohjelmat kuitenkin tarjoavat käyttäjilleen jonkinlaisen mahdollisuuden antaa ohjelmalle syötettä (input) joko suorasti tai epäsuorasti. Tässä joitakin esimerkkejä:
- Ohjelmassa on graafinen käyttöliittymä, jonka osia klikkailemalla käyttäjä voi kertoa ohjelmalle, mitä haluaa sen tekevän.
- Ohjelma osaa ladata kiintolevylle tallennettuja tiedostoja, joista se saa dataa käsiteltäväkseen.
- Tekstikonsolissa toimiva sovellus osaa pysähtyä odottamaan käyttäjän näppäimistöltä syöttämiä tekstirivejä.
Palataan graafisiin käyttöliittymiin kohta ja tiedostojen lataamiseen luvussa 12.2. Ensin tutkailemme kolmantena mainittua tapaa, jolla ohjelma ja käyttäjä voivat vuorovaikuttaa.
Sovellus tekstikonsolissa
Laaditaan ohjelma, joka toimii Eclipsen Console-välilehdellä seuraavasti:
Seis! Kuka siellä? posteljooni Petskin Ave, posteljooni Petskin!
Enter
-painalluksen jälkeen.readLine
-funktio
Funktio readLine
vastaanottaa eli "lukee" yhden rivin käyttäjän antamaa syötettä.
Ohjelman suoritus pysähtyy readLine
-kutsuun, kunnes syöte on annettu. Funktio palauttaa
käyttäjän antaman syötteen String
-tyyppisenä arvona.
Sen avulla yllä kuvatun ohjelman voi toteuttaa seuraavasti.
import scala.io.StdIn._
object Tervehdysohjelma extends App {
println("Seis! Kuka siellä?")
val nimi = readLine()
println("Ave, " + nimi + "!")
}
readLine
-funktion käyttö sujuu kätevimmin, kun otat sen ensin
käyttöön import
-käskyllä. Nimi StdIn
on lyhenne sanoista
standard input, jotka viittavat tässä käytännössä
tekstikonsolilta luettavaan syötteeseen.Kirjoita itse tällainen ohjelma. Voit joko muokata jo palauttamaasi Ave
-oliota tai
tehdä uuden tiedoston.
Aja ohjelma. Katso, mitä konsoliin tulostuu, ja vastaa ohjelman kysymykseen. (Huom. Scala IDE:n "erikoisuuksista" johtuen saatat joutua näpäyttämään tekstikonsolia hiirellä ennen kuin saat syötettyä sinne merkkejä näppäimistöllä.)
Mainittakoon vielä, että readLine
-funktiosta on myös kätevä variaatio, joka ottaa
parametrikseen merkkijonokehotteen, tulostaa sen käyttäjän nähtäväksi ja lukee syötteen
samalta riviltä, jolle kehotekin tulostettiin. Esimerkiksi seuraava ohjelma:
val nimi = readLine("Seis! Kuka siellä? ")
println("Ave, " + nimi + "!")
Tuottaa tällaisen tulosteen:
Seis! Kuka siellä? posteljooni Petskin Ave, posteljooni Petskin!
readLine
ja Scala IDE:n REPL
Scala IDE:en sisäänrakennettu REPL on osin prototyyppiasteella.
Siinä on eräitä puutteita, joista yksi on se, ettei syötteen
lukeminen toimi niin kuin voisi toivoa. Esimerkiksi
readLine
-käskyn käyttäminen tässä REPLissä tuottaa
virheilmoituksen.
Odds-tehtävä (osa 5/9)
Kehitellään pieni testiohjelma lukujen 2.4 ja 2.5 Odds-projektiin. Ohjelma luo
käyttäjän antaman syötteen perusteella Odds
-olioita ja raportoi niiden metodien
palautusarvoja tulostein.
Tehtävänanto
Käytetään tässä tehtävässä kahta Odds-projektin tiedostoa. Odds.scala
on edeltä tuttu;
se määrittelee Odds
-luokan. Tutustu nyt myös tiedostoon OddsTest1.scala
. Se sisältää
käynnistysolion määrittelyn, joka ei kuitenkaan ole vielä ihan valmis, sillä se ei käytä
Odds
-luokkaa laisinkaan.
Täydennä käynnistysolio sellaiseksi, että se tuottaa täsmälleen seuraavan ajoesimerkin mukaisen tulosteen. (Syötteet voivat tietysti olla toisiakin kuin esimerkissä.)
Please enter the odds of an event as two integers on separate lines. For instance, to enter the odds 5/1 (one in six chance of happening), write 5 and 1 on separate lines. 7 2 The odds you entered are: In fractional format: 7/2 In decimal format: 4.5 Event probability: 0.2222222222222222 Reverse odds: 2/7 Odds of happening twice: 77/4 Please enter the size of a bet: 50.0 If successful, the bettor would claim 225.0 Please enter the odds of a second event as two integers on separate lines. 10 1 The odds of both events happening are: 97/2 The odds of one or both happening are: 70/29
Ohjeita ja vinkkejä
- Voit kokeilla käynnistää
OddsTest1
-ohjelman jo annetussakin muodossa. Se kyllä lukee syötettä, muttei vielä tuota ihan oikeanlaista tulostetta. - Sinun täytyy lisätä
Odds
-olion luovat käskyt ja kutsua luotujen olion metodeita sopivissa kohdissaOddsTest1
-ohjelman koodia.- Älä muokkaa
Odds
-luokkaa äläkä kopioi sitä tai osia siitäOddsTest1.scala
-tiedostoon. KäytäOdds
-luokkaa sellaisenaan. - Käskyjen järjestys on merkityksellinen.
Valitse ajatuksella kohdat, joissa luot
uudet
Odds
-oliot. Oliohan voidaan luoda vasta sitten, kun tarvittavat syötteet on luettu, mutta toisaalta olio on luotava ennen kuin sen metodeita voi kutsua.
- Älä muokkaa
OddsTest1
jaOdds
ovat samassa pakkauksessa, joten voit luodaOddsTest1
-ohjelmassaOdds
-olioita helposti lisäämättäimport
ia.- Huomaat, että annetussa koodissa on käytetty
readInt
- jareadDouble
-nimisiä funktioita. Ne ovat samankaltaisia kuin yllä esiteltyreadLine
, mutta tulkitsevat käyttäjältä saadut merkit lukuarvoina. EsimerkiksireadInt
palauttaaInt
-tyyppisen arvon eikäString
-tyyppistä. - Kohdassa, jossa pitää laskea todennäköisyys sille, että tapahtuma
tapahtuu kahdesti, voit käyttää
both
-metodia. (Esimerkki: kahden kuutosen heittäminen nopalla on sitä, että heitetään nopalla kuutonen ja heitetään nopalla toinenkin kuutonen.)
Palauttaminen
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Lisäharjoitus: toisteisuutta vähemmäksi metodilla
OddsTest1
:n koodissa toistuu sama rakenne kahdesti: luetaan kaksi lukua ja
käytetään niitä Odds
-olion konstruktoriparametreina. Vältä turha toisto toteuttamalla
tämä ohjelma hieman toisella tavalla:
- Laadi
OddsTest1
-yksittäisoliolle parametriton vaikutuksellinen metodirequestOdds
, joka lukee kaksi kokonaislukua, luo niiden perusteellaOdds
-olion ja palauttaa viittauksen luomaansa olioon. - Kutsu
requestOdds
ia (kahdesti).
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Sovellus graafisella käyttöliittymällä
Ohjelman aihepiiriä kuvaa ohjelmoijan laatima malli; käyttöliittymä esittää tuon mallin jossakin käyttäjän havaittavissa olevassa muodossa, yleensä kuvina tai tekstinä (luku 1.2). Käyttöliittymä voi myös tarjota käyttäjälle mahdollisuuden vuorovaikuttaa mallin kanssa ja muuttaa mallin tilaa. Moneen sovellukseen sopii graafinen käyttöliittymä eli GUI (graphical user interface), joka rakentuu erilaisista visuaalisista osasista ja esitetään tyypillisesti omassa ikkunassaan.
Malliesimerkki
Edellisessä luvussa loimme mallin FlappyBug-pelille luokista Bug
, Game
ja Obstacle
.
Ennen kuin teemme graafisen käyttöliittymän tuolle mallille, aloitetaan hieman
yksinkertaisemmasta. Tässä mallissa on vain yksi luokka, Palikka
:
class Palikka(val koko: Int, val sijainti: Pos, val vari: Color) {
override def toString = this.vari + " block at " + this.sijainti
}
Käyttöesimerkki:
import o1._, o1.palikka._import o1._ import o1.palikka._ val malli = new Palikka(20, new Pos(300, 50), Gray)malli: Palikka = Gray block at (300.0,50.0)
Luodaan graafinen käyttöliittymä, jolla voi esittää ikkunassa tällaisen palikan taustaa vasten.
Pohjustava kertaus
Muistatko, kun luvun 2.4 lopussa kirjoitimme luokan Henkilo
ja loimme siitä ilmentymiä?
Teräsmiestä kuvaavan ilmentymän loimme tällaisella käskyllä:
val terasmies = new Henkilo("Clark") { def lenna = "WOOSH!" }
Tuo luomamme olio on henkilöluokan ilmentymä, minkä lisäksi määrittelimme sille
lenna
-metodin. Metodin määrittely yhdelle luokan ilmentymälle tuohon tapaan tulee kohta
tarpeeseen.
Käyttöliittymäikkuna esiin: o1.View
Graafista käyttöliittymää ei joudu laatimaan joka sovellukseen "tyhjästä" pikseli kerrallaan, vaan apuna käytetään jotakin tarkoitukseen sopivaa ohjelmakirjastoa.
GUI-kirjastoja on monia. Eräs tunnetuista kirjastoista on nimeltään Swing; sitä käytämme luvussa 12.3 sijoittaaksemme ruudulle nappuloita, tekstikenttiä ja sensellaista. Nyt käytämme O1:n omaa GUI-kirjastoa, joka on erityisen näppärä geometrisia kuvioita hyödyntävien pienten sovellusten laatimiseen (ja jota voi myös yhdistellä Swingin kanssa).
Pakkaus o1
tarjoaa tyypin View
, jolla nimensä mukaisesti saa esiin näkymän johonkin
mallina toimivaan olioon. Käytetään mallina tätä Palikka
-luokan ilmentymää:
val malli = new Palikka(20, new Pos(300, 50), Gray)malli: Palikka = Gray block at (300.0,50.0)
Luodaan View
-olio. Se kuvaa sellaisen graafisen käyttöliittymän ikkunan, joka toimii
näkymänä yhteen Palikka
-tyyppiseen olioon.
val nakyma = new View(malli) { def makePic = { val tausta = rectangle(500, 500, Black) val palikanKuva = rectangle(malli.koko, malli.koko, malli.vari) tausta.place(palikanKuva, malli.sijainti) } }
View
-luokan ilmentymä. Konstruktoriparametriksi
annetaan viittaus malliin, joka näkymässä on tarkoitus esittää.View
-oliot yleensäkin, sille on tässä määritelty vaikutukseton
metodi makePic
, joka muodostaa kuvan mallista. Kuva on tyyppiä
Pic
ja voimme muodostaa sen tutuilla välineillä.Tuo koodi ei vielä tuonut mitään graafista näkyviin, vaan sitä varten meidän on
käynnistettävä käyttöliittymämme. Kaikilta View
-olioilta löytyy vaikutuksellinen
metodi, joka tekee juuri sen. Seuraava käsky tuo esiin alkeellisen käyttöliittymämme.
Kokeile.
nakyma.start()
Kukin View
-olio osaa piirtää itsensä näkyviin käyttäen makePic
-metodinsa palauttamaa
kuvaa. Saamme esiin ikkunan, jossa on palikan kuva mustalla taustalla. Ikkunan
kulmassa on myös sen pienentämiseen ja sulkemiseen sopivat nappulat; tuon vähäisen
vuorovaikutusmahdollisuuden View
tarjoaa ilman lisämäärittelyjäkin.
Sovellus graafisella näkymällä
Yhdistetään luvussa esitellyt asiat: tehdään käynnistysolio graafiselle sovellukselle.
object PalikkaApp extends App {
val tausta = rectangle(500, 500, Black)
val palikka = new Palikka(20, new Pos(300, 50), Gray)
val nakyma = new View(palikka, "Palikkaohjelma") {
def makePic = {
val palikanKuva = rectangle(palikka.koko, palikka.koko, palikka.vari)
tausta.place(palikanKuva, palikka.sijainti)
}
}
nakyma.start()
}
View
-oliolle.
Tämä teksti tulee näkyviin ikkunan otsikkoriville.start
-metodia, joka käynnistää
käyttöliittymämme. Käynnistysolion koodi on tämän jälkeen
suoritettu mutta sovelluksemme pyörii edelleen erillisessä
ikkunassaan kunnes käyttäjä toisin haluaa.Tämä ohjelma löytyy Pikkusovelluksia-projektin pakkauksesta o1.palikka
; voit ajaa sen.
Lisätieto: makePic
abstraktina metodina
Kysymys: mitä tapahtuu, jos poistat makePic
-metodin määrittelyn
äskeisestä sovelluksesta?
Vastaus: saat melko selväsanaisen käännösaikaisen virheilmoituksen,
joka kertoo, ettet voi luoda sellaista View
-oliota, jolla ei ole
makePic
-metodia.
Selitys: View
-luokka on määritelty siten, että vaikka siellä ei
olekaan toteutusta makePic
-metodille, niin se edellyttää
tuollaisen toteutuksen olevan olemassa kaikilla View
-tyyppisillä
oliolla. Teknisemmin sanoen makePic
on luokan View
abstrakti
metodi. Abstrakteista metodeista kerrotaan tarkemmin luvussa 7.2.
Olipas tylsä ohjelma. Nyt se FlappyBug.
FlappyBug-tehtävä (osa 3/16: käyttöliittymän alkua)
Pohjustus
Tässä on pohjakoodi käynnistysoliolle. Se löytyy myös projektin tiedostosta
FlappyBugApp.scala
.
package o1.flappy.gui
import o1._
import o1.flappy._
object FlappyBugApp extends App {
val sky = rectangle(ViewWidth, ViewHeight, LightBlue)
val ground = rectangle(ViewWidth, GroundDepth, SandyBrown)
val trunk = rectangle(30, 250, SaddleBrown)
val foliage = circle(200, ForestGreen)
val tree = trunk.onto(foliage, TopCenter, Center)
val rootedTree = tree.onto(ground, BottomCenter, new Pos(ViewWidth / 2, 30))
val scenery = sky.place(rootedTree, BottomLeft, BottomLeft)
val bugPic = Pic("ladybug.png")
def rockPic(obstacle: Obstacle) = circle(obstacle.radius * 2, Black)
// INSERT YOUR OWN CODE BELOW.
}
scenery
viittaa
lopputulokseen. Ei ole välttämätöntä, että ymmärrät, miten tämä
kuva on muodostettu, mutta löydät selityksen luvun 2.5 lopun
vapaaehtoisesta materiaalista.bugPic
viittaa kuvaan, jota käytämme ötökän
esittämiseen käyttöliittymässä.rockPic
muodostaaksesi annettua estettä
vastaavan kuvan.Ensin muistutus: älä vain unohda pyytää vinkkiä neuvontafoorumeillamme tai harjoitusryhmässä. Älä hakkaa päätäsi seinään yksin!
Tässä tehtävänannossa on kaksi vaihetta:
Vaihe 1/2: esiin vain tausta
- Luo uusi olio, joka toimii aihealueen mallina. FlappyBug-pelin
malliksi sopii
Game
-tyyppinen olio.Game
-olion saa luotua ilmaisullanew Game
; konstruktoriparametreja ei tarvita (luku 2.6).- Luo myös muuttuja, joka viittaa tuohon
Game
-olioon. Nimeä se haluamallasi tavalla.
- Luo näkymä (
View
), joka esittää tuonGame
-olion ikkunassa.- Laita otsikoksi "FlappyBug".
- Idea on hyvin samantapainen kuin edeltävässä
palikkaohjelmassa, mutta nyt mallina on
Palikka
-olion sijaanGame
-olio. VälitäView
-oliota luodessasi parametreiksi sekä viittausGame
-olioon että otsikkomerkkijono. - Määrittele myös muuttuja, joka viittaa
tuohon näkymäolioon (kuten
nakyma
aiemmassa esimerkissä). Nimen voisi muuten valita itse, mutta käytä nyt automaattisen arvioinnin vuoksi nimeägui
.
- Laadi näkymälle
makePic
-metodi. Voit nyt aluksi laittaa metodin palauttamaan vain maisemakuvan (scenery
). Lisätään ötökkä ja este kohta. - Lisää ohjelmaan
start
-metodikutsu, joka käynnistää näkymän.
Ajaessa esiin pitäisi tulla yksinkertainen maisemakuva otsikollisessa ikkunassa.
Lopputulos ei paljon poikkea siitä, mitä olemme aiemmin show
-käskyllä saaneet aikaan.
Vielä.
Vaihe 2/2: este ja ötökkäkin näkyviin
Täydennä näkymän makePic
-metodi. Sen tulee muodostaa ja palauttaa pelitilanteen kuva
taustakuvan, ötökän kuvan ja esteen kuvan yhdistelmänä siten, että ötökkä ja este ovat
pelitilanteen mukaisissa sijainneissa taustan päällä.
Siis:
- Käytä annettuja kuvia, joihin
scenery
jabugPic
viittaavat. Hyödynnä funktiotarockPic
. - Luvussa 2.6 luomallasi
Game
-oliolla on kaksi muuttujaa:bug
jaobstacle
. Pääset niiden kautta käsiksi peliin kuuluvaan ötökkään ja esteeseen, mikä onkin tarpeen.- Esim.
gameOlioonViittaavaMuuttuja.bug
- Esim.
- Pääset ötökän ja esteen sijainteihin käsiksi niiden
pos
-muuttujien kautta (luku 2.6).- Esim.
gameOlioonViittaavaMuuttuja.bug.pos
- Esim.
- Asemoi ötökkä ja este juuri niihin sijainteihin, joissa ne aluksi
ovat ja jotka on niiden
pos
-muuttujiin kirjattu. Käytäplace
- taiagainst
-metodia.- Tähän tyyliin:
scenery.place(viittausEsteeseen, esteenSijainti)
- Vrt. palikkaohjelma yllä.
- Tähän tyyliin:
Aja ohjelma. Esteen ja ötökän pitäisi näkyä paikoillaan. Ne eivät liiku. Vielä.
Palauttaminen
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Lisäpuuha: nätimpää koodia
Annetussa FlappyBugApp
issa taustakuva on muodostettu useilla peräkkäisillä käskyillä
käyttäen useita muuttujia (esim. foliage
, ground
) tilapäissäilöinä, jotka vain
pitävät tallessa kuvanmuodostuksen välivaiheita mutta jotka jäävät turhiksi, kun
lopullinen maisemakuva on valmis. Voimme kaunistaa koodiamme jäsentämällä sen hieman
toisin. Kokeile näitä.
Osaatko muotoilla tuon osan koodista toisin siten, että
scenery
ei olekaan muuttuja vaan parametriton funktio, joka palauttaa maisemakuvan? Näin:def scenery = { // kuvan muodostava koodi tänne }
Tilapäissäilöt kuten
foliage
ovat tässä ratkaisussa paikallisia muuttujia, jotka määritteletscenery
n monirivisen rungon sisällä.Entä jos vaihdat äskeisestä ratkaisusta ilmaisun
def scenery
muotoonval scenery
? Toimiiko? Osaatko sanoa, mitä eroa tällä ratkaisulla on äskeiseen?
Yhteenvetoa
- Scala-sovellukselle määritellään käynnistysolio ilmaisulla
extends App
.- Tällaiselle oliolle ei tarvitse kirjoittaa metodeita. Olion sisältämä koodi suoritetaan järjestyksessä, kun sovellus käynnistetään.
- Isomman ohjelman tapauksessa käynnistysolion käskyt aktivoivat muita ohjelman osia.
- Scala-kirjastoista löytyy funktioita, joilla Scala-ohjelma voi lukea ohjelman käyttäjän kirjoittamaa näppäimistösyötettä tekstikonsolissa.
- Sovellusohjelman ohjelmakoodissa tyypillisesti erotetaan toisistaan aihealueen malli ja tuota mallia kuvaava ja käsittelevä käyttöliittymä.
- Graafisen käyttöliittymän laatimiseen on tarjolla apukirjastoja.
- Yksi sellainen löytyy pakkauksesta
o1
. Sen keskeinen luokka on käyttöliittymäikkunoita edustavaView
- Yksi sellainen löytyy pakkauksesta
- Lukuun liittyviä termejä sanastosivulla: käynnistysolio; syöte, I/O; malli, käyttöliittymä, graafinen käyttöliittymä eli GUI.
Palaute
Huomaathan, että tämä on henkilökohtainen osio! Vaikka olisit tehnyt lukuun liittyvät tehtävät parin kanssa, täytä palautelomake itse.
Tekijät
Tämän oppimateriaalin kehitystyössä on käytetty apuna tuhansilta opiskelijoilta kerättyä palautetta. Kiitos!
Kierrokset 1–13 ja niihin liittyvät tehtävät ja viikkokoosteet on laatinut Juha Sorva.
Kierrokset 14–20 on laatinut Otto Seppälä. Ne eivät ole julki syksyllä, mutta julkaistaan ennen kuin määräajat lähestyvät.
Liitesivut (sanasto, Scala-kooste, usein kysytyt kysymykset jne.) on kirjoittanut Juha Sorva sikäli kuin sivulla ei ole toisin mainittu.
Tehtävien automaattisen arvioinnin ovat toteuttaneet Riku Autio, Jaakko Kantojärvi, Teemu Lehtinen, Timi Seppälä, Teemu Sirkiä ja Aleksi Vartiainen.
Lukujen alkuja koristavat kuvat ja muut vastaavat kuvituskuvat on piirtänyt Christina Lassheikki.
Yksityiskohtaiset animaatiot Scala-ohjelmien suorituksen vaiheista ovat suunnitelleet Juha Sorva ja Teemu Sirkiä. Niiden teknisen toteutuksen ovat tehneet Teemu Sirkiä ja Riku Autio käyttäen Teemun toteuttamia Jsvee- ja Kelmu-työkaluja.
Muut diagrammit ja materiaaliin upotetut vuorovaikutteiset esitykset on laatinut Juha Sorva.
O1Library-ohjelmakirjaston ovat kehittäneet Aleksi Lukkarinen ja Juha Sorva. Useat sen keskeisistä osista tukeutuvat Aleksin SMCL-kirjastoon.
Opetustapa, jossa käytämme O1Libraryn työkaluja (kuten Pic
) yksinkertaiseen graafiseen
ohjelmointiin on saanut vaikutteita tekijöiden Flatt, Felleisen, Findler ja Krishnamurthi
oppikirjasta How to Design Programs sekä Stephen Blochin oppikirjasta Picturing Programs.
Oppimisalusta A+ on luotu Aallon LeTech-tutkimusryhmässä pitkälti opiskelijavoimin. Pääkehittäjänä toimii tällä hetkellä Jaakko Kantojärvi, jonka lisäksi järjestelmää kehittävät useat tietotekniikan ja informaatioverkostojen opiskelijat.
Kurssin tämänhetkinen henkilökunta on kerrottu luvussa 1.1.
Joidenkin lukujen lopuissa on lukukohtaisia lisäyksiä tähän tekijäluetteloon.
extends
voidaan tässä lukea: "on eräänlainen".