Përmbajtje:

Rivaliteti i Rrjetit: një lojë me vonesë të ulët për BBC Micro: bit: 10 hapa (me fotografi)
Rivaliteti i Rrjetit: një lojë me vonesë të ulët për BBC Micro: bit: 10 hapa (me fotografi)

Video: Rivaliteti i Rrjetit: një lojë me vonesë të ulët për BBC Micro: bit: 10 hapa (me fotografi)

Video: Rivaliteti i Rrjetit: një lojë me vonesë të ulët për BBC Micro: bit: 10 hapa (me fotografi)
Video: Elon Musk: A future worth getting excited about | Tesla Texas Gigafactory interview | TED 2024, Korrik
Anonim
Rivaliteti i Rrjetit: një lojë me vonesë të ulët për BBC Micro: bit
Rivaliteti i Rrjetit: një lojë me vonesë të ulët për BBC Micro: bit
Rivaliteti i Rrjetit: një lojë me vonesë të ulët për BBC Micro: bit
Rivaliteti i Rrjetit: një lojë me vonesë të ulët për BBC Micro: bit

Në këtë tutorial, unë do të shpjegoj se si të zbatoni një lojë bazë multiplayer në mikro BBC: bit me karakteristikat e mëposhtme:

  • Një ndërfaqe e thjeshtë
  • Vonesë e ulët midis shtypjeve të butonave dhe përditësimeve të ekranit
  • Një numër fleksibël pjesëmarrësish
  • Kontroll i lehtë mbi lojën duke përdorur një pajisje kryesore të telekomandës ("rrënjë")

Loja është në thelb një simulim i politikës. Të gjithë lojtarët fillojnë të pacaktuar për çdo ekip, përveç dy lojtarëve. Njëri nga këta lojtarë është caktuar në Ekipin A, dhe tjetri është caktuar në Ekipin B.

Objektivi i lojës që secili lojtar të jetë në ekip me shumicën e lojtarëve në kohën kur të gjithë janë konvertuar.

Diagrami i mësipërm ilustron një makinë me gjendje të fundme, domethënë një specifikim të gjendjeve në të cilat mund të jetë pajisja dhe kalimet midis atyre gjendjeve.

Një gjendje mund të mendohet si grupi aktual i të dhënave që përshkruan kujtesën e pajisjes që kur është ndezur. Bazuar në ato të dhëna, pajisja mund të kryejë veprime të caktuara ose të reagojë ndryshe ndaj hyrjes së përdoruesit.

Një kalim është një gjendje logjike që, kur është e vërtetë, bën që pajisja të ndryshojë gjendjen e saj. Një kalim mund të jetë nga një gjendje në çdo gjendje tjetër. Një shtet mund të ketë kalime të shumta.

Diagrami i mësipërm specifikon gjendjet e mëposhtme:

  • E pacaktuar
  • Dëgjoni për A
  • Dëgjoni për B.
  • Ekipi A
  • Ekipi B

Një pajisje që ekzekuton kodin e lojës mund të jetë në secilën nga këto pesë gjendje, por vetëm një në një kohë, dhe vetëm këto pesë.

Unë do të supozoj gjatë gjithë udhëzuesit se po përdorni redaktorin MakeCode të Microsoft, i cili mund të gjendet në:

Zbatimin e plotë të lojës mund ta gjeni këtu:

makecode.microbit.org/_CvRMtheLbRR3 ("microbit-demo-user" është emri i projektit)

Dhe zbatimi i kontrolluesit të rrjetit master ("rrënjë") mund të gjendet këtu:

makecode.microbit.org/_1kKE6TRc9TgE ("microbit-demo-root" është emri i projektit)

Unë do t'i referohem këtyre shembujve gjatë gjithë mësimit tim.

Hapi 1: Konsiderata të Dizajnit të Fotografisë së Madhe

Para se të shkruajmë ndonjë kod, duhet të mendojmë se si duam të duket produkti ynë përfundimtar. me fjalë të tjera, cilat janë kërkesat e aplikacionit? Çfarë duhet t'i thotë kodi ynë pajisjes të bëjë kur të përfundojë? Unë e kam ndarë funksionalitetin e aplikacionit kryesor në gjashtë kategori, secila prej të cilave mund të konsiderohet nga një perspektivë e ndryshme e projektimit.

  1. Ne duam të kontrollojmë veprimet e pajisjes bazuar në gjendjen e saj aktuale
  2. Ne duam që pajisja të reagojë ndaj hyrjes së përdoruesit
  3. Ne mund të duam të shfaqim animacione dhe grafika duke përdorur ekranin LED 5 x 5
  4. Ne duam të fillojmë vlerat e të dhënave në kujtesën e pajisjeve kur pajisja të ngrihet
  5. Ne duam të transmetojmë të dhëna pa tel duke përdorur radion e pajisjes
  6. Ne duam të dëgjojmë dhe të marrim të dhëna përmes radios së pajisjes dhe t'i përpunojmë ato në përputhje me rrethanat

Më lejoni të hyj pak më shumë në detaje për secilën prej tyre.

1. Ne duam të kontrollojmë veprimet e pajisjes bazuar në gjendjen e saj aktuale

Ashtu si shumica e programeve të tjera, ekzekutimi i udhëzimeve të përcaktuara nga kodi ndodh një rresht në të njëjtën kohë. Ne duam që pajisja jonë të ekzekutojë udhëzime të caktuara bazuar në gjendjen e saj të brendshme, siç ilustrohet nga diagrami në krye të këtij mësimi. Ne mund të shkruajmë një seri kushtesh pas çdo blloku të kodit që kontrollon pajisjen, por kjo qasje mund të bëhet shumë e çrregullt shumë shpejt, kështu që ne do të përdorim një lak të pafund që thjesht kontrollon një ndryshore, dhe bazuar në atë ndryshore, ekzekuton një grup të caktuar udhëzimesh ose nuk bën asgjë fare. Ky variabël do të identifikohet me prapashtesën "_state" si në aplikacionin tonë të përdoruesit ashtu edhe në aplikacionin tonë rrënjësor.

2. Ne duam që pajisja të reagojë ndaj hyrjes së përdoruesit

Pavarësisht ekzekutimit normal të kodit që ndodh në mënyrë sekuenciale, domethënë një rresht në të njëjtën kohë, ne kemi nevojë që pajisja jonë të reagojë ndaj shtypjeve të butonave, ndërsa laku kryesor i gjendjes përcakton se çfarë duhet të bëjë pajisja në çdo moment të caktuar. Për këtë qëllim, pajisja ka aftësinë për të dërguar sinjale në softuerin e nivelit më të ulët që ndërvepron me harduerin, duke shkaktuar atë që quhet ngjarje. Ne mund të shkruajmë kod që i thotë pajisjes të bëjë diçka kur zbulon një lloj specifik të ngjarjes.

3. Ne duam të shfaqim animacione dhe grafika duke përdorur ekranin LED 5 x 5

Mekanizmi për ta bërë këtë duket të jetë i thjeshtë, por blloku që shfaq një imazh shton një vonesë të fshehur prej 400 ms. Për shkak se ne duam që pajisja jonë të vazhdojë të ekzekutojë lakin e saj të gjendjes me sa më pak vonesë të jetë e mundur, do të na duhet të redaktojmë kodin javascript për të minimizuar vonesën.

4. Ne duam të fillojmë vlerat e të dhënave në kujtesën e pajisjeve kur pajisja fillon

Para se pajisja jonë të bëjë diçka, aplikacioni duhet të ngarkojë të dhënat e tij në memorie. Kjo përfshin ndryshore konstante të emërtuara për lexueshmërinë e kodit, variablat që përmbajnë imazhe, të cilat mund të jenë pjesë e një animacioni, dhe ndryshoret kundër që duhet të fillojnë nga 0 për të punuar siç duhet. Ne do të përfundojmë me një listë të gjatë të emrave të ndryshoreve dhe vlerave të tyre të caktuara rishtazi. Si një zgjedhje e stilit personal, unë do të shënoj vlera konstante, domethënë vlera që nuk do të kem nevojë t'i ndryshoj kurrë, duke përdorur ALL_CAPS. Unë gjithashtu do të parashtroj identifikuesit kryesorë të ndryshoreve me një emër të kategorisë që i referohet një lloj objekti ose lloji nën të cilin identifikuesi bie. Kjo është në përpjekje për ta bërë kodin më të lehtë për t’u ndjekur. Unë kurrë nuk do të përdor një emër të ndryshueshëm si "artikull" ose "x" për shkak të paqartësisë që lind kur përpiqem të deshifroj kodin.

5. Ne duam të transmetojmë të dhëna pa tel duke përdorur radion e pajisjes

Kjo është në të vërtetë një detyrë mjaft e thjeshtë kur përdorni gjuhën e blloqeve MakeCode. Ne thjesht i vendosim të gjitha pajisjet në të njëjtin grup radio në kohën e nisjes dhe pastaj kur duam të dërgojmë një sinjal, mund të kalojmë një numër të vetëm në bllokun "Numri i dërgimit të radios" që na është dhënë. Shtë e rëndësishme që dërguesi dhe marrësi të punojnë në të njëjtin grup radio, sepse nëse jo, ata do të dërgojnë ose marrin në frekuenca të ndryshme, dhe komunikimi do të jetë i pasuksesshëm.

6. Ne duam të dëgjojmë dhe të marrim të dhëna përmes radios së pajisjes dhe t'i përpunojmë ato në përputhje me rrethanat

Duke pasur parasysh të njëjtat konsiderata si artikulli i mëparshëm, ne do të dëgjojmë për transmetimet në hyrje në të njëjtën mënyrë si do të dëgjojmë për të dhënat e përdoruesit: me një mbajtës të ngjarjeve. Ne do të shkruajmë një bllok kodi që do të ekzaminojë çdo sinjal në hyrje dhe do të kontrollojë nëse do të ndërmerret ndonjë veprim pa prishur lakin kryesor të gjendjes.

Përveç kësaj, ne duhet të konsiderojmë shkurtimisht hartimin e aplikacionit rrënjë shumë më të thjeshtë, një program që do të lejojë një pajisje të kontrollojë të gjithë rrjetin. Unë nuk do të shpenzoj shumë kohë për këtë pasi është shumë më e thjeshtë se modeli i mësipërm dhe shumë prej tij është thjesht përsëritje. Unë e kam ndarë funksionalitetin e rrënjës në tre kategori.

  1. Ne duam të jemi në gjendje të zgjedhim një sinjal
  2. Ne duam të jemi në gjendje të transmetojmë një sinjal

--

1. Ne duam të jemi në gjendje të zgjedhim një sinjal

Kjo mund të bëhet thjesht duke pasur një buton që përsëritet përmes sinjaleve të mundshme. Meqenëse janë vetëm tre, kjo qasje do të jetë e mjaftueshme. Në të njëjtën kohë, ne mund të kemi një lak që rishfaq vazhdimisht sinjalin e zgjedhur, duke i lejuar përdoruesit të shtypë një buton dhe të shohë që sinjali i zgjedhur të shfaqet në ekranin LED me shumë pak vonesë.

2. Ne duam të jemi në gjendje të transmetojmë një sinjal

Meqenëse ka dy butona, ne mund të caktojmë njërën për përzgjedhje dhe tjetrën për konfirmim. Ashtu si aplikacioni i përdoruesit, ne thjesht dërgojmë sinjal mbi rrjetin si një numër. Nuk kërkohet asnjë informacion tjetër.

Unë do të flas më shumë për protokollin e thjeshtë të sinjalit në pjesën tjetër.

Hapi 2: Protokolli i Sinjalit: një gjuhë e thjeshtë për komunikimin në rrjet

Sinjalet e mëposhtme mund të mendohen si tërësia e të gjitha fjalëve të mundshme që pajisjet mund të përdorin për të folur me njëri -tjetrin. Për shkak se rrjeti është kaq i thjeshtë, nuk ka shumë për të thënë, dhe kështu ne mund t'i përfaqësojmë këto tre sinjale me vlera të thjeshta të numrave të plotë.

0. Rivendos

  • Identifikuesi në kodin: SIG-R
  • Vlera e plotë: 0
  • Qëllimi: Thuajini të gjitha pajisjeve brenda rrezes që të heqin dorë nga ajo që po bëjnë dhe të veprojnë sikur të jenë vetëm të ngarkuara. Nëse ky sinjal arrin çdo pajisje në rrjet, i gjithë rrjeti do të rivendoset dhe përdoruesit mund të fillojnë një lojë të re. Ky sinjal mund të transmetohet vetëm nga një pajisje rrënjë.

1. Konvertimi A

  • Identifikuesi në kod: SIG-A
  • Vlera e plotë: 1
  • Qëllimi: Thuaji çdo pajisjeje që është në gjendjen LISTEN_A, sapo të marrë sinjalin e konvertimit, të kalojë në gjendjen TEAM_A.

2. Konvertimi B

  1. Identifikuesi në kodin: SIG-B
  2. Vlera e plotë: 2
  3. Qëllimi: Thuaji çdo pajisjeje që është në gjendjen LISTEN_B, sapo të marrë sinjalin e konvertimit, të kalojë në gjendjen TEAM_B.

Hapi 3: Ne duam të kontrollojmë veprimet e pajisjes bazuar në gjendjen e saj aktuale

Ne duam të kontrollojmë veprimet e pajisjes bazuar në gjendjen e saj aktuale
Ne duam të kontrollojmë veprimet e pajisjes bazuar në gjendjen e saj aktuale
Ne duam të kontrollojmë veprimet e pajisjes bazuar në gjendjen e saj aktuale
Ne duam të kontrollojmë veprimet e pajisjes bazuar në gjendjen e saj aktuale
Ne duam të kontrollojmë veprimet e pajisjes bazuar në gjendjen e saj aktuale
Ne duam të kontrollojmë veprimet e pajisjes bazuar në gjendjen e saj aktuale

Më në fund, ne mund të fillojmë të shkruajmë kod.

Së pari, hapni një projekt të ri në Make Code

  • Krijoni një funksion të ri. Unë e thirra lakun tim sepse ky është laku kryesor i aplikacionit
  • Shtoni një bllok loop që do të përsëritet pafundësisht. Kam përdorur ndërsa (e vërtetë) sepse një e vërtetë fjalë për fjalë nuk do të jetë kurrë e rreme, prandaj rrjedha e kontrollit të aplikacionit nuk do të dalë kurrë nga laku
  • Shtoni mjaft blloqe if-else për të kontrolluar nëse pajisja është në ndonjë nga pesë gjendjet e saj të mundshme
  • Krijoni një ndryshore për të mbajtur gjendjen aktuale të pajisjes
  • Krijoni variabla për të përfaqësuar secilën nga pesë gjendjet e mundshme

    Shënim: OKshtë në rregull që këto variabla të mos kenë ende ndonjë vlerë të caktuar. Ne do të arrijmë në atë. Në këtë pikë, është më e rëndësishme që të shkruajmë kod të pastër dhe të lexueshëm

  • Ndryshoni çdo kusht në blloqet if-else për të krahasuar gjendjen aktuale me një nga gjendjet e mundshme
  • Në fund të blloqeve if-else, shtoni një pauzë për disa milisekonda dhe krijoni një ndryshore për ta mbajtur atë numër. Ne do ta fillojmë atë më vonë. Sigurohuni që variabla të ketë një emër përshkrues, siç është shënimi ose rrahjet e zemrës. Meqenëse ky është laku kryesor i pajisjes, kjo pauzë do të përcaktojë shpejtësinë me të cilën pajisja ekzekuton lakun kryesor, kështu që është një vlerë shumë e rëndësishme dhe është shumë e rëndësishme për të qenë një numër magjik pa emër.

Shënim: Mos u shqetësoni për blloqet gri në imazhin e tretë. Do të shkoj tek ato më vonë.

Hapi 4: Ne duam të reagojmë ndaj hyrjes së përdoruesit

Ne duam të reagojmë ndaj hyrjes së përdoruesit
Ne duam të reagojmë ndaj hyrjes së përdoruesit
Ne duam të reagojmë ndaj hyrjes së përdoruesit
Ne duam të reagojmë ndaj hyrjes së përdoruesit

Tani, ne duam t'i tregojmë pajisjes se si të trajtojë shtypjet e butonave. Mendimi i parë i dikujt mund të jetë thjesht përdorimi i blloqeve "Kur shtypet butoni" në kategorinë e hyrjes, por ne do të donim kontroll më të imët se kaq. Ne do të përdorim bllokun "në ngjarje nga (X) me vlerë (Y)" nga kategoria e kontrollit nën seksionin e avancuar, sepse ne jemi të avancuar në këtë tutorial.

  • Krijoni katër blloqe "në ngjarje nga …".

    • Dy nga këto duhet të kontrollojnë burimin e ngjarjes "MICROBIT_ID_BUTTON_A"
    • Dy nga këto duhet të kontrollojnë burimin e ngjarjes "MICROBIT_ID_BUTTON_B"
    • Nga dy ngjarjet që synojnë secilën buton:

      • Duhet kontrolluar për ngjarjen e llojit "MICROBIT_BUTTON_EVT_UP"
      • Duhet kontrolluar për ngjarjen e llojit "MICROBIT_BUTTON_EVT_DOWN"
    • Shënim: Këto opsione me të gjitha shkronjat e mëdha janë etiketa që përdoren në kodin mikro: bit të nivelit më të ulët. Ata janë thjesht mbajtës vendesh që më vonë zëvendësohen me numra të plotë kur kodi përpilohet në një binar të ekzekutueshëm. Humansshtë më e lehtë për njerëzit që të përdorin këto etiketa sesa të shikojnë se cilin numër të plotë të vendosin, edhe pse të dy do të funksiononin në të njëjtën mënyrë.
  • Zgjodha, si çështje stili, që secila të thërrasë bllokun "në ngjarje nga …" një funksion që përshkruan ngjarjen e ngritur. Ndërsa nuk është rreptësisht e nevojshme, për mendimin tim kjo përmirëson lexueshmërinë. Nëse dikush dëshiron ta bëjë këtë, ata mund të vendosin kodin e trajtimit të ngjarjeve brenda vetë bllokut "në ngjarje nga …".

    Shënim: Blloku i kodit që trajton përgjigjen e pajisjes ndaj një ngjarjeje quhet në mënyrë intuitive një "mbajtës ngjarjesh"

  • Shtoni, në secilin mbajtës të ngjarjeve, të njëjtën strukturë nëse tjetër përdoret për të ndarë rrjedhën e kontrollit bazuar në gjendjen e pajisjes si struktura në lakin e gjendjes kryesore.
  • Shtoni blloqe të caktimit që modifikojnë atë gjendje të pajisjes siç përcaktohet nga diagrami ynë i gjendjes

    • Ne e dimë që kur pajisja është në gjendje E PADASURUAR, pajisja duhet të reagojë ndaj butonit A të shtypur nga një kalim në gjendjen LISTEN_A, dhe butonit B të shtypur nga një kalim në gjendjen LISTEN_B
    • Ne gjithashtu e dimë se kur pajisja është në gjendjen LISTEN_A ose LISTEN_B, pajisja duhet të reagojë ndaj butonit A të lëshuar dhe butonit B të lëshuar, përkatësisht, duke kaluar përsëri në gjendjen E PADASURUAR.
    • Së fundi, ne e dimë se kur pajisja është në gjendje TEAM_A ose TEAM_B, pajisja duhet të reagojë ndaj butonit A të shtypur dhe butonit B të shtypur duke transmetuar SIG_A dhe duke transmetuar SIG_B respektivisht.

      Në këtë pikë nuk është e nevojshme të plotësoni detajet e sinjaleve të transmetimit. Ne do të arrijmë tek kjo më vonë. Ajo që është e rëndësishme është që ne të udhëzojmë këto funksione të përdorin kodin që do të shkruajmë duke i dhënë atij blloku të veprimeve një emër, si transmetimiSignalSIG_A, i cili përshkruan se çfarë duhet bërë në atë pikë

Hapi 5: Ne duam të fillojmë vlerat e të dhënave në kujtesën e pajisjeve kur pajisja të fillojë

Ne duam të fillojmë vlerat e të dhënave në kujtesën e pajisjeve kur pajisja të fillojë
Ne duam të fillojmë vlerat e të dhënave në kujtesën e pajisjeve kur pajisja të fillojë
Ne duam të fillojmë vlerat e të dhënave në kujtesën e pajisjeve kur pajisja të fillojë
Ne duam të fillojmë vlerat e të dhënave në kujtesën e pajisjeve kur pajisja të fillojë
Ne duam të fillojmë vlerat e të dhënave në kujtesën e pajisjeve kur pajisja të fillojë
Ne duam të fillojmë vlerat e të dhënave në kujtesën e pajisjeve kur pajisja të fillojë

Në këtë pikë, ne kemi përdorur shumë ndryshore (emra për të dhëna), por në fakt nuk u kemi caktuar vlera atyre emrave. Ne duam që pajisja të ngarkojë vlerat e të gjithë këtyre variablave në memorie kur fillon, kështu që ne e vendosim inicimin për këto ndryshore në një bllok "në fillim".

Këto janë vlerat që duhet të inicializojmë:

  • Konstantet e sinjalit, sipas protokollit të sinjalit. Vlerat DUHET të jenë:

    • SIG_R = 0
    • SIG_A = 1
    • SIG_B = 2
    • Shënim: Unë i parashtrova këto konstante me "EnumSignals" në mënyrë që të tregoj se këto ndryshore duhet të sillen sikur të ishin pjesë e një lloji të numëruar të quajtur Sinjale. Kjo është mënyra se si këto variabla mund të zbatohen në gjuhë të tjera programimi. Përkufizimi dhe shpjegimi i llojeve të numëruara është përtej fushëveprimit të mësimit tim. Dikush mund ta kërkojë në Google nëse dëshiron. Këto parashtesa janë thjesht zgjedhje stilistike dhe nuk janë aspak thelbësore për funksionimin e duhur të programit.
  • Konstantet e gjendjes, të cilat mund të jenë arbitrare për sa kohë që ato kanë një vlerë. Kam bërë një zgjedhje të stilit për të përdorur thjesht numra të plotë që rriten nga 0, si kështu:

    • E PADASUAR = 0
    • LISTEN_A = 1
    • LISTEN_B = 2
    • TEAM_A = 3
    • TEAM_B = 4
    • Shënim: Kam marrë të njëjtin vendim stili në lidhje me parashtesat edhe për këto ndryshore. Përveç kësaj, unë do të përmend se gjithçka në lidhje me këto caktime, vlerat dhe rendin, është krejtësisht arbitrare. Madje nuk ka rëndësi që këto vlera janë të qëndrueshme nga një pajisje në tjetrën, sepse ato përdoren vetëm brenda dhe jo për komunikim përmes rrjetit. E gjithë ajo që ka rëndësi është që variablat të kenë një vlerë dhe se ato mund të krahasohen me njëra -tjetrën për të parë nëse janë ekuivalente apo jo.
  • Për lexueshmëri, një konstante e quajtur BOOT_STATE dhe vendoseni atë në UNASSIGNED. Kjo e bën faktin që ne rivendosemi në gjendjen e nisjes, në vend të një gjendjeje më arbitrare, më të qartë kur pajisja merr një sinjal rivendosjeje, të cilin do ta zbatojmë më vonë.
  • Konstantet e animacionit, të përdorura në hapin e mëposhtëm për të krijuar animacione që lejojnë ndërprerje jashtëzakonisht të ulët të vonesës përmes hyrjes së përdoruesit. Ne nuk i kemi përdorur këto deri më tani, por ato me siguri do të shpjegohen dhe përdoren në pjesën vijuese. Kuptimi i disa prej këtyre duhet të jetë intuitiv për shkak të emrave të tyre.

    • TICKS_PER_FRAME_LOADING_ANIMATION = 50
    • MS_PER_DEVICE_TICK = 10
    • MS_PER_FRAME_BROADCAST_ANIMATION = 500
    • MICROSECONDS_PER_MILLISECOND = 1000
    • NUMBER_OF_FRAMES_IN_LOADING_ANIMATION = 4
  • Një tjetër ndryshore për animacionin, këtë herë një numërues që definitivisht nuk është konstant. Ashtu si shumica e sporteleve, ne e inicializojmë atë në 0

    iTickLoadingAnimation = 0

  • Krijoni dy seri variablash për të mbajtur kornizat e animacioneve. E para, të cilën e quaj "ngarkimi i animacionit", duhet të ketë katër imazhe (të cilat mund ta keni marrë me mend nga fillimi i fundit konstant), dhe e dyta, të cilën unë e quaj "animacion i transmetimit", i cili duhet të ketë tre imazhe. Unë rekomandoj që emërtimi i variablave të korrespondojë me kornizat e animacionit, p.sh. unazëAnimacion0, unazëAnimacion1…

    Krijoni të njëjtat vlera të imazhit si unë ose krijoni imazhe më origjinale dhe më të ftohta

  • E fundit por jo më pak e rëndësishme, ne duhet të vendosim grupin e radios të pajisjes në 0 duke përdorur bllokun "grupi i radios (X)"
  • Opsionale, shkruani mesazhin "Fillimi i plotë" në daljen serike për t'i treguar përdoruesit se gjithçka shkoi me not.
  • Tani që kemi mbaruar me konfigurimin e pajisjes, mund të thërrasim funksionin tonë të lakut të gjendjes.

Hapi 6: Ne duam të shfaqim animacione dhe grafika duke përdorur ekranin LED 5 X 5

Ne duam të shfaqim animacione dhe grafika duke përdorur ekranin LED 5 X 5
Ne duam të shfaqim animacione dhe grafika duke përdorur ekranin LED 5 X 5
Ne duam të shfaqim animacione dhe grafikë duke përdorur ekranin LED 5 X 5
Ne duam të shfaqim animacione dhe grafikë duke përdorur ekranin LED 5 X 5
Ne duam të shfaqim animacione dhe grafika duke përdorur ekranin LED 5 X 5
Ne duam të shfaqim animacione dhe grafika duke përdorur ekranin LED 5 X 5

Dhe tani për diçka krejtësisht të ndryshme.

Ne duam të shfaqim disa animacione dhe disa karaktere, por nuk duam të ndërpresim lakin kryesor të gjendjes. Fatkeqësisht, blloqet që shfaqin imazhe dhe vargje teksti kanë një vonesë prej 400 ms si parazgjedhje. Nuk ka asnjë mënyrë për ta ndryshuar këtë pa redaktuar përfaqësimin javascript të kodit. Pra, kjo është ajo që ne do të bëjmë.

  • Krijoni një funksion për secilën imazh. Kjo do të lejojë që dikush të përdorë një bllok të vetëm për të shfaqur imazhin në vend që të redaktojë javascript çdo herë. Në këtë program specifik, asnjë imazh nuk përdoret më shumë se një herë, por unë ende mendoj se ky stil e bën kodin më të lehtë për t'u lexuar.
  • Shtoni, në çdo funksion të ri, një bllok "shfaqni imazhin (X) në kompensimin 0" me emrin e ndryshores përkatëse të imazhit që zëvendëson (X)
  • Shtoni, në lakin e gjendjes kryesore. Blloqet "Trego vargun (X)" për secilin bllok përveç atij që trajton gjendjen UNASSIGNED. Shtoni një karakter që pajisja të shfaqë për të treguar gjendjet e saj të ndryshme. Këtu është ajo që kam bërë:

    • LISTEN_A: 'a'
    • LISTEN_B: 'b'
    • TEAM_A: 'A'
    • TEAM_B: 'B'

      Për gjendjen UNASSIGNED, vendosni një thirrje në një funksion që do të përditësojë animacionin e ngarkimit. Ne do të plotësojmë detajet e këtij funksioni më poshtë

  • Kaloni në modalitetin javascript.
  • Gjeni çdo thirrje në X.showImage (0) dhe Basic.showString (X)
  • Ndryshoni secilën në X.showImage (0, 0) ose Basic.showString (X, 0)

    • Shtimi i këtij argumenti shtesë do të vendosë vonesën pas veprimit në 0. Si parazgjedhje, kjo lihet jashtë dhe pajisja do të ndalojë për 400 ms pas ekzekutimit të secilit prej këtyre blloqeve.
    • Tani, ne kemi një mekanizëm gati pa vonesë për të shfaqur imazhet tona në blloqet tona të animacionit, të cilat tani mund t'i ndërtojmë

Së pari, ne do të ndërtojmë funksionin relativisht të thjeshtë të animacionit të transmetimit. Isshtë më e thjeshtë sepse nuk duam që përdoruesi të jetë në gjendje të bëjë asgjë derisa të përfundojë funksioni, në mënyrë që t'i ndalojë ata të spamojnë funksionin e transmetimit. Për ta arritur këtë, ne thjesht mund ta mbajmë rrjedhën e kontrollit të kufizuar në bllok derisa të përfundojë funksioni, që është sjellje standarde.

  • Krijoni një funksion që do të shfaqë animacionin e transmetimit.
  • Brenda atij blloku, shtoni tre thirrje funksionesh, një në secilën kornizë të animacionit, në rendin që ato duhet të shfaqen
  • Shtoni një bllok "prisni (ne) (X)" pas çdo thirrjeje në një funksion të shfaqjes së imazhit.

    Shënim: Ky bllok, nga pjesa e kontrollit të avancuar, do të shkojë edhe më tej se "pauzë (ms)" në atë që do të ngrijë plotësisht procesorin derisa të ketë kaluar koha e specifikuar. Kur përdoret blloku i pauzës, është e mundur që pajisja të kryejë detyra të tjera prapa skenave. Kjo është e pamundur me bllokun e pritjes

  • Zëvendësoni (X) me (MS_PER_FRAME_BROADCAST_ANIMATION x MICROSECONDS_PER_MILLISECOND)
  • Animacioni tani duhet të funksionojë siç duhet

Së dyti, ne do të ndërtojmë mekanizmin për shfaqjen e animacionit të ngarkimit. Ideja prapa kësaj është të përditësoni ekranin LED në një interval të caktuar, të cilin e përcaktojmë në variablën MS_PER_DEVICE_TICK. Kjo vlerë, gjatësia e shënimit të pajisjes, është numri i milisekondave që pajisja ndalon pasi të ketë përfunduar çdo përsëritje të lakut të gjendjes. Meqenëse kjo vlerë është mjaft e vogël, ne mund ta përditësojmë ekranin një herë gjatë çdo përsëritjeje të lakut të ekranit dhe do t'i duket përdoruesit se animacioni po përparon pa probleme, dhe kur të ndryshojë gjendja, do të ketë shumë pak vonesë midis hyrjes së përdoruesit ekrani po përditësohet. Duke numëruar rriqrat, të cilat i bëjmë me ndryshoren iTickLoadingAnimation, ne mund të shfaqim kuadrin e duhur të animacionit.

  • Krijoni një funksion që do të përditësojë animacionin e ngarkimit
  • Shtoni një kusht për të kontrolluar nëse numëruesi i rriqrave ka arritur vlerën e tij maksimale. Ky kusht do të jetë i vërtetë nëse vlera e numëruesit të rriqrave është më e madhe se numri i kornizave në animacionin e ngarkimit shumëzuar me numrin e rriqrave për të shfaqur secilën kornizë

    Nëse gjendja është e vërtetë, rivendosni iTickLoadingAnimation në 0

  • Shtoni një bllok të kushteve nëse-tjetër. Këto do të përcaktojnë se cilën kornizë të animacionit do të shfaqet.

    Për secilën kornizë të animacionit, nëse numëruesi i rriqrave është më i vogël se numri i rriqrave në secilën animacion shumëzuar me numrin e kornizës së animacionit (duke filluar nga 1), atëherë shfaqeni atë kornizë, përndryshe kontrolloni nëse korniza tjetër është ajo që të shfaqet

  • Në fund të bllokut, shtoni iTickLoadingAnimation
  • Animacioni tani duhet të funksionojë siç duhet

Shënim: Të gjitha blloqet gri që shfaqen në shembullin tim krijohen kur dikush redakton përfaqësimin javascript të një blloku. Thjesht do të thotë që blloku përfaqëson kodin javascript që nuk mund të përfaqësohet duke përdorur grupin standard të blloqeve dhe duhet të redaktohet në formë teksti.

Hapi 7: Ne duam të transmetojmë të dhëna pa tel duke përdorur radion e pajisjes

Ne duam të transmetojmë të dhëna pa tel duke përdorur radion e pajisjes
Ne duam të transmetojmë të dhëna pa tel duke përdorur radion e pajisjes

Ky hap është shumë më i shkurtër se ai i mëparshmi. Në fakt, është ndoshta hapi më i shkurtër në të gjithë këtë mësim.

Kujtoni që kur programuam përgjigjen e pajisjes ndaj hyrjes së përdoruesit, kisha dy blloqe në pamjen e ekranit që nuk ishin shpjeguar në atë pjesë. Këto ishin thirrje për funksione që dërgojnë sinjale në radio. Më specifikisht:

  • Në butonin A të shtypur:

    • Nëse pajisja është në gjendje TEAM_A:

      Sinjali i transmetimit SIG_A

  • Në butonin B të shtypur:

    • Nëse pajisja është në gjendje TEAM_B

      Sinjali i transmetimit SIG_B

Krijoni këtë funksion nëse ato nuk ekzistojnë tashmë.

Në secilin funksion:

  • Thirrni funksionin e animacionit të transmetimit. Kjo do të bllokojë çdo gjë tjetër që të ndodhë derisa të përfundojë, e cila do të jetë në MS_PER_FRAME_BROADCAST_ANIMATION * 3 = 1.5 sekonda. Konstanta shumëzohet me tre sepse ka tre korniza në animacion. Kjo është arbitrare dhe mund të shtohet më shumë nëse përmirësimi estetik është mjaft i madh. Qëllimi i dytë i këtij animacioni është parandalimi i përdoruesit nga spamimi i funksionit të transmetimit.
  • Shtoni një bllok "numri i dërgimit të radios (X)", ku është konstantja e sinjalit e përmendur në emrin e funksionit

Kjo është gjithçka që duhet të transmetohet përmes radios.

Hapi 8: Ne duam të dëgjojmë dhe të marrim të dhëna përmes radios së pajisjes dhe t'i përpunojmë ato në përputhje me rrethanat

Ne duam të dëgjojmë dhe marrim të dhëna në radio të pajisjes dhe t'i përpunojmë ato në përputhje me rrethanat
Ne duam të dëgjojmë dhe marrim të dhëna në radio të pajisjes dhe t'i përpunojmë ato në përputhje me rrethanat
Ne duam të dëgjojmë dhe marrim të dhëna në radio të pajisjes dhe t'i përpunojmë ato në përputhje me rrethanat
Ne duam të dëgjojmë dhe marrim të dhëna në radio të pajisjes dhe t'i përpunojmë ato në përputhje me rrethanat

Ky është hapi i fundit për të krijuar aplikacionin kryesor.

Ne do t'i tregojmë pajisjes se si të përpunojë sinjalet e radios në hyrje. Së pari, pajisja jonë do të emërojë sinjalin e marrë. Pastaj, bazuar në vlerën e atij sinjali, do të vendosë se çfarë veprimi do të ndërmarrë, nëse ka.

Së pari:

  1. Krijoni një bllok kodi duke filluar me një bllok "në radio të pranuar (X)".
  2. Opsionale, caktojeni vlerën e marrë një ndryshoreje tjetër me një emër më përshkrues.
  3. Thirrni një funksion që do të përpunojë sinjalin

Së dyti, në funksionin e përpunimit të sinjalit:

  1. Krijoni një bllok deklaratash nëse-tjetër që dega kontrollon rrjedhën bazuar në vlerën e sinjalit.
  2. Nëse sinjali ishte SIG_R

    Vendosni gjendjen e pajisjes në BOOT_STATE (kjo është arsyeja pse ne e krijuam këtë konstante më herët)

  3. Nëse sinjali ishte SIG_A dhe nëse gjendja aktuale është LISTEN_A

    Vendosni gjendjen e pajisjes në TEAM_A

  4. Nëse sinjali ishte SIG_B dhe nëse gjendja aktuale është LISTEN_B

    Vendosni gjendjen e pajisjes në TEAM_B

Kjo eshte. Aplikimi ka përfunduar.

Hapi 9: Pajisja Rrënjë: Ne duam të jemi në gjendje të zgjedhim një sinjal

Pajisja Root: Ne duam të jemi në gjendje të zgjedhim një sinjal
Pajisja Root: Ne duam të jemi në gjendje të zgjedhim një sinjal

Tani, ne do të shkruajmë një aplikacion të thjeshtë për një pajisje "rrënjë", domethënë një pajisje që do të kontrollojë rrjetin.

Kjo pajisje do të duhet të kryejë dy funksione:

  • Ne duam të lejojmë përdoruesin të zgjedhë një nga sinjalet tona
  • Ne duam të lejojmë përdoruesin të transmetojë sinjalin

Meqenëse specifikimi i këtij aplikacioni është një nëngrup i atij të mëparshmi, unë do të jap një përmbledhje, por nuk do të hyj në aq detaje sa kisha më parë. Imazhi i mësipërm përmban kodin e plotë për këtë aplikacion.

Për të lejuar përdoruesin të zgjedhë një sinjal:

  1. Filloni 5 ndryshore në një bllok "në fillim":

    1. Tre sinjalet (0, 1, 2)
    2. Numri i sinjaleve (3)
    3. Një ndryshore për të mbajtur sinjalin e zgjedhur aktualisht (fillimisht i vendosur në sinjalin e parë, 0)
  2. Trajtoni një shtypje të butonit A:

    1. Rritni sinjalin e zgjedhur
    2. Kontrolloni nëse sinjali i zgjedhur është më i madh ose i barabartë me numrin e sinjaleve

      Nëse është kështu, vendosni sinjalin e zgjedhur në 0

  3. Pas bllokut të fillimit, drejtoni një lak "përgjithmonë" që shfaq vlerën aktuale të sinjalit të zgjedhur pa vonesë

Për të lejuar përdoruesin të transmetojë një sinjal

  1. Vendosni grupin e radios në 0 në bllokun "në fillim"
  2. Trajtoni një shtypje të butonit B:

    Transmetoni sinjalin e zgjedhur duke përdorur një bllok "numri i dërgimit të radios (X)"

Kjo eshte. Aplikimi i nyjeve rrënjësore është jashtëzakonisht i thjeshtë.

Hapi 10: Jemi Përfunduar

Jemi Mbaruar
Jemi Mbaruar

Më sipër është një fotografi e pajisjeve që ekzekutojnë aplikacionin. Të dy në të djathtë po ekzekutojnë aplikacionin kryesor "përdorues", dhe ai në të majtë po ekzekuton aplikacionin "rrënjë".

Unë e demonstrova këtë lojë në CS Connections 2018, një konferencë verore një javore për mësuesit e shkollave të mesme dhe të mesme në lidhje me edukimin e shkencave kompjuterike. U dhashë rreth 40 pajisje mësuesve dhe u shpjegova rregullat. Shumica e gjetën lojën argëtuese dhe shumë e konsideruan konfuze derisa nuk kuptuan se si të luanin. Demonstrata ishte e shkurtër, por ne gjetëm që loja ishte e këndshme në mesin e një turme mjaft të larmishme.

Më shumë informacion në lidhje me CS Connections 2018 mund të gjeni këtu.

Recommended: