august 31, 2014

Trips Traps Trull: Variant II

Allpool toon ära TRIPS TRAPS TRULLI natukene kõpitsetuma variandi. Hoiatan ette, neid tuleb siin veel, see pole veel täiuse tipp.

TTT blogikood selles osas veidi erineb allpool toodust, kuigi püüdsin olulise sisu säilitada. Tuli vältida eelmise TTT versiooniga kokkupõrkeid nimederuumis. Kuidas seda viisakamalt teha keskkonnas, kus jooksevad kümned skriptid, seda peaks veel lähemalt uurima.

TRIPS TRAPS MEGATRULL

TTTII HTML tekst

Kahjuks pole jõudnud kirjutada oma blogis vastavat puhastusfunktsiooni soovimatute blogitäienduste vältimiseks, mistõttu HTML näidistes on </body> ja </html> lõpetamata ">" märgiga.

TTTII JavaScript kood

Selgitused koodi juurde

HTML-st, mida enam ei ole

Nagu näete - HTML -st ei ole alles peaaegu mitte midagi.
Kõik, mis vaja, joonestab JavaScript ise valmis. Ajutiselt lülitasin välja viite "css" failile, millega praegu ei tegele. Lisaks märkate "mõttetut" div märgist. See on kasulik mitmel põhjusel: selle div-le on antud id "TTTII" ja nii on seal sees tekkivaid-kaduvaid asju võimalik kergesti kätte saada. Selle HTML teksti võib tõenäoliselt tõsta mõne teise html sisse, ilma, et mäng lakkaks töötamast.
Täpsustav märkus
Päris nii kahjuks ei ole (isikliku näite varal), minu enda kirjutatud endise TTTI mängu objektid segavad siin asja.

Märkused JavaScript aadressil

Nagu nägite - HTML -st ei jäänud suurt midagi alles, aga JavaScript koodi saime pea 50 rida juurde.
See ei ole isegi mitte patt. Koodiridadega, kui need tunduvad vajalikud, ei maksaks koonerdada.
Ka funktsioone on lisandunud juurde. Ka see ei ole patt, kuigi mitte alati ka voorus. Kui funktsioon on vajalik ja täidab kindlat funktsiooni ja mitte midagi muud, siis tuleb see luua.

Funktsioonide deklareerimisest

Mulle meeldib mõelda ülevalt alla stiilis ja nii tundub mugavam.
See tähendab, et kõigepealt kirjutame valmis mallina, mis ehk midagi ei teegi, kõige üldisemad, suuremad operatsioonid. Näiteks looManguLaudTTT() võiks olla selline operatsioon. Funktsioonide deklareerimise stiilis kirjutamisel ei ole sellest lugu, kui pudiludi funktsioonid tulevad suure funktsiooni järel, aga funktsiooniavaldiste puhul var funkts = function() {...}; tekivad probleemid, saame teateid, et mingi funktsioon on "undefined". Seetõttu ma praegu eelistan seda stiili lihtsamate programmide kirjutamisel. Keerukamatega nii ei saa, sest seal tuleb funktsioone kirjutada üksteise sisse ja deklaratiivne stiil (vist enam) sellisel juhul ei toimi. Kuidas sellisel juhul loetavat JavaScripti kirjutada, kasutades funktsiooniavaldisi, üritan välja uurida ja siis soovitusi jagada.

Muutuvaim asi ilmas - KONSTANDID

// KONSTANDID:
var KANVAA = "kanvaa";
var VOIDUKOMBINATSIOONID = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],
[2,5,8],[0,4,8],[2,4,6]];
Siin on muutuvad suurused kirjutatud üles suurte tähtedega. See on iidne konventsioon tähistamaks asju, mille kohta on kujunenud veendumus - need asjad iial ei muutu.
Kahjuks on see veendumus osutunud peaaegu alati valeks
Kõige muutuvamad suurused ilmas on "KONSTANDID" ja kõige püsivamad nähtused need, mille kohta armastatakse mõelda "AJUTINE".
Ettenägelikud programmeerijad seetõttu mitte kordagi ei jäta programmi sisse peaaegu mitte ühtegi arvu ja asendavad nad suurte tähtedega kirjutatud muutujatega päris programmi alguses, et kui läheb jälle suureks muutmiseks ja ümbertegemiseks, oleks neid võimalik muuta.
Lisaks on inimkeeles ära seletatud konstantidel see hea omadus, et nad on teisele programmeerijale arusaadavad. Kui kirjutada mingi asja kohta 3.141592, siis vähesed siin maailmas oskavad kohe öelda, et see võiks olla PI. Aga kui selle koha peal ongi Math.PI, siis on kõigile selge, kes koolis käinud, et see on see kuulus PII.

Sissejuhatus objektide maailma

// Objekt mang (mäng)
var mang = {
sisu :[-1,-1,-1,-1,-1,-1,-1,-1,-1],
kaik : 0
};

Kommenteerin siis nüüd ridu, mis tekitavad objekti mang:
Kuigi siin oleks olemas juba võimalus märku anda oma teadmiste pakatamisest OO (ObjektOrienteerituse) vallas, jätan selle targu tegemata. Praegu kasutan objekte lihtsalt selleks, et oma koodilasu grupeerida.

Mis on objekt ?

Objekt on muutuja, mis võib endas sisaldada mitmesuguseid omadusi. "Omadus" omakorda on tegelikult igas muus suhtes täieõiguslik muutuja, v.a. see asjaolu, et ta on seotud oma objektiga (ülemusega). Minu koodis TTT I sisu[] oli täieõiguslik massiiv. Praeguses koodis tekitasin ma objekti mang ja selle alla paigutasin selle massiivi. Nüüd sisu enam päris omaette ei ole, tema väärtusi ilma viitamata ülemusobjektile kätte ei saa.
sisu[0] muutub nüüd viiteks mang.sisu[0].
sisu ise on muuseas ka objekt, sisaldades oma elemente, nii et objekt võib sisaldada alamobjekte, need omakorda alamobjekte ja nii edasi...
Samasuguse degradatsiooni tegime ära muutujaga kaik. kaik ja sisu on nüüd objektmuutuja mang OMADUSED. Nagu arvata võib, saab objekti mang omadustega manipuleerida samamoodi, nagu tavaliste muutujatega, näiteks saab mang omadusele kaik ühte juurde liita: (mang.kaik++ teeb seda )
Märkus
Kui päris täpne olla, on kõik muutujad sirvikus algusest peale ühe suure globaalobjekti "window" alluvuses, nii et eelmises variandis oli sisu window alam, nüüd sai siis ülemuseks mang
Selles mõttes on analoogia DOM puuga, kõik asjad JavaScripti interpretaatori jaoks moodustavad ühe suure objektipuu ja nn. mitteobjektid on siiski vaid konventsioon tavaprogrammeerijale.
Need mitteobjektid (string, number, loogiline andmetüüp ning eraldi "undefined" ja "null") lihtsalt on teatud piiratud võimalustega objektid.
Näiteks string jaoks on olemas meetod .length, aga pole võimalusi igasuguseid omadusi juurde teha.

Objektide loomine

Objektide loomiseks ja täiendamiseks on mitu võimalust. Ühte nägite selles koodis:
Sama võib aga saavutada ka nn. punktnotatsiooni kasutades. Kõigepealt loome tühja objekti ja seejärel lisame omadusi ja nende väärtusi, või ka juba muudame neid. sellist notatasiooni kasutades:
OBJEKT . OMADUSE NIMI = OMADUSE VÄÄRTUS
Objekt mang omistused võiksid välja näha nii: Kolmas võimalus oleks omadus:väärtus paare lisada, kasutades massiividega sarnanevat süntaksit, ainult et massiivi indeksi asemel on objekti omadus, kirjutatuna jutumärkides.

Edaspidi tahaksin objekt mang alla sokutada ka kõik selles mängus vajaminevad funktsioonid või vähemalt enamik neist.

Sündmuste ettearvamatu maailm: window.onload-st ja teistest juhtumustest veebilehekülgedel

See rida koodis -
window.onload = function() ...
tundub esimesel pilgul üsna krüptiline.
Selle lause sisu aga midagi üleloomulikku ei ole - käsk on SEE tegevus edasi lükata hetkeni, kui lehekülg laaditud.
Nii näetegi selle kirjutise laadimisel kummalisi asju juhtuvat ekraanil - algul tekib pealkiri ja isegi selgitav tekst selle juurde ja ALLES SIIS tekitab "nähtamatu käsi" ekraanile 9 kanvaad ja saate hakata oma lemmikmängu mängima.
Selle kohta ütlevad netigurud, et see sündmus toimub ASÜNKROONSELT. Ja otse vastupidist juhtumit, kus kõik ilmub veebileheküljele nii, nagu veebilooja on kirjutanud, ülevalt alla, algul "head-s" sisalduv, seejärel body sisu, nimetatakse SÜNKROONSEKS.
See terminoloogia kahjuks on väga eksitav, sest pigem just asünkroonselt toimuvad sündmused on sujuvamad, kasutaja saab samal ajal, kui server ajab kusagilt netist reklaami taga, juba tegelda lehekülje sisuga.
NN. sünkroonselt toimuvate sündmuste puhul tuleks netilehekülje laadimise ajaks minna kohvi keetma, täpselt samamoodi, nagu teleka reklaamipauside puhul. Ja ärge imestage, et teie veebileheküljed muutuvad selles mõttes järjest "sünkroonsemaks": kes maksab, see tellib ka muusika. Kui reklaami tellija on ähmaselt taibanud, et vaid "sünkroonne" mudel tagab reklaami 100%-lise jõudmise kasutaja ajudesse, saavad kõik programmeerijad delfis ja mujal kiiresti kinga, kui nad ainult julgevad iitsatada mõttest käitada autoreklaam TAGAPLAANIL (Väga hea näide on jutjuubis toimunud saastumine). Nii et ärge laske ennast eksiteele viia ebaõnnestunud terminitest - arvutimaailmas kahjuks tänase päevani ei ole olemas sünkroonsust, sekundilise täpsusega käivitatavaid sündmusi kindlas, ettenähtud järjestuses.
Termin Asünkroonne aga vastab enam-vähem ettekujutletavale - võite selle kohta mõelda: nii nagu jumal juhatab...
Netilehekülje laadimisel toimub veel tänini asi enam-vähem sünkroonselt: sirvik loeb rida rea haaval leheküljelt elemente ja käske ja täidab neid nii, nagu nad ette tulevad. Seetõttu võib lehekülje laadimine viibida: näiteks on päises viide javascripti failile ja selle laadimine võtab aega. Sellise olukorra vältimiseks võikski programmeerija vahel lasta toimida asünkroonselt, kui tema koodi toimimine ei sõltu sellest, kas ülejäänud lehekülg on üles laetud või mitte. Ja otse vastpidi on siis, kui kood tegeleb selle lehekülje alles üleslaetava elemendiga, siis tuleb see osa koodist edasi lükata, kasutades sündmust windows.onload - selle sündmuse külge poogitud funktsioon käivitub alles siis, kui lehekülg on laaditud. Blogis tajute seda imeliku viitena, mängulaud ilmub alles kõikide teiste elementide järel.
Kui aga lehekülg on laaditud, ei ole mingist sünkronismist mõtet isegi mitte mõelda. Kõik, mis toimub, toimub juba asünkroonselt. Enamasti on sündmuste tekitajaks kasutaja, aga on võimalikud ka välised sündmused, mis mõnda tegevust käivitavad - näiteks programmides ikka esinevad vead. Nii ongi ülejäänud kood sõltuv kasutaja suvast, sellest millal ja mismoodi ta klõpsib 9 kanvaa ruutudel.

Näiteid võimalikest sündmustest

Sündmusi veebilehe elus võib olla väga palju, allpool ma natuke loetlen neid asj, mida üsna tõenäoliselt tuleb kasutada.
Entsüklopedistid võtku ette juba mõni "REFERENCE MANUAL", kahjuks olete jõudmas sinnamaale, kus neist enam pääseda ei ole võimalik. Isegi Flanagani tuleks väga ettevaatlikult hakata veerima. Wiki, "Dom events" märksõna alt leiab ka päris korraliku tabeli. Aga loodame pääseda kõigist sündmustest ja tegeleme kõige tähtsamatega. Enne loetelu juurde asumist märgime, et kui sündmuse tüüp on näiteks click, siis selle sündmuse halduri külgevõtmiseks tuleks kasutada onclick nimetust (button.onclick = ... ja siin tuleb funktsioon, mis midagi teeb). Veel moodsamal moel jälle peab kasutama sündmuse tüübi nimetust click umbes nii:
el.addEventListener("click", hallo_maailm, false);
(hallo maailm on funktsioon, mis hõigub ilmakuulsat programmilauset - "Hello World", seda iga programmeerimisega alustanu on kohanud ad nauseam) Selle selgituseni, mida see krüptika teeb, tahaks jõuda veidi hiljem, mängulaua loomise juures, siin lihtsalt memoriseerimise mõttes jätke meelde, et kaks lihtsamat viisi sündmuse halduri paikapanekuks kasutavad eesliidet "on" sündmuse tüübile lisaks, ja kõigetäiuslikum meetod jälle viitab sündmusele selle tüüpi kasutades. Ja IE-st parem ei räägi, see sirvik teeb seda kõike omamoodi. Versioon 11 väidetavalt enam ei tee omamoodi ja äkki saab sellest ajastust lahti, kus pool manuaali läheb alati selle peale ära, kus selgitatakse, kuidas teevad teised sirvikud ja teise poole peal selgitatakse, mida sellest arvab IE. Kui aga sellest lahti ei saa, aitab JavaScripti abipakett nimega JQUERY, sellest tn. ei pääse keegi isegi siis, kui IE korralikuks hakkab. Kuid ma praegu lükkan JQUERY-ga tegelemise edasi. Sisulise mõistmise mõttes oleks vaja ka allolevast masinavärgist aru saada. Aga IE veidruste peale aega ei raiska. (Seda peate aga tn. hakkama kohe tegema, kui reaalsete rakenduste tegemiseks läheb.)

Tähtsamad võimalikud sündmused veebilehe elus:

  • click / onclick - käivitub, kui elemendi peal on klikatud
  • dblclick / ondblclick - topeltklõps...
  • mousedown /onmousedown - hiire nupp vajutatud alla (peab eraldi uurima veel, mis nupp)
  • mouseup / onmouseup - nupp lastud üles tagasi
  • mouseover / onmouseover - hiirega libisetud elemendile peale

  • igasugu drag ja drop sündmusi ei viitsi loetleda

  • keydown / onkeydown klaveri klahv vajutatud alla
  • keyup / onkeyup klaveri klahv vabas positsioonis tagasi keypress / onkeypress - klahv vajutatud alla.
  • unload / onunload - sündmus ilmselt leheküljelt lahkumisel.

  • ja nii edasi ja edasi, küllap kodeerimispraktika edenedes jõuab need asjad kõik sõrmede sisse tampida, ja kui ei jõua, ei ole neid asju järelikult vaja.

Mängulaua loomisest

Vaatleksime siis, kuidas JavaScriptis luua HTML elemente ja neile omadusi külge pookida.
Mängulaua joonistamise võinuks siin muidugi jätta ka HTML teksti hooleks, sest see ei muutu mängus, v.a. ristide ja nullide kustutamine, mis kindlalt oleks JavaScripti töö. Kuid võiks olla ka nii, et iga mäng tuleb joonistada erinev laud - ütleme siis, kui tahetakse mängida vahel ka 4x4 laual...
Päris hakatuseks on näha, et põhifunktsioon midagi sisulist ei teegi, ainult jagab korraldusi.
Kui inimühiskonnas sooviksime, et ka ülemused vahel midagi sisulist teeksid, siis programmide sootsiumis on selline nähtus AINULT TERVITATAV.
Kood tuleb niimoodi pulkadeni lahti kirjutada, et reaalsed töötegijad tõesti täidaksid vaid äärmuseni lihtsustatud ülesandeid, ei midagi enamat. Umbes nagu Ford 20. sajandi alguses leiutas konveiermeetodi.
looManguLaudTTT() tött öelda siiski ühte teist teeb, tõlkides ülesande arvutikeelde.
(Ka inimühiskonnas sageli ülemused siiski teevad kasulikku tööd, tõlkides alamuste jaoks arusaadavasse keelde asju, millest arusaamiseks ei ole meile aru antud.)
Esialgne ülesanne:
Joonista ruudustik 3x3, iga ruut kujutagu omaette kanvaad.
Iga kanvaad ümbritsegu punane äärejoon.

Esimene tõlge:
Joonista 3 rida kanvaasid, igas reas 3 kanvaad ja sellejärel reavahetus.
Iga kanvaad ümbritsegu punane äärejoon

Panek arvutikeelde (lühendatud, täistekst on juba kood ise):
Tee 3x for tsükli abiga kanvaarea joonistamist,
kus kanvaarea joonistamine tähendab 3x kanvaa joonistamist,
pluss reavahetus,
ning kanvaa numbriks saab reanumbri (0-2) ja veerunumbri (1-3) summa.
Ilma programmeerimise aluseid oskamata oleks väga raske taibata, et selleks, et midagi teha n korda, tuleks luua muutuja i ning iga i väärtuse jaoks 0...,(n-1) sedasama asja teha.
Aga selline on arvuti arusaamine ülesandest "tee midagi n korda". Ja see on alles "kannatuste raja" algus, sest sama ülesande saaks kirja panna rekursiivselt või koguni kõrgemat järku funktsioone kasutades....

Funktsioonist looKanvaa

Elemendi tekitamine arvutiekraanile TEGELIKULT toimub kahes järgus.

  • Kõigepealt element tuleb luua:
    Seda teeb käsk kanvaa = createElement('canvas')
    Sulgudes tuleb ära märkida, mis tüüpi elementi tahetakse tekitada.
    Pärast loomisakti tasuks loodule kohe kõik vajalikud atribuudid juurde pookida, kuigi seda võib igal ajal teha.
    Atribuutide nimed HTML-s ja loodavad elemendi omadused JavaScriptis enam-vähem on üks ühele ümber pandavad.
    ("." järel tuleb loodava HTML elemendi atribuudi nimi).
    Aga!:JavaScriptis on need ALATI väikeste tähtedega, kui ühesõnalised ja järgmine sõnaalustus suurega, kui atribuudi nimi koosneb mitmest sõnast (vt. all näidet)
    Aga! style="border:..." asemel on siin .style.border =...
    Võinuks ka vanaviisi, s.t. .style=....
    Aga! Mitmeosalised atribuudid HTML-s kaotavad JavaScriptis ära "-" kahe sõna vahelt ning vormindatakse ära JavaScripti stiilselt, s.t. esimene sõna väikse tähega, järgmine algab alati SUURE tähega.
    text-align muundub nii textAlign-ks.
    Aga! 2 atribuuti HTML-s ja üks CSS-s on JavaScriptis reserveeritud sõnad: HTML atribuut class muundub className-ks, for muundub htmlFor-ks ja float CSS-st muundub cssFloat-ks.
  • KUI nüüd element on loodud, tuleb ta DOM puu külge pookida. DOM - Document Object Model on viis HTML lehekülgi arvutile arusaadavaks teha. Kogu loodud HTML lehekülje elemendistik paigutatakse puusse, v.t. minu sissejuhatava jutu lõpp HTML-st.
    Lühimeenutusena: kõige alustus, puu juur on html, html-l on lapsed "head" ja "body". "head" järglased võiksid olla näiteks "meta" - märgised, aga ka "title", "script" märgised ehk programmid lehekülje jaoks, ja nii edasi... "body" lasteks on juba lehe sisu, näiteks võiks tulla kohe "p" (paragrahv", "img" ja nii edasi. Ja peaaegu igal elemendil võib olla "järglasi" ...
    DOM puusse istutamiseks tuleb otsida element, kellele loodud laps sokutada.
    Praegu oleme isarolli täitjaks määranud elemendi "div" id-ga "TTTII".
    Lõplikuks elemendi sünnimomendiks saabki siis selle elemendi puusseistutamise käsk:
    kanvaaIsa.appendChild(kanvaa);
    appendChild() asemel on veel võimalus panna loodud laps mõnele teisele kohale isaelemendi laste järjestuses. Seda toimetab käsk insertBefore(viide elemendile).
    Ka juba loodud elemente saab nii ümber paigaldada.
    Kes tunneb hästi Piiblit, teab, et kõik autoriõigused sünnijärjestuse muutmise mõtte osas kuuluvad Jaakobile, kes Eesavilt esisünniõiguse välja kauples läätseleeme eest.

Kliki käitlemise 3 viisi JavaScriptis

Iga sündmuse lehekülje elus (hiireklikk, nupuvajutus etc...) saab programselt seostada mingi tegevuse / tegevustega. Seondamiseks on 3 erinevat võimalust.

  • Ajalooliselt vanim on meetod, mida kasutatakse TTT I variandis - "canvas" elemendi juurde kirjutatud onclick="kanvaaKlikk(x)".
    x asemel on siis kanvaa number 1-9. Kanvaa klikkamisel tõepoolest käivitub see funktsioon ja ka parameeter x on edastatud iga kord õieti. Võite aga proovida, ühe funktsiooni asemele võib kirjutada ka mitu käsku, kusjuures need isegi ei pea olema kirjas mingis skriptifailis. Võtke näiteks lihtsaim HTML ilma "js", "css" lisadeta, lisage paragrahv tekstiga "hallo, maailm" ja kirjutage üheks paragrahvi atribuudiks onclick="alert('hallo');alert('maailm');". Kõik toimib. Tegelikult teeb Javascript onclick juurde kirjutatud stringist FUNKTSIOONI, lisades stringi algusesse sõna function() ning ümbritsedes stringi loogeliste sulgudega. "hallo, maailm" paragrahvi näites saadakse paragrahvi klikkamise puhul käivitavaks funktsiooniks function() {alert('hallo');alert('maailm');} TTT I variandis ei kasutata mitte ühte ja sama funktsiooni 9 erineva parameetri väärtusega 1-9, vaid luuaksea iga kanvaa puhul klikkamiseks eraldi funktsioonid ,
    kanvaa 1 puhul siis function() {kanvaaKlikk(1);}
    ...
    kanvaa 9 puhul function() {kanvaaKlikk(9);}.
  • TTT II, hetkel kehtiva mängu variandi korral loome elemendid kanvaa1...kanvaa9 JavaScriptis ning nende elementide sündmuse klikihalduri peab määrama JavaScriptis.
    kanvaa.onclick =function()
    { kanvaaKlikk(kanvaaNumber);};

    teebki seda, "kanvaa.onclick" omaduseks on funktsiooni kood.
    Märkus - katsed siia külge riputada I meetodis kasutatud stringe, näiteks "kanvaaKlikk(1)" , ei toimi. Vastava omaduse väärtuseks saab null
    Kui funktsioon on süntaktiliselt vigane, saame sama tulemuse.
    Võrreldes TTT I variandiga antakse kanvaaKlikk funktsioonile kaasa muutuja kanvaaNumber väärtus. JavaScriptis saab seda teha, muutuja kanvaaNumber on nähtav kogu funktsiooni looKanvaa ulatuses (ja mittenähtav naabruses asuvatele funktsioonidele). Nähtavus laieneb ka kõigile selle funktsiooni all loodud funktsioonidele, siin siis funktsioonile kanvaa.onclik.
    kanvaaNumber on tõsi, parameeter, aga niipea, kui parameeter on jõudnud funktsiooni, on ta oma staatuselt täpselt samaväärne muutuja.
    Kuulge, siin on midagi mäda, võib lugeja hüüatada, eriti mõni selline, kes peab iseenesestmõistetavaks, et kui funktsioon lõpetab tegevuse, kaovad areenilt ka kõik selle funktsiooni sees defineeritud muutujad.
    Ja koht, kus funktsioon välja kutsutakse, määrab selle, mida see funktsioon näeb.
    Talle peaks nähtavad olema kõik väljakutse hetkel kättesaadavad muutujad.
    Sellist asja nimetatakse veel DÜNAAMILISEKS SKOOBIKS ja kes sellega harjunud, sellel on ümberõppimine päris valulik (k.a. mina).
    Aga JavScriptis nii ei ole. Kõigepealt ei tea funktsioon tema väljakutsuja skoobis kehtivatest muutujatest midagi, v.a. globaalne skoop... Selle asemel peab funktsioon meeles mingeid noaaegseid muutujaid sellest kohast ja ajastust, millal ta defineeriti.
    Ja ta ei näe mitte midagi sellest ümbrusest, kus ta välja kutsuti! PS! Veel kord: näeb siiski globaalskoopi, mistõttu see kanapimedus ei paista kohe välja!
    Sellest võib mõelda umbes nii.
    Olgu meil mingi funktsioon F, mille sees luuakse uus funktsioon f (Praegu looKanvaa()). Praegu on funktsiooniks f sündmuse "click" haldur loodava kanvaa jaoks. Loodud funktsioon f jätab meelde kõikide muutujate väärtused, mis tema looja F-le on kättesaadavad. Neist globaalsed muutujad j ä t k a v a d oma muutumist funktsiooni f jaoks, kui tal peaks neid tarvis minema, aga kõik F-i jaoks lokaalsete muutujate väärtused jäetakse mällu selle ajahetke väärtustega. Nii jääbki "kanvaa1" klikihaldurile igaveseks tempel mällu muutujast kanvaaNumber väärtusega 1. Hiljem kutsutakse looKanvaa() funktsiooni veel 8 korda välja, luues elemendid kanvaa2 ... kanvaa9.
    Muutuja kanvaaNumber jõuab lõpuks omadega väärtuseni 9. See kõik kanvaa1 klikihaldurit ei häiri, tema jaoks jääb kanvaaNumber väärtuseks 1.
    Üks üsna vastik nüanss on veel selle kõige juures: ülesvõtte hetk. Klõps käib siis, kui funktsioon lõpetab oma töö. Kui meil oleks tulnud pähe mõte parameetrit kanvaaNumber muuta, näiteks enne töö lõppu teha käsk kanvaaNumber++;, saaksime paraja segaduse - 1. ruudul klikkides joonistatakse 0 või x teise ruutu.
    Veel pöörasemaks läheksid asjad, kui sündmuse haldur ise otsustab kanvaaNumber väärtust muuta ütleme kanvaaNumber++ käsuga, siis teisel ja rohkematel klõpsudel sellel kanvaal hakkaksid klõpsude järgsed ristide ja 0-de joonistused toimuma järjest suurema järjenumbriga ruutudel (kuni 9-ni)...
    Hea oleks, kui te praegu lepiksite tõsiasjaga - mingi imevalemiga jäävad kanvaade klikihalduritele meelde muutuja kanvaaNumber väärtused 1-9. Ühel ilusal päeval aga põrkute nende nähtustega jälle kokku.
    Nende teemade ümber jahumist tähistatakse sõnadega "Leksikaalne skoop" ehk "Lexical scope" (funktsioon näeb seda ümbrust, kus ta on defineeritud) ning "Sulund" elik "Closure". Funktsioonidest on saanud "sulundid", kes tassivad kaasa tema loomise ajal eksisteerinud temast ülalpool olevate muutujate väärtusi. Tõeline "sulund" kasutab neid väärtusi, tavapärane ei kasuta, kuigi võiks seda iga kell teha. Nii võib kohata vaheldumisi väiteid, et iga funktsioon on sulund ja väiteid, et näe, see funktsoon ikka tõeline sulund ei ole...
    Nii et leksikaalses skoobi korral funktsioonid sarnanevad inimestega, kes ühest firmast teise minnes põhilises säilitavad need hoiakud, mis kaasa antud koolist ja ülikoolist.
    Erinevalt inimestest sellised funktsioonid lausa põhimõtteliselt ei taha midagi teada oma "uutest väljakutsetest" ja asjaoludest, miks seda väljakutset tehti...
    Iga tervemõistuslik firmajuht annaks sellisele tegelasele üsna pea kinga.
    Funktsioonidega nii ei ole, "sulund" on tänapäeval väga populaarne nähtus, hoolimata püsivast peavalust, mida professionaalse slängiga mittekohanenud progejale sellega on võimalik tekitada.
  • Meie praegusteks vajadusteks piisab täiesti sündmuste halduri programmeerimisest kujul x.onclick = function() {kood siin};. Sellest hoolimata võivad ette tulla olukorrad, kus see enam nii ei ole. Eelkõige puudutab see vajadust siduda ühe ja sama sündmusega mitu haldusprogrammi.
    Näiteks window.onload-ga sidumine võiks olla selline sündmus. Kui kirjutada TTT II mängu omaette, käivitades seda oma arvutis, siis selline vajadus puudub. Aga näiteks minu Trips Trapsi versioonid pidanuks juba sellega arvestama (ja tõtt öelda eriti ei arvestanud, ma lihtsalt lootsin, et blogikeskkond ehk oskab selliste amatööride eest ennast piisavalt hästi kaitsta).
    Minu blogis võinuks blogikeskkond vajada omi window.onload haldureid ning mina oleksin võinud selle kergesti ära rikkuda. Tõsi, ainuke tõsisem kaotaja oleks olnud minu enese blogi, mis poleks käivitunud normaalselt ja minema peletanud viimasedki lugejad, kes veel siin käivad.
    Vanasti tehti selleks alati nii - funktsioon windows.onload haldur salvestati muutujasse old_onload ning uus haldur pidi ära tegema kõigepealt oma töö ja seejärel käivitas selle "old_onload"-i uue funktsiooni sees.
    Nagu ma nüüdseks olen õppinud, nii enam minu (ja teiste amatööride õnneks) ei saa juhtuda, sest rohkem JavaScripti õppinud programmeerijad enam iial ei kasuta minu poolt kasutatud sündmuste halduri sättimise viisi kujul window.onload = function() {}; Tõtt öelda on see meetod lausa taunitav (deprecated), viitav kas õppimisvõimetuse sündroomile, s.t. taunprogrammeerijale või algajale. Praeguseks, isegi IE-s (vähemalt versioonis 11 peaks olema kõik OK) on nii, et sündmuste haldurile lisatöö lisamine toimub nii:
    el.addEventListener(sündmuse tüüp, meil "click" või "load",
    ,funktsiooni NIMETUS või kood kujul function() {kood},
    false - sellest hiljem, mida see tähendab)
    Nüüd see sündmuse haldurprogramm vaid lisatakse olemasolevatele ja teiste töötlejate koodi ei eemaldata.

Kliki käitlemise 2 faasi

Sündmuse käitluses on veel üks nüanss - saladuslik 3. parameeter addEventListener() meetodis, mis millegipärast on false. See on seotud elementide paiknemisega üksteise sees. Igal elemendile on võimalik sättida sündmuste haldurit ja kohe kerkib probleem - millist eelistada. Ka TTT mängus on mängulaud div märgisega elemendi vahel, id TTTII. Ka selle elemendi külge on võimalik lisada sündmuse käitlejat. I faasis püütakse sündmus kõige ülemise elemendi halduri poolt kinni ning see annab ülesande, kui see ei tundu küllalt tähtis, üle DOM puus alamatele elementidele. Bürokraatia lõpeb kõige madalamas positsioonis paikneva elemendil. Seda faasi nimetatakse püüdmisfaasiks (capture phase). Selles faasis lisatavatele püüduritele või halduritele tuleb see kolmas parameeter sättida true-ks. Järgnevat faasi nimetatakse mullitamise faasiks (bubble phase). Nüüd annavad sündmuste haldurid tulist kartulit edasi alt üles, järjest tähtsamatele elementidele DOM hierarhias. Kõikidel selles faasis lisatavatel haldurprogrammidel peab see kolmas parameeter olema false. Ja kogu see muinasjutuline töötlus toimub vaid ühe hiirekliki jooksul! Õnneks ei ole tegelikus elus neid mullistamisi ja püüdurfaase vist väga palju kasutatud, muidu ei õnnestuks vist netis enam ühte hiireklikki ka teha, ilma et arvuti lootusetult kinni ei jookseks. Ja IE vist veel ei ole hakanud püüdurfaasi kasutama, nii et peab piirduma sündmusemulli veeretamisega alt üles. Ma usun, et selletagi on võimalik tekitada halle juukseid nii kasutajale kui ka programmeerijale.

Globaalsetest muutujatest, mida enam ei ole

Mõni probleem võib osutuda üllatavalt lihtsaks. Kirjutasin TTT II variandi alguses, et "peab uurima, kuidas globaalsetest muutujatest lahti saada". Minu blogirullis osutus see suureks probleemiks, kuna TTT I variandi kood suurel määral on suguluses TTT II variandi koodiga ja seetõttu vähemalt blogirulli sees pidin mõne funktsiooni ümber ristima, sest sirvik näeb korraga kõiki skripte, nii TTT I koodi skripti, kui TTT II skripti. Nii et TEGELIKULT eesriide taga mängisite natukene teistsugust TTT skripti, kui ma avalikult välja tõin - mitmed funktsioonid, mis TTT I variandiga ühise nimega (aga veidi erineva koodiga), olid ümber ristitud. Selgub muidugi, et see oli lahendatav KAHE (jah, KAHE!!) reaga. Kogu TTT II kood tuleks ümbritsega selliste ridadega:
ALGUSESSE KIRJUTAGE:
(function() {
// siia tuleb kõik see kood TTT II-st.
// Kõige lõpus aga on:
}());
Sellist funktsiooni nimetatakse
Kohe Käivituvaks FunktsiooniAvaldiseks,
originaalis Immediately Invoked Function Expression - IIFE
Algselt on selliste asjade mõte olnud vist pigem mingite kohe kohe käivitatavate asjade loomine, mille jaoks nime ei tasugi raisata. Praegu aga on tegemist väga mugava vahendiga, sest funktsiooni kesta sisse saab tegelikult kõike, mida soovitakse lõppkasutaja eest varjata, ära peita. Kõik muutujad on lokaalsed selle anonüümse, nimeta objekti sees ja ometi üksteisele nähtavad, sest muutuja skoop või nähtavus ongi funktsiooni sisene, kõik funktsioonid, mis selle näota ja nimeta funktsioni sees, on ka üksteisele nähtavad ja kõige tähtsam - hiirekliklikile reageerivad funktsioonid function() {kanvaaKlikk(xx);} samuti näevad kõike selle skoobi sees, kuigi näotu funktsioon käivitus ju kohe ja lõpetas oma tegevuse. See on nüüd üks kohene näide sellest, et algselt hirmsegasest asjast nimega SULUND võib kohe tulu tõusta... Mis veel rõõmustavam - JavaScripti sees joonistamine ja klikihaldurite paigaldamine andis kohe praktilise väljundi - TTT I versioonis peab onclik atribuudis viidatud kanvaaKlikk() olema avalikkusele nähtav funktsioon, sest sellele viidatakse HTML teksti seest ja sinna anonüümse funktsiooni sisse peidetud seltskond välja ei paista.

august 26, 2014

Harjutusväljak

Panen siia kokku harjutus- või proovikastid eelmisest kirjutisest, s.t. saab ise katsetada oma programmijupikestega ning joonistada midagi kanvaale.

UUS!

Alustasin täna, 29.08.2014 harjutuste loomist. Harjutuste algtingimused: selles blogis on olemas 3 tekstikasti ning üks kanvaakast (tekstikast - textarea tüüpi element, kanvaakast - canvas tüüpi element).
Programmikast sisaldab programmi ( elemendi id on "programm"). Logikasti saab kasutada programmi väljundina, selle tekstikasti id on "logi". Kanvaakasti ehk lõuendit id-ga "louend" saab kasutada graafiliseks joonestamiseks, siin "joonista lõuendile" teeb ära kanvaakasti "avamise", nii et "kontekst" nimelise objektile käske andes saate kohe joonestama hakata, kui kasutada joonestusprogrammiks kanvaaprogrammi nimelist kausta.
Saate kasutada "sisseehitatud" funktsiooni "logi(lisaLogiKasti)", mis lisab logikasti muutuja lisaLogiKasti sisu, tehes enne reavahetuse.
Võib ka kasutada funktsiooni alert(teade), mis toob ekraanile teate Windows uues aknas ning kõike muud kräppi, mis on olemas JavaScripti standardvarustuses.
Pakette, nagu "Jquery" tänase päeva seisuga (28.08.2014) ma veel lisanud ei ole ja ei tea, mis juhtub nendega blogimise keskkonnas.
Tekstikastide all on praegu 3 nuppu. Esimene käivitab programmi, teine puhastab tekstikasti, kolmas nimega "Harjutus: Kaks nuppu" avab minu esimese prooviharjutuse. Hommikuse seisuga seal midagi ei ole, lõunaks peab lindilt tulema esimene näidis! See ei takista teil oma oskusi näitamast, näiteks töötab väga hästi kuulus Gaussi ülesanne 100 arvu liitmiseks
var sum=0;for(var i=1;i<=100;i++) sum+=i;logi(sum);
Selle ülesande lahendas Gauss oma matemaatikaõpetaja meelehärmiks peaaegu momentaalselt, õpetaja nimelt tahtis oma lastele tööd anda, et tegelda oma asjadega...
Et teha aga täitsa oma HTML lehekülje elementide loomine võimalikuks selle blogi kontekstis ilma blogikirjutist väga ära rikkumata, tekitasin nendele tekstikastidele ja nuppudele esivanema id-ga "isa".
Selle alla saate luua "lapsi", näiteks nuppusid, oma tekstikaste, oma paragrahve, päiseid, ühesõnaga, mida iganes.
Võite seda rahulikult teha, sest pärast minu lehekülje uuestiavamis on minu õnneks teie looming "haihtunud".

Logikast nimega logi

Programmikast nimega programm



Kanvaa nimega louend

Siin peaks olema kanvaa, kui seda siin ei ole, on teie sirvik pärit Noa aegadest!

Kanvaaprogramm

august 25, 2014

Laiskuse apoloogia_I












Kes iganes tahab hakata koodinikerdamisega tegelema, peab oskama põhjendada seda, miks asjad ei lähe nii, nagu tahaksid. Nii ka mina. Üks tekst peaks olema valmis kirjutatud ülemusele, teine võimalikule kliendile, kellega ka suhtled ja kolmas iseendale.
Praeguses õndsal ajal ei oma kaks esimest teksti väärtust, nii et peaks selgeks tegema, MIKS ei valminud TTT_II versioon lubatud ajaks, s.t. pühapäevaks, kl. 23.59 Eesti aja järgi??
Ma arvan, et põhiliselt seetõttu, et valisin vale strateegia. Tahtsin TTT kirjutada ümber nii, et veenda lugejat - absoluutselt kõik elemendid, v.a. <body>, on võimalik jooksu pealt tekitada teie HTML leheküljes
. Kõik toimis kuni hetkeni, mil tahtsin hakata tekitatud elemente siduma sündmustepühiselt käitatavate funktsioonidega.
Ja siis selgus, et onclick "sündmuste haldur" ei taha käivituda. Miks ta seda ei tee, jääb selgitada lähipäevil, aga et jõuda järgmiseks pühapäevaks kl. 23:59 mingi suhteliselt õpetliku TTT_II versioonini, peaksin valima praeguseks strateegia, kus ma ei tekita kõike käigult, vaid vähendan kanvaade arvu 1-ni, mis oleks arvutigraafikas normaalne ja lisaksin nupud ja viled, mis parandaksid programmi loogikat. Kui sündmuste haldurite kohta saab selguse majja, siis panen selle onclick sündmuse (s.t. klõpsitakse kanvaal) JavaScripti põhiselt püsti, võimalik, et elementide tekitamise toon ka siiski sisse, ainult et ilma kohese sidusmisega sündmustega (näiteks ei ole päris alguses vaja kogu infot kuvada, seda võib ka peita, ehk ka vajadusel tekitada).
Hakatuseks aga panen homme õhtuks püsti harjutusväljaku - silmas pidades nii potentsiaalset JavaScript õppijat, kellel kõik uus kui iseennast - päris mugav on oma blogist väljumata mõnda koodijuppi kohe testida, nii et ei pea ronima Firebug-i, lisaks saaks harjutusväljakul mõne eeltöö kohe ära teha - näiteks kanvaa elementide programmeerimisel.
Lisaapoloogiaid, mis muuseas on ka tõesed:
Käisime P kalal, poeg püüdis 9 viidikat lisaks kalalaagris püütud 20 kalale ja abikaasa 3,

s.h. ESIMESE kala üleüldse, mis osutus särjeks. Tõnis teab, kas oli roosärg või see teist tüüpi särg.
Mina piirdusin filosoofeerimisega. Mahajäetud nutikas W8 föön oleks ehk suutnud vähendada mahajäämust TTT-ga.
Teiseks lugesin laupäeva õhtal läbi Tanel Tammeti mõned antud viited (otsige tema sissejuhatusest infotehennoloogiasse lõpust need üles. Peaks kuhugi (peale harjutuste lisama sujuvalt täieneva lingipuru, kuid ainult testitud linkidena. Mida ise pole lugenud, seda põhimõtteliselt ei soovita. Ärge lisage spämmi Internetti, viidates kräpile, mida ise poole lugenud, aga mõni autoriteet tungivalt soovitab.)
Näited: "Tao of Programming".
Paul Grahami mõne jutu - näiteks miks mõned häkkerid on kõvemad kui teised ja kuidas selliseid ära tunda, kuidas teha startup firmat ja edukas olla.
Douglas Crockfordi jutte ka tasub tõsiselt võtta.
Aga kujutlega nüüd situatsiooni - E. hommikuks peab toimima laoarvestuse uusversioon ja ma vastan nõudlikule pearaamatupidajale, et lugesin nädalavahetusel "Tao of Programming...". Et kirjutage paar päeva kasumiteenimist või vähemalt selle arvestamist korstnasse ja ilmselt mõni päev hiljem peaks pearaamat tegema mõne öötunni lisaks...
s.t. elukutse üheks hädaks, mis meenub 10 aasta tagusest ajast, on 24 tunnised progemise tsüklid ja sellega peab arvetama. See ei ole ainult isiklik kogemus - ka Paul Grahami jpt... juttudes ja igapäevaelu vaatlustest selgub, et uusversiooni tekitamine ei ole meelakkumine.
btw. veel on olemas natuke uniseks jäänud foorum pinu.ee. Kui asi väga kirveks läheb, võib mõne suure murega sinna pöörduda, seal paistab olevat professionaale, kes ka vastavad ja teavad, mida vastavad...









august 22, 2014

Mida teha edasi TTT mänguga?

Tänasel mõtterünnakul tahaksin mõelda edasi, kuidas seda mängu võiks paremaks teha ning ühtlasi selle käigus õppida enam-vähem viisakalt programmeerima JavaScriptis.
Lisaks tuleks kindlasti uurida HTML lehekülgede kujundamist - see võiks olla siiski JavaScripti üks põhilisemaid rakendusi vähemalt alguses.

 Programmeerimiskeel iseenesest aga võimaldaks edasi arendada oma oskusi mängude programmeerimise vallas.
Need oleksid ehk sellised  filosoofilised eesmärgid... 
Aga ma ei tea  paremat moodust kokanduse tundmaõppimiseks, kui kokkamine.
Täpselt sama põhimõte kehtib ka programmeerimises. Meil ei ole teisi võimalusi, kui kulutatud tagumikutunnid vahel ka helesinise ekraani ees.


Niisiis võiks proovida hakatuseks seda mängu paremaks teha ja valminud malli kohaselt veel mõnigi mõtlemismäng tööle saada.
Vahepeal leidsin võrgust üles ka ühe suhteliselt ohutu sportmängu nimega "Tellised". Seal tuleb reketiga palli suunates  tuimalt telliseid purustada. See on natukene parem, kui lõputu tapmine ja tagaajamine, millega praegu noorsugu rikutakse ... 
Kusagil peab tekitama nurga JavaScript kogunenud õppematerjalide ja töövahendite jaoks. Siin ma olen muutunud ettevaatlikuks.
Kõigepealt tuleb eraldada õpikud käsiraamatutest. Ja kui juba koostada käsiraamatut, peaks see millegipoolest olema parem, kui mõni teine käsiraamat või viide. Samad sõnad kehtivad õpiku suhtes - tuim järjestikune jutustamine ei ole eriti hea plaan. 
James Olivier on üks näide sellest, et nii tehnilist ala, nagu on kokandus, saab esitada nii, et isegi minusugusel paadunud härjasilmapraadijal tekiks isu ise praepanni juurde minna ja mingi hõrgutis valmis nikerdada.
Iga töövahend, algul on selleks ka õpik, aga peab olema mugav kasutada.
Üks arvutigraafik, kelle juttudest loodan ka mõne jupi siia panna, märkis õieti - ärge raisake aega oma töölaua peale, mõelge selle peale, millise TOOLI peal te istute. Seal peab olema mugav. Sarnane asi kehtib ju ka perenaiste puhul köögis. Kui köögis ei ole mõnus toimetada, siis on midagi valesti: vale inimene köögis (ka võimalus, mitte iga inimene siin planeedil ei pea minema ekstaasi for(;;) tsüklite peale mõeldes), või on köögis asjad valesti, mitte nii, nagu sellele inimesele kohane.
Mõni inimene näiteks armastab põhjalikku, ranget, süsteemset õpet. Neile sobiks alustuseks Flanagan, veel mõni süstemaatiline õpik ja alles siis võtku pann kätte. Mina arvan siiski ,et hea mõte on kohe alguses köögis toimetada ja selle kõrval hoolega vaadata ka kõiki Olivieri suurepäraseid videosid. 

Usun, et ei ole paremat õpikut kui ISIKLIK KOGEMUS.
Kuid seda kogemust ei tasu vägisi muuta negatiivseks. Ühe asja suhtes ei maksa iial muretseda - puugid (bug) tulevad ise, neid ei maksa vägisi välja kutsuda ja kui nad on juba programmi kallal, ei ole põhjakõrbemine ka kaugel. Nii et vägisi põhja kõrvetama hakata ei maksa iial.
Aga mis siis edasi, küsib kiuslik lugeja? Õpin ära JavaScripti, oskan kirjutatada "Totrusest" kümneid kordi vingemaid videomänge? Kirjutasin sellest oma CV-s ja tulemus?....Mingi hale nurgake mõnes mängusid treivas kontoris. Igareedene ihunuhtlus kogunenud puukide pärast. Aruandlus, miks viimasel nädalal ei ole koodi lisandunud ühtegi rida... ja nii edasi.
Elu argipäev.

Igast armastusest saab kord abielu, või ei saa, kui veab, ütleb kogenud inimene selle peale ja tark paneb siin punkti. Ehk ongi parem säilitada kõik oma illusioonid, nagu olevat öelnud Wilde paadunud vanapoiste kohta ...või oli see Vilde?
Meid, ükskõik kui kõvadeks me end peame või isegi oleme, ei oota siin planeedil kusagil pudrumäed ja piimajõed. See kehtib isegi infotehnoloogia vallas...
See viimane lõiguke natuke on initsialiseeritud eilsest nõupidamisest parema kasutajatoe osutamise küsimuses ja ma ei usu, et koodinikerdajate ülemused on paremast tõust.
Ei ole uut päikese all, ütleb Saalomoni tarkuseraamat. Kuidas ikka rohkem probleeme ajaühiks ära lahendada. Kuidas selle kõige juures dumbjuuserist välja pigistada rahulolu. Kuidas seda kõike ilusti kirja panna, et statistiline programm seda ka näitaks...
Tagasihoidliku FIE-na kunagi kümnend tagasi märgiksin, et isenese peremees olek ka väga tore asi ei ole, see tähendab ikkagi ka 24/7 rühmamist mingi ühe programmimonstrumi kallal, et see asi ka reaalselt muutuks kasutuskõlbulikuks...
...
Tuleksin tagasi pilvepiiri peale ja mõtleksime edasi TTT parendamise teemadel.

Mõned mõttejupid (nikerdan ehk mõtteid päeva peale edasi, kui huvitab, tulge homme siia veel tagasi, pühapäevaks planeerin TTT fenomenaalse uusversiooniga mänguturule tulla...)
1) Uue mängu alustuseks ei pea lehekülge ümber laadima.
   Oskame kanvaade pealt sisu kustutada, muude asjade nullimine ei tohiks olla ka mure.
2) Võiks hakkama saada ühe kanvaaga, neid ei pea olema 9 tk.
3) HTML-s ei pea olema onclick() klauslit, isegi kanvaa võib tekitada JavaScript.  ja onclick() funktsiooni kleebib elemendile külge ka JavaScript.
4) Siia ei saa käia alert() võiks asenduda sellega, et sinna EI SAAGI KÄIA (s.t. ei ole võimalik juba märgitud ruudule midagi kirjutada).
5) Üheks mängijaks võiks saada arvuti vähemalt juhuslikult mängiva idioodi tasemel.
6) Mängu alguses võiks tiksuda mõnda aega lühike demo, mis õpetaks veel TTT-ga kursis olevaid isikid õieti mängima ja miks ka mitte õpimaterjal (sageli kasutatavad avangud, parimad partiid etc...)
7) Võiks lisada malekellad, et ditsiplineerida mängijaid
8) Kõige lõpus, see vist tuleks juba versioon III, võiksin proovida seda kõike kirja panna OO (Objekt - Orienteeritud ) stiilis. Otsin sobivat näidismaterjali selleks, ei tahaks olla jalgratta leiutaja rollis. On olemas üks manuaal, kuidas teoreetiliselt asju teha, aga KONKREETNE kood puudub ja sellisest üldisest vahutamisest on üsna villand.


august 11, 2014

TRIPS TRAPS TRULL KOOD - VARIANT I

Kuidas oma mängu püsti panna ?

Toon lõpuks ära selle mängu "koodi".
Minu poolt ümberkirjutatud TTT sisaldub 3 failis:
"trips_traps_trull.html" - TTT põhi
"trips_traps_trull_stiil.css" - TTT stiil
Märkus
Siin küll palju huvitavat ei ole, sest mängimisel sageli kasutatav element canvas (kanvaa ehk lõuend eesti keeles) ei arvesta stiilifailis kirjapanduga, v.a. ALGUSES. Kuid stiilifaili võib vaja minna edaspidi, kui muud elemendid lisanduvad, mis korrektselt koos stiilifailiga koos töötavad. Praegu on seal vaid mitte muutuv kanvaa äärejoone kirjeldus.
"trips_traps_trull_jscript.js" - Põhiprogramm.
See on kindlasti mängu tuum, mingeid mänge ilma programmeerimiskeele osavõtuta teha ei anna. HTML programmeerimisekeeleks on javascript.
Kopeerige allpooltoodud tekstikastides sisu vastavale nendesse failidesse (notepad++ ehk on juba käima saadud, notepad vinnab ka välja) ning paigutage ühte kataloogi. TTT HTML faili peal klõpsimine peaks võimaldama seda mängu mängida.
PS!
Minu praegune piinlik moment on bloggeris kusagil peituv programm, mis järjekindlalt kirjutab igale poole, kus kohtab </body></html> sümbolijada 2 skripti (<script> ja </script> vahele peitunud jura). Mina hetkel sellest jamast lahti saada ei oska. js. programmi jätab skript rahule, kõik see asi puudutab HTML lehekülgi, mida näiteks toon. Kolme viimast rida peate niisiis html tekstide puhul parandama: lõpetage ära body ja html märgised suurem märgiga ja kustutage samasugune soovitus body ja html lõpumärgiste vahelt ära! Lühemate lehekülgedega saab hakkama ilma textarea-ta kasutades väiksem märgi ja suurem märgi jaoks eritähistusi, suuremate lehekülgedega nii ei tahaks toimetada.
Tekstikastidesse võib muuseas oma lõbuks ükskõik mida kirjutada või kustutada,see ei häiri kedagi - ärge kartke, keegi kaugemal ei saa teada iial, mida te sinna tekstikastide sisse panite või ära võtsite. See info kõik jääb teie sirviku ja teie teada, minuni või mistahes serverini see ei jõua ...
Pärast sisu "uuendust" teie looming tekstikasti seest kahjuks haihtub. Selleks tuleb küll, tõsi, lk. kinni panna ja uuesti avada - naljakal kombel tekstikastidesse sehkendatud mõtteid F5 ei puuduta. Vähemalt Firefox-iga oli nii... Allpool tuleva TTT mängu "uuestiavamise kood" selles mõttes on võimsam - siin taastatakes ka tekstikasti algolek.

TTT HTML kood

Stiililehe kood

TTT Jscript kood

Märkused HTML koodi juurde

  • Õppija, kes HTML puhul toetub ainult minu mängudele ja näidetele, võib jääda vaeslapseks. Allpool, TTT ja HTML sissejuhatuses soovitasin kõige alul alustada Codeacademy (otsi googlega!) peal olevate ingliskeelsete kursustega. Mingil hetkel võib soovitada ka eestikeelseid, praegu ei tee seda mitte, sest mingite kohtade peal jooksevad harjutused kinni ja ei saa ei edasi ega tagasi. Saab soovitada mingid vigased harjutused vahele jätta, aga ma ei soovita. Tehke see asi korda, vastavate materjalidega tegelejad!
  • Tundub, et kõige põhjalikum HTML sissejuhatus on saidil Pyramdesign praegu mulle tundmatu autor On näha, on põhjalikult vaeva nähtud. Mõned asjad tunduvad vananenud, kooditabeli puhul peaks rõhuma ntx utf-8, raamide asemel midagi uuemat välja pakkuma etc... Midagi täiuslikku ei ole tehniliste asjadega tegelejal iialgi võimalik välja otsida, guugeldage, katsetage, äkki leiate veel soovitusi ja andke teistele ka teada, mis mõnes kohas on hästi, mõnes halvasti
  • Sellest hoolimata katsun vähemalt mõelda selle peale, et asja esimest korda uurijale ei oleks niinimetatud õppimise kõver liiga järsk ja vähemalt enamik asju veidi seletatud.

Päiste märgistest

Rida <h1> TRIPS TRAPS MEGATRULL</h1>
tähistab pealkirja, on olemas märgised h1, h2... kuni h6, tähtsuse järjekord määrab ka nende vähenemise. Kuid kui avamärgisele lisada style="color:red ...ja muid omadusi"... siis saab oma pealkirja teha ükskõik milliseks soovitakse. style rea asemel peaks vastav koht olema kirjas stiilifailis, siis peaks vastav pealkiri (h1 näiteks) omama lisaattribuuti class="mingi nimi", kui kõik h1 pealkirjad sellest klassist võiks olla sedamoodi. Kui tahate vaid sellele pealkirjale eriomadusi, siis peaks valima attribuudi id="mini unikaalne nimi", sellele saab .css failis ilusti viidata ja igatpidi disainida, nagu soovitakse.
Kanvaa märgis, eesti keeles ka lõuend,
<canvas id = "kanvaa1" width = "50px"
height = "50px" onclick="kanvaaKlikk(1)">
</canvas>

on uus ja väga paljulubav element HTML (5)-s. See võimaldab HTML lehekülgedes vahest esmakordselt standardsete vahendite abil luua mõistlikku graafikat.
HTML-s saab ja TULEB ära märkida kanvaa kõrgus ja laius pikselites. Standardmõõdud on 300px laiust ja 150 kõrgust. Näete neid kanvaa attribuutides. Kui nüüd teha nii, et selle kõrguse ja laiuse määramine jätta stiilifaili ülesandeks, jookseb asi kolinal ämbrisse - algul joonistatakse kanvaad ilusti välja, aga seejärel seda ignoreeritakse, sirvik lähtub sellest, et html failis olid kõrgus ja laius määramata ja joonistab eeldusel, et kanvaa on 300 punkti lai ja 150 punkti kõrge.
Selline läbikolistatud ämber siis. Sellest hoolimata, kuna mingeid muid muudatusi ja joonimisi kanvaa äärel ei järgne, on kanvaa ääre värv ning laius järgnevas stiilifailis ära määratud:
canvas { border: 1px solid red; } Sama asi näeks canvas märgise juures välja umbes nii: style="siia kirjuta see asi, mis praegu loogeliste sulgude vahel" Natuke ikkagi "hoiab aega kokku" - meie näites on ju 9 kanvaad ja iga kanvaa juurde peaks selle border rea kirjutama...
Meie näites (tundub, et piisab ka ühest kanvaast, aga lähtun originaali ideest) tuleb sirvikul opereerida 9 kanvaaga. Et nende vahel vahet teha, on neile vaja omistada id, mida 9 korda ongi tehtud ja saadud 9 kanvaad id-dega kanvaa1... kanvaa9. Kõik ülejäänud joonestamine toimub juba jscript vahendite abil, tavaliset vahenditega ei saa siin midagi ära teha. Lisaks, et variant II-s tekitame kogu kanvaanduse javascript vahendite abil, aga täna, et elu mitte liiga keeruliseks ajada, teeme algusotsa valmis HTML-s.
Esimene märkus programmeerimise kohta:
<canvas> juurde kuuluv attribuut onclick="kanvaaKlikk(1)
seob hiirekliki elemendil kanvaa java scriptis kirjutatud funktsiooniga kanvaaKlikk(). Sulgudes tuleb anda parameetriks selle kanvaa number, kus klikkamine aset leidis. Funktsiooni leiate ise javascripti failist üles ja see peamiselt joonistab sinna kas X või O kujulisi märke, või teadustab sellest, et seal juba on midagi joonitud. Lehekülje elus on ka teisi sündmusi, mille puhul saab sundida sirvikut midagi tegema. Sündmuste töötleja (ingl. keeles event handler) sidumine omakirjutatud programmijupiga on peamine meetod, millega javascript suhtleb inimestega. Teiseks mooduseks on DOM puu objekte (inimkeeles HTML lehekülje elemente, s.t. kahe märgise vahele pandud sisu) kas mingi sündmuse ajel või lihtsalt niisama muuta. Neid saab tekitada ja kaotada ning sellega ma mängu järgmistes versioonides tegelemegi.
Ülejäänud jutu kanvaast ja graafika joonestamise lihtsamatest võimalusest katsun ära märkida JavaScripti käsitlevate märkuste lõpus / peenemat juttu koguni eraldi loona.

Mõned märkused stiilifaili kohta

  • Milleks stiilifail hea on?
    Üheks põhjuseks oleks sisu ja kujunduse lahutamine niivõrd, kui see on võimalik ja vajalik. Praegu tegelikult eriti ei ole, hoiab aega kõvasti kokku, kui ei nikerda üldse mingi 3 realise stiilifailiga ja lingiga sellele. Allpool toon ära ka võimaluse stiilifail html faili sisse istutada. Üldiselt aga siiski on hea, kui html peamiselt sisaldab sisu ja sisu erinevatele osistele viitavaid märgiseid ja kõik laused, mis ütlevad, kuidas see asi peaks välja nägema, tuleksid kusagilt mujalt. Teine, veel lihtsam põhjus on aja kokkuhoid. Pange samasse kataloogi see üks fail ja nüüd on teie uue html lehekülje tegemisel vaja lisada vaid see üks viide kujundusfailile ja kohe hakkab valmiv lehekülg ilus välja nägema. Kolmandaks saab seda asja kergemini muuta. Neljas pluss - eriti praegu - sama veebilehte saab näidata erinevalt. erinevatele seadmetele - nutikas telefon peab nägema asju erinevalt kui tavaarvuti, aga kui asutakse lehte välja printima, peab lähtuma paberile tekkivast pildist. css faile on siis vaja mitmeid.
  • Miks selline imelik laiend - css ja nimi - Cascading Style Sheet? Tõlgituna võiks see olla kaskaadlaadistik (Vallaste arvutisõnastik) või astmeline stiili- või laadileht.
    See kaskaadsus või astmelisus tähendab seda, et sirvik arvestab kõigepealt sirviku enda seadetega, kui serveri pealt mingit infot mingi elemendi kohta ei leia, kui aga leiab, siis võetakse kõigepealt arvesse .css fail, mille kirjutab üle veebilehe sees olev <style> ja </style> vahel olev tekst, ning kõige prioriteetsem on märgise enda juures eraldi attribuudina märgitud style="color:red" näiteks. Isegi siin on erandeid, mingi lisamärge color:red !important võib seda prioriteeti tõsta ja koguni kõige tähtsamaks panna. Kui kaaskaadlaadistik loodi, käis kõva vaidlus selle üle, kas kasutajal lasta otsustada, kuidas ta oma lemmikveebilehti peaks vaatama või mitte. Lugesite õieti, kasutajal on selline võimalus tõesti olemas. Firefox profiilikataloogi tehke kataloog chrome ja sellesse fail userContent.css. Sinna võite väga vabalt kirjutada sellise toreda lause, nagu body { color:red } ja see tõesti värvib sirvikus näiteks postimehe või delfi tekstid PUNASEKS. Testitud! Töötab! Sõbrale väikese tünga tegemiseks (eeldades, et te mingi mõistliku aja vältel siiski teada annate, mida tegite) sobiks see päris hästi, ja muidugi peaks sõber olema selliste asjade huviline, mitte näiteks kohalik poksimeister. Peab olema realist.
  • CSS "lausete" põhikuju on väga lihtne:
    selektor või mitu selektorit, eraldatud komaga
    { omadus1:omadus1-e väärtus;
    omadus2:omadus2-e väärtus;
    ....
    }

    Selektor on tavaliselt märgis, neid, nagu juba ülal öeldud, võib olla mitu, näiteks h1,h2,h3,h4,h5,h6 { color:red; } värvib kõik pealkirjad punaseks. Omadusi ja nende väärtusi on aja jooksul tekkinud kui seeni ja neid peab käsiraamatutest järgi vaatama. Juba värvide nimetusi (õnnetuseks inglisekeelsed) on üle 100...  Värvide jaoks saab kasutada ka koode, aga kasutage alati inimkeelseid nimetusi, kui võimalik.
    Peale märgiste ja nende loetelude on aga veel kaks põhilist selektorite tüüpi, mida tõesti vaja läheb (lisaks nendele on veel ja veel võimalusi, aga siin ma peatun). Klass (class) on omadus, mida saab märgisele alati juurde kirjutada. Näiteks <p class="punane_element"> defineerib paragrahvi kuuluvana punane_element klassi. btw, ei soovita jamada tühikutega klassi ja id nimedes... Kasutage progejate jaoks klassikalist ALAKRIIPSU sõnade eraldajana, kui vaja peaks minema. Kõik paragrahvid, mis on klassis "punane_element" (ja ainult need paragrahvid) saab nüüd css faili abiga nii punaseks värvida:
    p.punane_element {color:red;}
    Äkki tahate pealkirju ka punaseks teha selle klassikuuluvuse abiga? See lause, mis ülal toodud, pealkirja alustava märgisega
    <h1 class="punane_element"> 
    punaseks ei värvi.
    Lause .punane_element {color:red;} aga värvib sellise avamärgisega pealkirja ka punaseks.
    id märgis on ühekordse kasutusega - seda saab ainult ühele märgisele lehekülje piirides omistada. NÄiteks <p id="lilla" > võimaldab css failis sellele paragrahvile nii viidata:
    #lilla {color:red;}
  • Kolm võimalust oma css stiili html leheküljele "sisse istutada".
    Kõige viisakam võimalus on stiilifailile ilusti viidata. Kuidas seda teha - seda vaata juba ülalpool toodud koodist.
    Teine võimalus on kogu faili sisu kirjutada päisesse <head> ja </head> vahele, kasutades märgist style.
    kogu body elementi ilusti punaseks värviv stiilifail võiks päisesse "istutatuna"välja näha selline:
    <style> body {color:red;} </style> Kolmas võimalus, nn inline kood, on see asi body avamärgise sisse kirjutada.
    <body style="color:red;">
    Seda peetakse kõige inetumaks viisiks, aga veel inetum viis on mingi märgise väljanägemist kirjeldada mingi muu meetodi abiga, kui style=... Vanast ajast on selliseid võimalusi jäänud ja mingitel põhjustel on ka näiteks kanvaa elemendi puhul vaja selle elemendi suurus kohe html faili sisse kirjutada mulle arusaamatutel põhjustel, ütleme lihtsalt: programse kala tõttu.
  • Viimane märkus
    Põhjus, miks ma selle stiilifailiga nii kaua jamasin, on aga peamiselt selles, et ma ei oska praegu leida head varianti, kuidas alustada javascript kirjeldamist. Kindlasti ei tahaks seda teha nii, nagu seda teeb David Flanagan. Kõik on ilusti kirjas, aga selle järgi ei saa õppida. Minu suureks eeskujuks oleks pigem
    Invent with Python
 , suurepärane sissejuhatus igasugusesse programeerimisesse. Aga kas ma viitsin nii põhjalikult sellega jamada, on iseküsimus. Ehk siis peab siia trehvanud koodinikerdamisega alustaja veidi järsemate kurvidega leppima. See raamat aga on shedööver ja tasub läbiuurimist isegi siis, kui ei taha õppida Python keelt.

Sissejuhatavad märkused javascript koodi kohta

  • Javascript on omapärane keel - ta hakkab meeldima tasapisi, mitte kohe. Üheks veidraks asjaks selle keele juures on see, et õppureid kästakse usinalt kasutada sisuliselt ühtainukest väljundfunktsiooni nimega console.log(). See asi aga kirjutab oma väljundi kuhugi müstilisse aknasse, mille saavat kätte F12 abiga. Kui installeerite firefox juurde firebug-i, see on kindlasti vaja ära teha, siis näete kindlast muid asju ka f12 järel ja kui esimest ehmatusest üle, saate igaühe html "lehestikku" põhjalikult uurida.
    Aga päris alustuseks võiks olla midagi lihtsamat. Nuputasin hakatuseks välja tekstikasti (textarea) nimega "programmikast" ja nupu "Käita programm". Kirjutage sinna kasti midagi javascriptis ja vajutage nuppu. Pikemate programmide korral on ikkagi vaja appi võtta firebug, sest seal saab kõike ka siluda, kuid mõne rea puhul võiks sellisest kastist abi olla. Soovitatavate console.log() asemel võiks aga kasutada funktsiooni alert(), mis uues aknas väljastab soovitava sisu.
  • Lisaks nuputasin välja "logikasti". Kui kasutate alert() asemel MINU funktsiooni logiraamat(), siis see sisu peaks kirjutatama logikasti(). Näiteks praegu programmikastis ilutseva alert("Halloo õppurid!") asemele kirjutage logiraamat("Halloo õppurid!") ja vajutage programmi käitamise nuppu.
  • Kui te aga veel väga ei oska javascripti lauseid kirja panna. siis jätke programmikast ja logikast rahule ja nende kastide all hakkame närima TTT koodi koos tn. hädatarviliku kiirkonspektiga.

Programmikast


Logikast


Mõned ajaloolised märkused siiski enne imedemaale kukkumist

  • javacripti nimetab Douglas Crockford
    maailma kõige halvemini mõistetud programmeerimise keeleks
    Ma arvan, et seetõttu on mõningased märkused abiks.
  • Javascripti leiutas Brendan Eich  1995 aasta maikuus, 10 päeva jooksul. Algul kandis see keel nimetust Mocha ja nii võinukski jääda. Mocha on kohvisort mdx. Siis aga, kusagil 1995 detsembris sekkusid marketroidid ja kuna Java keel oli väga popp ja ka kasutatav vebis (praegu ka on), tuli vastav skriptiv keel ümber nimetada JavaScript.-ks. Õnnetu otsus, mis külvab segadust tänase päevani ja lisaks kõigele pidi Eich mõned asjad tõesti Javast üle võtma - arvatavalt siis loogelised sulud ja semikoolon iga Javascipti lause lõpus.
  • 1996-1997 võttis JavaScripti oma aluseks ECMA International(Euroopa arvutitootjate assotsiatsiooni organisatsioon, kes üritab kokku panna arvutialaseid standardeid. Nii võib kohata ka nime ECMA script. Standardina on Javascriptil veebi programmeerimises kindel esimene koht - ei pea isegi ära märkima, et kirjutad javascriptis, piisab javascripti teksti märkimiseks märgistest <script> ja </script>
  • Hoolimata kiirustamisest keele vermimisel on JavaScript TEGELIKULT üsna hästi õnnestunud mitmetes põhilistes punktides: näiteks ta on funktsionaalne ja objektorienteeritud. Need sõnad vaevalt, et praegu midagi ütlevad, aga loodetavasti mõne aasta pärast ehk ütlevad (ka allakirjutanu veel kavatseb läbi närida funktsionaalse programmeerimise õpikutest ja ka objektorienteeritust tuleb jõuga omandada - vanad halvad harjumused segavad siin mind enam, "puhast" õppurit need vaevad ei ähvarda.)
  • Ometi on javascriptis ilmseid puudusi, näiteks korralikult võrdlemiseks peate kirjutama kolm võrdusmärki "===". Aga need on siiski väikesed puudused ja pigem kaunistavad seda keelt mõnes mõttes.
  • Aastatega on javascript küpsenud ja saanud järjest paremaks ja on praegu täiemõõduline programmeerimise keel, mida võib ja saab julgelt kasutada igal pool.
  • Ei ole enam õige ka lause, et serveritarkvarana javascripti ei kasutata. Juba kasutatakse seal ka.
  • Brendan Eich on aga kahjuks anno 2014 sattunud äärmiselt vastiku rünnaku alla.
    Isegi nõnda vastiku, et wikis räägitakse rohkem sellest rünnakust kui tema elutööst, mis on äärmiselt väljapaistev, ja ilmselt poliitkorrektses meedias nii hakkabki olema. Mõned on pailapsed ja kui sattud poriloopimise märklauaks, näiteks sellel lihtsalt põhjusel, et oled religioossetelt veendumustelt katoliiklane, siis ei ole sind olemas. Toetagem teda kasvõi sellega, et uurigem põhjalikult tema loomingut, keelt tegeliku nimega Mocha...

Koodinäringu algus

Hakakem siis pihta, alustuseks sööksime ära kuni funktsioonideni tuleva osa:

"//" taga olev jutt ühel real on kommentaar.
Pikema kommentaari jaoks kasutage "/*" märke, siis võib juttu
üle mitme rea heietada ja lõpetama peab selle "*/"-ga.
Mida aga selline keerdsõnapaar - globaalne muutuja - tähendab ? Muutuja suhtes ei tohiks väga suuri probleeme olla - matemaatikaga sarnaselt saab viisakas muutuja sisaldada näiteks arve. Erinevalt matemaatikast võib muutuja sisuks olla ka tekst ehk string ning kaks inglisekeelset tõeväärtust: true ja false. Viimast tüüpi nimetatakse loogiliseks, ingliskeelses tekstis boolean tüübiks. (George Boole'i auks, kes kõikide koodinikerdajate hirmuks leiutas matemaatilise loogika, millega Peeter Lorents oma tudengeid kotib...) Sellised kolm lihttüüpi javascriptis tõesti on.
Muutujatele peab andma nime, mis algab tähega, mitte arvuga, edasi võib arve ka järjest ritta laduda. Tavaliselt mingite eriprogrammide puhul tikutakse muutujaid alustama selliste imelike, ka alguses lubatud märkidega, nagu ALAKRIIPS ja DOLLARI märk. See on ka võimalus, aga teie ärge nii tehke.
var kaik = 0; ongi selline lihtmuutuja deklaratsioon koos omistusega, var on erisõna selleks tööks. (lühend sõnast variable) Ei pea kohe muutujale midagi omistama, seda võib teha ka hiljem, kahes eraldi käsus või lauses: var kaik; // semikoolon lõpetab käsu ja järgmises reas k=0;
Hakatuseks proovige muutujate tegemine kohe ära, kasutades kontrolliks kas minu programmikasti ja logikasti või firebug-i: installeerige see, käivitage firefox, ja minu blogi, siis vajutage F12 ja otsige üles console. Pikemate jupikeste jaoks saab kasutada käsueditori ja saadud jupike Run käsu abiga (paremal) käima tõmmata, teine mood on käsurida saada alumiseks reaks firebug aknas (paremal ülal ühe noolemärgi juures on see moodi muutmise võimalus)ja seal iga käsu järgselt trükitakse välja selle käsu arvutatud tulem. Tavaliselt javascript aga nii ei tee, arvutatud väärtusega tuleb ise midagi teha, omistada mõnele muutujale näiteks või välja "trükkida", kasutades console.log meetodit. Aga konsooli ühekäsurezhiimis väljastatakse lause tulem automaatselt.
Kellele see firebugiga jahmerdamine ei meeldi, võib ka minu programmikastis katsetada - kirjutage sinna näiteks
var numbrimuutuja=0;
logiraamat(typeof numbrimuutuja);
tulem näitab välja selle muutuja tüübi - number. Proovige ära ka tekstimuutuja või loogilise muutuja tegemine ning lõpuks tehke ainult var deklaratsioon - siis saate vastuseks undefined.
Javascript on mdx tõstutundlik, nii et muutuja ja Muutuja ongi kaks eri muutujat. Muutujate nimed soovitatakse kirjutada üldiselt väikeste tähtedega,kui koosnevad ühest sõnast ja alates teises sõnast sõnad alustada suure tähega: voiduKombinatsioonid on siin katse seda reeglit järgida.

Massiivid

Ridade var sisu =[] ja voidukombinatsiooni omistamisest rääkimiseks on vaja kõigepealt ütelda, et ülejäänud muutujatüübid on JavaScriptis kõik objektid. Suhteliselt kõige arusaadavamateks objektideks peaksid neist olema massiivid, ingl. k. array - mingi hulk numbreid,tekste,ka väiksemaid massiive, muid objekte, kõik võib sellejuures JavaScriptis olla segamini. Elemente saab kätte massiivi nime ja indeksi abil. Ja nüüd kõige olulisem asi: indeksid algavad nullist! Massiiv võib olla ka tühi. Lause
var sisu = [];
ütleb JavaScriptis seda, et sisu võiks tulevikus hakata sisaldama mingeid elemente. Aga nendele elementidele võib (erinevalt paljudest teistest keeltest) viidata ja omistada neile väärtusi, kartmata massiivi piiridest väljumist. Proovige konsoolis või minu kastides. var sisu = []; ja minu programmikastis järgmise reana logiraamat(sisu[8]);
voiduKombinatsioonid massiivile erinevalt sisust, mis täituvad hiljem x-de ja o-dega, võib kohe väärtused ära omistada. Nurksulgude vahele tuleb kirjutada iga elemendi väärtuse, milleks aga on 3 elemendiline massiiv. Elemendid eraldage komaga. Kui kõik ühele reale ei mahu, pole tähtis, saate lauset jätkata teiselt realt. voiduKombinatsioonid teise elemendi esimese numbri saab kätte nii: voiduKombinatsioonid[1][0] (meenutage seda, et indeksid algavad nulliga. See on vahest see koht, mis peaks viitama sugulusele Java-ga või C-ga.)
2 viimast deklaratsiooni lihtsalt ütlevad, et kaks muutujat k ja kontekst on järgnevates funktsioonides kasutatavad objektid kanvaale joonistamiseks ja et nad oleksid nähtavad mitmes funktsioonis korraga, on nad igaks juhuks siin ära deklareeritud. Funktsiooni sees defineeritud objekte teised funktsioonid, sellesama funktsiooni kõrval defineeritud funktsioonid ei näe, küll on aga need nähtavad sellesama funktsiooni sees defineeritavatele funktsioonidele.
Natuke sarnane naabritevahelisele infovahetusele - sageli on ainsaks infokanaliks kõrvalkorteris toimuvale lukuauk vanemate majatüüpide korral, uuemate korral pole sedagi rõõmu.
Selles selgituses peitubki sõna globaalne tähendus. Funktsioonide sees defineeritud objektid on nähtavad selle funktsiooni sees, s.t. on lokaalsed. Muutuja või objekti nähtavuspiirkonda nimetatakse veel skoobiks

Funktsioonid

  • Uurime nüüd TTT koodi funktsioonide osa. Jätaks kõrvale praegu koodi ja vaatleks seda, milline on funktsiooni tegemise mall. Siin kasutatud malli nimetatakse funktsiooni deklaratsiooniks - function declaration Nagu näete, algab kõik sõnaga function, siis tuleb selle funktsiooni nimi ja sulgudes parameetrid. Ja ülejäänud kood on kahe loogelise sulu vahel. Märgiks ära, et sellise vormi korral ei ole vaja semikoolonit viimase looksulu järel. Seda teen seetõttu, et kohe toon ära teise malli funktsioonide tegemiseks - funktsiooniavaldise (function expression), kus selline asi on väga vajalik. Võite pühendada pikki tunde selle väljaselgitamisele, kumb viis on parem. Lihtsa koodi puhul erilist vahet ei tule. Vaid üks tõesti oluline asi tuleks juba eelnevalt meelde jätta - funktsiooni deklaratsiooni puhul ei ole vaja muretseda koodis selle üle, kui mingit funktsiooni kasutatakse enne, kui ta tekstis on deklareeritud. Funktsiooniavaldiste kasutamisel peab hoolega jälgima, kas see funktsioon väljakutsel üldse on olemas või luuakse kusagil allpool hilisema skripti täitmise käigus. Ka mina siin viitan ju alles tuleva teksti peale, see omadus on vahel elu mugavamaks tegev - panete minu märkuse funktsiooni avaldisest kõrva taha ja siis, kui funktsiooniavaldisest jutt käib, võtate selle sealt jälle välja ja uurite elu edasi.
  • ok, nüüd tuleb lubatud funktsiooniavaldise kirjeldus Tegime valmis kaks MUUTUJAT ja omistasime neile funktsiooni koodi. See on mittefunktsionaalsetes programmeerimise keeltes pea võimatu või vähemasti kõrvaltee, tavaliselt mingite kohmakate trikkidega tehtav. JavaScript on funktsionaalne programmeerimiskeel ja siin on see funktsiooni tegemise põhimeetod. Ka funktsiooni deklareerimise puhul on võimalik funktsiooni koodi omistada muutujale. Milleks see hea on, võidaks küsida? Üks mõeldav näide oleks massiividega manipuleerimine. Olgu vaja valmis teha kahest arvumassiivist kolmas, mis kahe esimese summa. Siis seda tegev funktsioon võiks parameetrina saada funktsiooni, mis liidab kaks arvu ja mõne näpuliigutusega saab sama funktsiooni panna kaht massiivi omavahel korrutama, vahetades parameeterfunktsiooni, mis nüüd peaks korrutama kaks arvu.

Funktsiooni kesVoitis() suur sisu

  • Alustan veidi lihtsamast funktsioonist, sest siin funktsioon ei käi lehekülje kanvaaelementide kallal joonistamas, s.t. ei pea rääkima DOM-st (Document Object Model).
    Kanvaa, canvas tahaks ka eraldi juttu vähemalt mingi väga lihtsa sissejuhatusena.
    Aga kõik, mis klassikalises programmeerimises on välja mõeldud, on siin olemas. Jah, lugesite õieti, enam-vähem kõik, tsükkel ja if - else tingimus ... ja nii pandi programmeerimist aastakümneid. Ja endiselt pannakse suures osas edasi, sest vana head tööriista on kindel kasutada, kõik head ja vead läbi proovitud.
  • Tsükkel ehk loop inglise keeles on progemise alustala. Ilma tsükliteta ei saa programmeerimist ette kujutada. Isegi kui teoreetikud on suutnud seda asendada millegi muuga, peab protsessor selle taandama ikkagi tsükliks, lihtsurelike jaoks peidetuna.
    Kõige lihtsam tsükkel tuleb ette siis, kui midagi on vaja teha N korda. Siin näemegi sellist juhtu - massiiv voiduKombinatsioonid tuleb järjest läbi vaadata, iga elemendi korral kontrollides, kas on kolm x-i või 0-i reas. Tsüklite kirjapanekuks on moodsatel programmeerimiskeeltel 3 klassikalist erinevat võimalust: for, while ja do while . JavaScriptis on nad VÄIKESTE tähtedega võtmesõnad, mõnes muus keeles asjad veidi varieeruvad. for toortõlge annab for lause mõtte siiski edasi - teatud muutuja väärtuste jaoks (n korda kordamisel tavaliselt i=1...,n, või i=0....,(n-1), see on javascripti traditsioon) teha mingeid asju
    FOR lause põhikuju:
    Selles funktsioonis algomistus a=0 (esimene indeks javascriptis) Tingimuslause on mingi avaldis, mis peab lõpptulemuseks andma kas true või false, praegu siis väga lihtsal kujul - a < massiivi pikkusest
    muutmislause on tavaliselt tsüklimuutuja ühe võrra suurendamine. a++ on sama, mis a = a + 1
    Märkus ++ kohta
    Traditsioon "++" märgi osas pärineb C keelest. Douglas Crockfordi arvates tuleb sellisest ühe juurdeliitmisest loobuda igal juhul, kuna btw, seda saab teha koguni kahel erineval viisil, nagu ka ühe mahavõtmist (--a;a--,a++;++a;) Isiklikult soovitan kasutada vaid ++ või -- märke for tsüklites või eraldi rea peal eraldi lausena, ja alati muutuja taga, mitte ees.
    Kui te lähete aga JavaScript eksamit tegema, on väga huvitav küsimus näiteks see, millega lõpeb rida a = a++ + ++a ....irw, proovige mdx minu logiraamatust järgi uurida
    Praegu tegeleks aga veel kahe klassikalise tsüklivormiga, kõik teada juba aastast 1960, mil avaldati kõikide tänapäevaste keelte vaarema ALGOL60 kirjeldus.
    while tsükli üldkuju Nagu siit näha võib, on kõik sisuliselt väikeste ümberpaigutustega sama, algomistused tuleb teha enne while algust, lõppu panna näiteks a++ meie näites. Millist tsüklivormi kasutada, on sageli maitse küsimus, while tsüklit kasutatakse sageli siis, kui olukord on keerukam, ei saa ette ennustada, millal tsükkel otsa saab. Meie funktsiooni näide transformeeruks selliseks: do while tsükli üldkuju Mõnikord on nii kasulik teha, kui on ette teada, et tsükkel vähemalt üks kord läbitakse, s.t. kontrollida tingimust juba järgmise tsükli algul.
    Tsüklist väljumine ja tsükli algusse paiskumine
    Ka arvutiga võib juhtuda nii, et tsüklist ei saadagi välja. Üldiselt on see üsna kole ja tüütav lugu. Selliseid kroonilisi tsükleid on üsna raske katkestada - parimal juhul õnnestub natuke nupukamal kasutajal see protsess kuidagi mõistlikult ära lõpetada, halvimal juhul aitab vaid arvuti eemaldamine toitejuhtmest, lootes, et ehk ei lähe kõvaketta vahetuseks ...
    Sellest hoolimata kirjutavad programmeerijad endiselt enesetapjalikke tsükleid algustega for(;;){kood} !! ei ole mingeid lauseid, kõik on täiesti korrektne! või while(true) { kood siin } või do {kood} while(true); Õnneks on arvutimaailmaski olemas oma doktor Mumma: lause break;. Õigesse kohta paigutatuna aitab see tsüklist välja, selle ette võiks panna muidugi tingimuse kontrolli if(tingimuslause), selleni kohe jõuame. Lause continue; paiskab seevastu usina arvunärilise tsükli algusse tagasi, seda on ka vahel vaja. Toimivad need laused iga tsükli sees.
  • Kui ... siis ehk if...else konstruktsioonid

Kuidas tingimuslauseid arvutada ?

Et programm saaks sooritada oma valiku, on tingimuslause tulemiks vaja saada kas true või false. See ei tundu üle mõistuse keeruline nõudmine, näiteks kontrollida, kas a<8 ,nii palju neid võidukombinatsioone ju oli.
Arve saab võrrelda kergesti, nad kas
  • on võrdsed, "==" operaatori abil küsitav,
  • ei ole võrdsed "!=" operaatori abil selgeks tehtav,
  • esimene on suurem teisest, ">" operaator
  • esimene on suurem või võrdne teisest, ">=" operaator
  • esimene on väiksem teisest, "<" operaator
  • esimene on väiksem või võrdne teisest, "<=" operaator

  • Täpselt samamoodi saame võrrelda tekste, kasutades tähestikulist järjestamist, suured tähed on ees, väiksed järel.
  • Loogilisi väärtusi väga võrrelda enam ei tasu, kuigi siin on ka asjad enam vähem selged, tõde võidab (true) ja vale vaob (false).
  • Objekte ei tasu aga iial võrrelda, ärge nähke vaeva ka spetsifikatsioonide lugemisega. (massiivid näiteks). Vaid siis saadakse võrdsus, kui objekt, mis peitub var a all, omistatakse otse var b-le: b = a; Selle kohta ütlevad targad, et kui viited objektile on samad, siis ollakse võrdsed. Sisu muidugi on ka sama, aga lihtsalt sisu samasus ei tähenda midagi. Probleem võib aga tulla sellest, et need soovitused JavaScripti jaoks ei tähenda midagi. Täiesti mõttetu jura võrdlemisega saadakse kenasti hakkama. Võrdleme näiteks NaN -i ja undefined minu programmikasti abiga - logiraamat(NaN < undefined);
    Siin vähemalt saame alati false, mis võrdlust ka ei kasuta. Segane lugu on aga siis, kui võrreldavate väärtuste tüübid ei ühti, näiteks logiraamat("5">4);, mis ütleb true, aga logiraamat("5">45);, mis ütleb false. Kui võtta nii, et vasak pool teisendatakse arvuks, on asi loogiline, aga miks mitte teha vastupidi? Mida tahtis skripti kirjutaja siin teha? Äkki annaks mingi veateate, näiteks võrdlusele võiks ka saada väärtuse "undefined". Veel võimalikke jaburusi: logiraamat([]<{}) annab true. See ei ütle, et JavaScriptile meeldivad loogelised sulud rohkem, üks objekt on tühi massiiv ja teine "tühi objekt" ja neid üritatakse mingil veidral viisil võrrelda...
    Tegelikult on keele loojate kavatsus olnud vist selline - see asi on nüüd täiesti programmeerija vastutada, meie siin vigu ei genereeri. Põhjus sellele oli aga sirvikud, mis kergesti jooksid kinni ja ka vigased HTML lehed ja seetõttu, isegi kui programm genereeris jaburusi, ei jooksutatud vägisi midagi kinni. Las olla loogelised sulud kõvemad kui kandilised.... Ainult üks leevendus sellele siiski tekkis - kolmekordsed võrdusmärgid võrdlemiseks! KASUTAGE operaatorit "===" "==" asemel!
    Selline võrdlus annab õige tulemi vaid siis, kui mingeid tüübiteisendusi vahel ei ole, arvud või tekstid peavad olema täpselt võrdsed. Mujal peab need vead, kus võrreldavate muutujate tüübid ei klapi, ise üles leidma.
    Kui aga täpselt vastupidist küsite, kasutage "!==" operaatorit (mis on "===" lihtne eitus). Näen kohe, et ka minu koodis on "==" võrldus sees, aga siin tasuks muud asja ka muuta, ei hakka seda ümber tegema.

Loogika maagika

George Boole'ist

















ei ole kuhugi pääsu - if lauses kohtab "&&" märki, mis tähendab AND operatsiooni kahe loogilise avaldise vahel. Tõesuseks peavad mõlemad avaldised TRUE olema. Kui avaldisi saab rohkem (siin 3), siis kõik avaldised olgu true
Loogiline OR
"||" (Alt Gr ja vasaku shift klahvi kõrvalklahv) tähistab OR operatsiooni. (või). Piisab, kui üks väide / avaldis on õige või true.
Ma arvan, et nüüd on selle funktsiooniga enam-vähem selge, mida see if tingimus ütles - kõigis 3 võidukombunatsiooni ruudus peab olema sama sümbol, s.t. 3 risti või 3 nulli.
EITUSE EITUSE SEADUS
Kuna üritan siiski hädavajaliku ära seletada, siis ei pääse veel ühest operaatorist üle - see on EITUS. Seda tähistab hüüumärk. Tahate mingit loogilist avaldist eitada, siis pange kõigele sulud ümber ja hüüumärk ette. Tahate aga lihtsalt teisendada mitteloogilist väärtust tema loogiliseks ekvivalendiks, siis pange kõigele ette kaks hüüumärki!
Näiteks: !!"Toomas" annab true - meeldiv üllatus JavaScriptilt.
Viisakamad programmeerijad teevad niimoodi:
Boolean("Toomas"); - jälle true. Tore!
Mina juba Lorentsi eksamil ei põru!
Kuidas arvutada JavaScriptis?
Kuidas siiski teha tavalisi arvutusi, jääb kiuslik küsimus? "*","+","-" on väga tavalised nähtused, selgitada jääb vaid "%". Operaator tähistab jäägi arvutamist. 3%2===1; s.t. 3 on paaritu arv.

Lehekülje restart Viimane lause, mis funktsioonis kesVoitis() veel uurimist väärt on, on antud leheküljele samaväärne RESTART käsuga.
location.reload(true); asemel peaks mängu taaskäivitamiseks kindlasti välja mõtlema midagi muud, aga hakatuseks käib seegi. Ka mõnede igivanade mängudega oli umbes samamoodi, et tuli kogu asi uuesti käivitada.

Sissejuhatus kanvaade teooriasse

Asume uurima funktsiooni kanvaaKlikk(). Siin ei pääse kahest seninini pea tundmatust tegelasest HTML draamas: kanvaa-st ning DOM-st. Alguseks vaatleme kahte esimest rida kanvaaKlikk() funktsioonist.
Esimene rida selles saagas kasutab ühte põhilist funktsiooni, mis võimaldab sirvikul käigus oleva HTML leheküljega üldse midagi teha - getElementById(id) Kui olete oma HTML leheküljel loonud mingi kindla id-ga elemendi, saab muutujale anda viite sellele elemendile, mis sisuliselt tähendabki, et muutuja kaudu saab saab seda objekti või elementi igatpidi muuta, koguni kustutada.
Uusi elemente saab ka juurde teha, selleni jõuame järgmises TTT variandis. Siin aga tahame aru saada elemendist kanvaa ja selleks peab muutuja k saama selle kanvaa kohta viite.
Käsk kontekst = k.getContext("2d"); ütleb, et tegeleme 2-mõõtmelise joonestamisega. Mõned kontekstid ("webgl" näiteks) peaksid võimaldama ka 3 mõõtmelist joonestamist, aga need ei ole veel igal pool toetatud. kontekst on selle käsu järgselt see muutuja, mille abiga saab kanvaa peal kõiki olulisi asju teha, välja arvatud kanvaa sisu kustutamine, milleks on tõtt öelda veider käsk k.width = k.width; põhjendusega, et niipea, kui me laiuse uuesti üle ütleme, siis see tähendab ka vana sisu kustutamist.
Aga tegeleks siis kanvaale joonestamisega.
Kõigepealt tegin allpool (esialgne variant, ma ehk täiustan seda ajapikku) valmis kanvaale joonistamise vahendi, all on 2 kasti - kanvaa, id="louend", laiusega ja kõrgusega "250px", ning textarea "kanvaaprogramm", mille abiga saab kanvaale joonistada. Tüütu alustus
kanvaa=document.getElementById("louend");
ning
; kontekst=kanvaa.getContext("2d");
on teie jaoks juba ette ära tehtud ja lõuendi puhastamine käib ka automaatselt.
"kanvaaprogramm" elemendi sisse on hakatuseks kopeeritud jupike funktsioonist kanvaaKlikk(), nimelt see osa, mis joonistab suure 0-i.
0 on pisut suurem, sellele kanvaale vastav. Teie ülesandeks on pärast tutvumist kanvaa-le joonistamise võimalustega sinna ise midagi joonestada.

Kanvaa nimega louend

Siin peaks olema kanvaa, kui seda siin ei ole, on teie sirvik pärit Noa aegadest!

Kanvaaprogramm

Kanvaaraja märkimine

Pärast kanvaa avamist ja mingile muutujale, ütleme, et kontekst, getContext("2d") meetodiga konteksti omistamist saab kanvaale joonistada mitmesuguseid jooni.
Et lõpuks TTT mängu variant I-ga ikkagi ühele poole saada, käsitleme siin vaid kanvaaraja märkimist ja seejärel joonistamist / täitmist. Tundub, et see teema, HTML5 graafika üldisemalt, vajaks põhjalikumat käsitlemist ja ka eestikeelseid juhendeid väga ei leidnud, nii et JavaScript mängude projekti edasiedenemisel tuleks sellest teha omaette lugu. Seevastu ingliskeelses maailmas on põnevat juhendmaterjali, mis ei tundu selle kõige juures üldsegi olevat raketiteadus.
Raja alustus: beginPath()
Joonistamise rada alustab alati beginPath(). See initsialiseerib teatud loendi parajasti käsilolevatest joonestuselementidest tühjaks objektiks, s.t. eelmine rada lõpetatakse ära. Umbes nii ma seda käsku praegu mõistan, s.h. olen seda ka kusagilt lugenud. Kommenteerigu mõni asjatundjam, kui oskab. Just seetõttu peaks (tõenäoliselt) funktsioonidesse peidetud kujundijoonestuste puhul mitte eeldama, et see element või kujund on esimene (siis ei ole vaja initsialiseerida) ja toimingut tuimalt alustama kontekst.beginPath(); käsuga.
Ülestõstetud pliiatsiga liikumise märkimine: moveTo(x,y)
Pärast raja alustust on järgmine käsk KINDLASTI moveTo(x,y) oma mõeldava joonistuse algusesse.
Seda võib kujutleda liikumisena, kus pliiats on lõuendilt tõstetud üles. Jäi märkimata, et koordinaatsüsteemi algus on VASAKUS ÜLEMISES NURGAS ja loogiliselt ainuvõimaliku järeldusena x suund on endiselt paremale, y telg aga näitab maakera keskpunkti suunas.... Ka raja edasisel joonistamisel võib nii palju, kui meeldib, kasutada moveTo() käsklusi.
Pliiatsiga joonistatava sirgjoone märkimine: lineTo(x,y)
See käsk joonistab märgib sellest kohast, kus parajasti ollakse, TULEVASE joone koordinaadini (x,y).
Kõikide märgitud joonte tegelik joonistamine: stroke()
Tegelik joonistamine käib siin, seejuures ei pea olema vaid sirgjooned, me ei tegele siin lähemalt Bezier joontega näiteks, üheks kahe punkti vaheliseks jooneks võib olla ka kaar.
Märgitud joontest moodustatud kujundi täitmine: fill()
Märgitud kujundi võib ka täita mingi soovitud värviga, vaikimisi on see must. Sellejuures teeb arvuti sellise operatsiooni: läheb tagasi alguspunkti, s.t. beginPath() järgse moveTo() koordinaadini ning joonistab sinna pideva joone. Seejärel üritab ta tekkinud kinniseid piirkondi värviga täita.
Märgitud raja sulgemine: closePath()
closePath() on vajalik, kui tehakse joonistamise operatsioon stroke(), fill() operatsiooni puhul üritatakse seda teha automaatselt.
closePath() EI ASENDA vajadust järgmist raja märkimist alustada beginPath() käsuga.
Kaarte, s.h. ringjoonte märkimine:
ctx.arc(x, y, raadius, algusnurk, lõppnurk, kas vastupäeva)

Kui nurk on 2*Math.PI, märgitakse maha ringjoon. Edasi võib siis kas joonistada märgitud ringjooni ja kaari, või neid ka täita, siis kaar suletakse automaatselt. Näiteks kui nurga suuruseks on Math.PI, siis saame joonistada poolringjoone.
Siin ma praegu peatun, sest nendest selgitusist õnneks on küllalt, et selgitada funktsiooni kanvaaKlikk() käitumist. Lühimärkusena selle pika teekonna lõpus leidsin vaid 2 äraseletamata rida selles funktsioonis. Need on:
if(! sisu[kanvaaNumber - 1]) kontrollib, kas sellesse massiivi elementi üldse midagi on salvestatud. Kui keegi on siia käigu teinud, peab seal olema kas X või 0, või on selle sisu undefined. !undefined annab aga JavaScripti reeglite põhiselt vastuseks true Järgmises versioonis II teen ehk selle lause viisakamaks, selliseks, nagu PEAB OLEMA, siin ehk on selline lohakus isegi kasuks, et selline asi sisse lipsas - seda siiski kasutatakse üsna tihti. if(kaik%2===0) küsib, kas käik on paarisarv. Kui on, siis tuleb joonistada ring, kasutades arc funktsiooni. Kui aga paaritu, joonistatagu X.

Lõpukooda

Selle versiooni kommenteerimise lõpuks on mul kujunenud kindel veendumus, et JavaScript-i õppimine ei ole raketiteadus. Sellest hoolimata ei ole pääsu arvuti taga veedetud tagumikutundidest, punnitage kuidas tahate. See, mis jäi täna lugemata - uurimata, maksab kätte homme mingi vastiku puugi näol.
Konkreetne näide minu puhul - jätsin ühe muutuja nimega sisu oma skriptides kogemata deklareerimata var käsuga ja tekkis vastik globaalne muutuja. See oli aga globaalne ka TTT mängus. Tulemina ühel hetkel, kui pusisin oma programmikasti ja logikastiga, TTT keeldus toimimast. Kasutasin sama muutujanime kahes kohas, aga minu blogilehel olid nad ninapidi koos ...
Järgmiseks eesmärgiks TTT koodis võiks olla sellis malli loomine, mille põhjal oleks võimalik kirjutada näiteks mänge ala "Viis risti ritta" etc...