kolmapäev, 30. september 2009

Ülesanne: Palju elukaid

Ülesanne on realiseerida järgmine animatsioon:

Algselt on ekraanil üks elukas, kes põrkab ekraani raamides ringi. Kui kasutaja klõpsab hiirega mõnda ekraani punkti, siis tekib sinna uus elukas. Kui kasutaja läheb hiirega mõnele elukale peale, siis see elukas hakkab "tõmblema" ehk üritab hiire eest ära põigata.

kolmapäev, 23. september 2009

Ülesanne: Objekt-orienteeritud elukas

Ülesanne: Kirjelda klass Eluka joonistamiseks. Loo selle klassi abil kolm erinevat objekti ja pane nad erinevalt liikuma.

Objekt-orienteeritud programmeerimine

Objekt-orienteeritud programmeerimine on mõtteviis, mis näeb programmi kui erinevate objektide vahelist suhtlust. Kui funktsioon kapseldab endas mingi tegevuse, siis objekt kapseldab endas nii tegevused kui andmed.

Objekte kirjeldavad klassid. Teeme näite loomariigist: olgu meil klass Koer ja objekt sellest klassist - Muki.

Klass kirjeldab, millised omadused on igal sellesse klassi kuuluval objektil ja milliseid tegevusi selle klassi objektid oskavad.
  • Klass Koer.
  • Omadused - värvus, vanus, kaal
  • Tegevused - haugu, sitsi, istu, hammusta 
Objekt annab omadustele konkreetsed väärtused, millest lähtudes ka tegevusi sooritatakse. Näiteks Muri on must, kolme aastane ja kaalub 5 kilo. Haugub kõvasti, sitsib vapralt, istub hästi ja hammustab natuke.

Klasside kirjeldamine ActionScriptis

 Klassi kirjeldamiseks tuleb kirjeldada eraldi failis klassi nimi, muutujad (omadused) ja funktsioonid (tegevused).

// Klassi nimi 
public class Koer
{

    // Klassi andmed 
    var color:int;
    var age:int;
    var weight:int;

    // Klassi konstruktor 
    public function Koer(cc:int, aa:int, ww:int)
    {
        color = cc;
        age = aa;
        weight = ww; 
    } 

    // Üks funktsioonidest 
    public function haugu(isend):void
    {
        ... 
    } 


NB! Klass tuleb salvestada faili KlassiNimi.as. Iga klass peab kuuluma teeki (package). Antud juhul paneme ta nimetusse teeki ja lepime hetkel sellega:

package
{
public class Koer
{

}

Klassist endast pole meile palju rõõmu. Klassi saame kasutada läbi objektide. Objektide loomine käib samamoodi nagu tavaliste muutujate loomine, mõne väikese erandiga.

var muri:koer = new Koer(0x000000, 3, 15);
var muki:koer = new Koer(0x000000, 1, 5);

Kõik on tore ja tuttav aga
  • new - selle võtmesõnaga öeldakse, et loome uue objekti järgnevast klassist
  • Koer(...) - konstruktor. See on eriline funktsioon, mis kutsutakse välja objekti loomisel ja mille abil objekt algväärtustatakse.  
 Nüüd saame juba rahus edasi programmeerida.

muri.istu();
muki.sitsi();
muri.haugu(kass);
muki.haugu(kass);

Loe ka artiklit "Object-oriented programming in ActionScript"

Ülesanne: Funktsioonide kasutamine Eluka joonistamisel

Ülesanne - vii oma eluka joonistamisalgoritm eraldi funktsiooni.

Funktsioon

Isegi väga lihtne programm koosneb mitmetest erineva iseloomuga tegevustest. Näiteks ühe Eluka joonistamine ja selle hiirega liigutamine on juba kaks erinevat tegevust. Kui tahta ühe Eluka asemel liigutada mitut, siis tuleb Elukat joonistavat koodi dubleerida.
  • Programmeerijatele meeldib eristada sikud lammastest - kood, mis joonistab Elukat ei pea midagi teadma sellest, et olemas on mingi hiir
  • Programmeerijatele ei meeldi juba lahendatud probleeme uuesti lahendada - võimalusel taaskasutaksid nad juba varem tehtud tööd.
Funktsioonid kapseldavad mingi programmijupi korduvkasutatavaks ühikuks. Funktsioon on nagu alltöövõtja - annad talle ülesande, tema teeb tööd ja ütleb sulle vastuse ilma, et sina peaksid mõtlema, kuidas ülesannet lahendada.

Funktsiooni defineerimiseks kasutatakse järgmist kirjapilti:

function addNumbers(num1:int, num2:int):int
{
    return num1 + num2;
}
  1. function - võtmesõna, mis ütleb, et järgneb funktsioon
  2. addNumbers - funktsiooni nimi, mille järgi teda hiljem kasutada
  3. (num1:int, num2:int) - argumentide loetelu, informatsioon, mida funktsioon vajab oma ülesande täitmiseks
  4. :int - tagastusväärtus, informatsioon, mille funktsioon ütleb oma tegutsemise tulemusena
  5. { ... } - funktsiooni keha, tegelik arvutuseeskiri
  6. return ... - võtmesõnaga return lõpetab funktsioon töö ja tagastab väärtuse.
Näide 1: Funktsioon, mis ei tee mitte midagi

function empty():void
{
}
  • Pane tähele, et argumentide loetelu on tühi - funktsioon ei vaja mingit sisendinformatsiooni.
  • Pane tähele, et funktsiooni keha on tühi - funktsioon ei tee midagi.
  • Pane tähele, et tagastusväärtus on void. Seetähendab, et tegelikult see funktsioon väärtust ei tagasta.
Näide 2: Funktsioon, mis liidab kaks numbrit


function addNumbers(num1:int, num2:int):int
{
    return num1 + num2;
}


Kasutamine:

var x1:int = addNumbers(1, 0);

// x1 == 1 + 0 == 0

x1 = addNumbers(15, 3);

// x1 == 15 + 3 == 18


Pane tähele, et funktsiooni täitmisel funktsiooni argumendid asendatakse sisendväärtustega ja neid kasutatakse funktsiooni keha täitmisel.

Näide 3: Mitu väljumiskohta

function isnumberbig(value:int):Boolean
{
    if (value > 3) {
        return true;
    }
    return false;
    value += 3;
}


Pane tähele, et return võtmesõnaga väljutakse funktsioonist. Sestap funktsiooni keha viimast rida enam ei täideta.

NB! Uuri kindlasti ka artiklit "Functions".

kolmapäev, 16. september 2009

Ülesanne: Pop-art

Realiseeri kõrvaloleval pildil kujutatud kunstiteos. Ristkülikute proportsioonid on fikseeritud ja valitud lava proportsioonidest lähtudes. Värvid on genereeritud juhuslikult.

Kasutada tuleks tsüklilauseid. Ehk siis selle asemel, et iga ristkülikut eraldi käsuga joonistada tuleks teha tsükkel, mis ristkülikud joonistab.

Näiteks võib kasutada for tsüklit. Tuletame meelde põhimõtte.
  1. var xx:int; 
  2. for (xx = 0; xx < 80; xx++) {
  3.     tee midagi 
Siin on xx tsüklimuutuja. Esimene lause tsükli päises on algväärtustamine, teine on lõputingimus ja kolmas tsükli samm. Algväärtustamine leiab aset ainult üks kord. Tsükkel kestab kuni lõputingimus pole väär ja iga tsükli lõpus tehakse tsükli samm.
Antud juhul tehakse tsüklit xx väärtustel 0, 1, 2, ... 79 ja siis lõpetatakse töö.
  1. var xx:int; 
  2. for (xx = 0; xx < 80; xx += 10) {
  3.     tee midagi 
Seda tsüklit tehakse xx väärtustel 0, 10, 20, ... 70. Kuna tsükli samm on muutunud pikemaks. Tsüklite kohta loe: 'Looping'

Ülesanne: Elukas gravitatsiooni küüsis

Ülesandeks on võtta oma elukas ja panna ta ekraanil põrkama selliselt, et põrkamine sõltub gravitatsioonijõust. Ülesannet saab lahendada mitmes järgus:
  1. Pane oma elukas lava ülemise ja alumise ääre vahele liikuma - kui jõuab alla, siis liikumise suund muutub üles, kui jõuab üles, siis liikumise suund muutub alla.
  2. Võta kasutusele muutuja eluka liikumise kiiruse kontrollimiseks. Proovi erinevaid kiiruseid.
  3. Pane kiirus sõltuma gravitatsioonist - mida lähemal lava alumisele servale, seda kiirem on liikumine. 
  4. Lõpuks võid panna külgetõmbejõu mõjuma ka x-telje suunas. 
Kuidas tuvastada seda, kas elukas on lava ülemise või alumise ääre lähedal? Tingimuslausega! Tuletan meelde, et tingimuslause on lause, mis kontrollib mingi tingimuse kehtivust ja selle põhjal otsustab, kas käiku läheb plaan A või plaan B.
  1. if (tõeväärtust tagastav lause) {
  2.     plaan A
  3. }
  4. else {
  5.     plaan B
  6. }
Tingimuslause else osa võib ka ära jätta.
  1. if (lava alumine serv) {
  2.     muuda liikumise suunda
  3. }
Tingimuslausete kohta loe lähemalt artiklist 'Conditionals'

Ülesanne: Võbelev elukas

Ülesandeks on panna elukas liikuma lava alumisest osast suunaga üles, kusjuures tervet liikumist saadaks väike värin eluka kehas. Kuidas seda teha? Põhimõtteline lahendus on siin:
  • Paigalda sündmusetuvastaja ja -töötleja sündmusele Event.ENTER_FRAME
  • Sündmusetöötlejas liiguta elukat y-telge pidi ülespoole ja liiguta tema x-telje asendit juhuslikult
Lihtne?
On küll lihtne. Lahenda ülesanne kahes järgus:
  1. Pane muutujate abil elukas liikuma lava alumisest osast mööda y-telge üles
  2. Lisa elukale väike juhuslik liikumine x-telje suunas 
Muutuja? Tuleta meelde eelmist praktikumi - sa panid oma eluka asukoha sõltuma süsteemsest muutujast mouseX. Muutuja - see on nimeline viit arvuti mälus hoitavatele andmetele. Nagu karp, kuhu saab asju tallele panna kuni neid vaja läheb. Süsteemsed muutujad on süsteemis juba olemas, kuid muutujaid saad sa ka ise defineerida:
  1. var muutuja1:int;
  2. var muutuja2:Boolean = true; 
Punktis 1. deklareerime täisarv tüüpi muutuja nimega muutuja1. Punktis kaks deklareerime tõeväärtus tüüpi muutuja nimega muutuja2, algväärtusega true.

Muutuja muutmine toimub omistamisoperaatoriga:
  • muutuja1 = 7;
  • muutuja2 = false;
Omistamisoperaator omistab muutujale väärtuse.

Lava alumine serv? Laval on kõrgus ja laius. Lava tähistas objekt stage, millel olid parameetrid stageWidth ja stageHeight.

Esimese järgu lahendamiseks on sul nüüd kõik vajalikud vihjed olemas. Muutujatest loe lähemalt artiklist: 'Variables'. Andmetüüpidest saad rohkem infot artiklist 'Data types'.

Teise järgu lahendamiseks on vaja oskust genereerida juhuslikke arve. Klassis Math on olemas funktsioon random, mis väljakutsumisel tagastab juhusliku arvu vahemikust [0, 1). See tähendab, et randomi tulemus võib olla ka 0, aga 1 ta kindlasti ei ole, kuigi võib olla näiteks 0.999999999999999999999.

Kui tahta saada muutujasse xx juhuarvu vahemikus [0, N), kus N on suvaline täisarv, siis piisab kui teha nii:
  •  xx = Math.random() * N;
Kuidas teha juhuarve vahemikus [-3, 3]?

Ka teise järgu lahendamiseks on sul vajaminevad vahendid olemas. Kui oled usin, siis paned ka oma eluka silmad värvi vahetama.

kolmapäev, 9. september 2009

Ülesanne: Eluka liigutamine

Kui elukas on joonistatud, siis järgmine samm on tema liikuma panemine selliselt, et eluka asukoht ekraanil sõltuks hiire asukohast.
Kuidas tuvastada hiire asukohta mingil ajahetkel? Igas Flash programmis on olemas klassi flash.display.Stage objekt stage, millel on parameetrid mouseX ja mouseY, kuhu salvestatakse hiire hetkel kehtivad koordinaadid.
Kuidas reageerida hiire liikumisele? Üks võimalus on tuvastada sündmus Event.ENTER_FRAME, mis genereeritakse iga kord, kui animatsioon jõuab vastavasse kaadrisse. Sündmusega seotud töötleja (funktsioon, mille peame ise looma) muudab eluka asukohta. Sündmuste kohta on täiendavat lugemist artiklis "Handling events".

Näide:
 
  1.  //Paigaldame sündmusetuvastaja
  2.  stage.addEventListener(Event.ENTER_FRAME, doDrawThing); 
  3.   
  4.  //Sündmusetöötleja 
  5.  function doDrawThing(event:Event):void
  6.  {
  7.      //Kustutame vana joonistuse
  8.      graphics.clear();
  9.      //Kirjeldame joone 
  10.      graphics.lineStyle(1, 0x000000);
  11.      //Joonistame eluka uude asukohta
  12.      graphics.drawRect(stage.mouseX, stage.mouseY, 20, 20);
  13.  }