Taula de continguts:

Network Rivalry: un joc de baixa latència per a la BBC Micro: bit: 10 passos (amb imatges)
Network Rivalry: un joc de baixa latència per a la BBC Micro: bit: 10 passos (amb imatges)

Vídeo: Network Rivalry: un joc de baixa latència per a la BBC Micro: bit: 10 passos (amb imatges)

Vídeo: Network Rivalry: un joc de baixa latència per a la BBC Micro: bit: 10 passos (amb imatges)
Vídeo: ✨Sony X90J X80H A80J Samsung QN900A 8K QN95A 4K QN90A Hisense 50B7100UW 100L9G-CINE100A 50A7500FTUK🔹 2024, Juliol
Anonim
Xarxa de rivalitat: un joc de baixa latència per a la BBC Micro: bit
Xarxa de rivalitat: un joc de baixa latència per a la BBC Micro: bit
Xarxa de rivalitat: un joc de baixa latència per a la BBC Micro: bit
Xarxa de rivalitat: un joc de baixa latència per a la BBC Micro: bit

En aquest tutorial, explicaré com implementar un joc multijugador bàsic al micro: bit de la BBC amb les funcions següents:

  • Una interfície senzilla
  • Baixa latència entre els botons premuts i les actualitzacions de pantalla
  • Un nombre flexible de participants
  • Fàcil control sobre el joc mitjançant un dispositiu remot principal ("root")

El joc és essencialment una simulació de política. Tots els jugadors comencen sense assignar-se a cap equip, excepte dos jugadors. Un d'aquests jugadors està assignat a l'equip A i l'altre a l'equip B.

L'objectiu del joc que cada jugador sigui a l'equip amb la majoria dels jugadors en el moment que tothom es converteixi.

El diagrama anterior il·lustra una màquina d'estats finits, és a dir, una especificació dels estats en què pot estar el dispositiu i les transicions entre aquests estats.

Es pot considerar un estat com el conjunt actual de dades que descriuen la memòria del dispositiu des que es va engegar. Basant-se en aquestes dades, el dispositiu pot realitzar determinades accions o reaccionar de manera diferent a l'entrada de l'usuari.

Una transició és una condició lògica que, quan és certa, fa que el dispositiu canviï el seu estat. Una transició pot ser d’un estat a qualsevol altre estat. Un estat pot tenir diverses transicions.

El diagrama anterior especifica els estats següents:

  • Sense assignar
  • Escolta A
  • Escolta B
  • Equip A.
  • Equip B.

Un dispositiu que executa el codi del joc pot estar en qualsevol d'aquests cinc estats, però només un a la vegada, i només aquests cinc.

Suposaré al llarg de la guia que utilitzeu l’editor MakeCode de Microsoft, que es pot trobar a:

La implementació completa del joc es pot trobar aquí:

makecode.microbit.org/_CvRMtheLbRR3 ("microbit-demo-user" és el nom del projecte)

I la implementació del controlador de xarxa mestre ("root") es pot trobar aquí:

makecode.microbit.org/_1kKE6TRc9TgE ("microbit-demo-root" és el nom del projecte)

Faré referència a aquests exemples al llarg del meu tutorial.

Pas 1: consideracions de disseny d'imatges grans

Abans d’escriure cap codi, hem de pensar com volem que sigui el nostre producte final. en altres paraules, quins són els requisits de l'aplicació? Què hauria de dir el nostre codi al dispositiu quan hagi acabat? He dividit la funcionalitat de l'aplicació principal en sis categories, cadascuna de les quals es pot considerar des d'una perspectiva de disseny diferent.

  1. Volem controlar les accions del dispositiu en funció del seu estat actual
  2. Volem que el dispositiu reaccioni a l'entrada de l'usuari
  3. És possible que vulguem mostrar animacions i gràfics mitjançant la pantalla LED de 5 x 5
  4. Volem inicialitzar els valors de dades a la memòria del dispositiu quan el dispositiu arrenca
  5. Volem transmetre dades sense fils mitjançant la ràdio del dispositiu
  6. Volem escoltar i rebre dades per la ràdio del dispositiu i processar-les en conseqüència

Permeteu-me que expliqui una mica més detalls sobre cadascun.

1. Volem controlar les accions del dispositiu en funció del seu estat actual

Com la majoria dels altres programes, l'execució de les instruccions especificades pel codi passa d'una línia a la vegada. Volem que el nostre dispositiu executi certes instruccions en funció del seu estat intern, tal com il·lustra el diagrama de la part superior d’aquest tutorial. Podríem escriure una sèrie de condicionants després de cada bloc de codi que comprovi que hauria de fer el dispositiu, però aquest enfocament es pot posar molt desordenat molt ràpidament, de manera que utilitzarem un bucle infinit que simplement comprova una variable i es basa en aquesta variable., executa un conjunt específic d'instruccions o no fa res. Aquesta variable s'identificarà amb el sufix "_state" tant a la nostra aplicació d'usuari com a la nostra aplicació arrel.

2. Volem que el dispositiu reaccioni a l'entrada de l'usuari

Tot i l'execució normal del codi que es produeix de manera seqüencial, és a dir, d'una línia a la vegada, necessitem que el nostre dispositiu reaccioni a les pulsacions de botons mentre el bucle d'estat principal determina què ha de fer el dispositiu en cada moment. Amb aquest propòsit, el dispositiu té la capacitat d’enviar senyals al programari de nivell inferior que interactua amb el maquinari, provocant el que s’anomena esdeveniment. Podem escriure codi que indiqui al dispositiu que faci alguna cosa quan detecta un tipus d’esdeveniment específic.

3. Volem mostrar animacions i gràfics mitjançant la pantalla LED de 5 x 5

Sembla que el mecanisme per fer-ho és senzill, però el bloc mostra una imatge afegeix un retard ocult de 400 ms. Com que volem que el nostre dispositiu continuï executant el seu bucle d'estat amb la menor latència possible, haurem d'editar el codi javascript per minimitzar el retard.

4. Volem inicialitzar els valors de dades a la memòria del dispositiu quan el dispositiu arrenca

Abans que el nostre dispositiu faci res, l'aplicació ha de carregar les seves dades a la memòria. Això inclou variables constants anomenades llegibilitat del codi, variables que contenen imatges, que poden formar part d'una animació, i variables de comptador que han de començar a 0 per funcionar correctament. Acabarem amb una llarga llista de noms de variables i els seus valors assignats recentment. Com a opció d’estil personal, designaré valors constants, és a dir, valors que mai no hauré de canviar, utilitzant ALL_CAPS. També prefixaré els identificadors de variables principals amb un nom de categoria que faci referència a una mena d’objecte o tipus en què es troba l’identificador. Això intenta facilitar el seguiment del codi. Mai utilitzaré un nom de variable com "element" o "x" a causa de l'ambigüitat que sorgeix en intentar desxifrar el codi.

5. Volem transmetre dades sense fils mitjançant la ràdio del dispositiu

En realitat, aquesta és una tasca bastant senzilla quan s’utilitza el llenguatge de blocs MakeCode. Simplement configurem tots els dispositius al mateix grup de ràdio en arrencar i, quan volem enviar un senyal, podem passar un número únic al bloc "Número d'enviament de ràdio" que se'ns proporciona. És important que l'emissor i el receptor treballin al mateix grup de ràdio, ja que, si no, envien o reben freqüències diferents i la comunicació fracassarà.

6. Volem escoltar i rebre dades per la ràdio del dispositiu i processar-les en conseqüència

Tenint en compte les mateixes consideracions que l’ítem anterior, escoltarem les transmissions entrants de la mateixa manera que escoltarem l’entrada de l’usuari: amb un controlador d’esdeveniments. Escriurem un bloc de codi que examinarà els senyals entrants i comprovarem si s’ha d’actuar sense molestar el bucle d’estat principal.

A més, hauríem de considerar breument el disseny de l’aplicació root molt més senzilla, un programa que permetrà a un dispositiu controlar tota la xarxa. No dedicaré molt temps a això, ja que és molt més senzill que el disseny anterior i gran part és simplement repetició. He dividit la funcionalitat de l'arrel deice en tres categories.

  1. Volem poder seleccionar un senyal
  2. Volem ser capaços de transmetre un senyal

-

1. Volem poder seleccionar un senyal

Això es pot fer simplement amb un botó que itera els possibles senyals. Com que només n’hi ha tres, aquest enfocament serà suficient. Al mateix temps, podem tenir un bucle que torna a mostrar constantment el senyal seleccionat, cosa que permet a l’usuari prémer un botó i veure com apareix el senyal seleccionat a la pantalla LED amb molt poca latència.

2. Volem poder transmetre un senyal

Com que hi ha dos botons, podem designar-ne un per a la selecció i l’altre per a la confirmació. Igual que l’aplicació d’usuari, simplement enviem el senyal per la xarxa com a número. No cal cap altra informació.

Parlaré més sobre el protocol de senyal simple a la següent secció.

Pas 2: el protocol de senyal: un llenguatge senzill per a la comunicació de xarxa

Els senyals següents es poden considerar com el conjunt de totes les paraules possibles que els dispositius poden utilitzar per parlar entre ells. Com que la xarxa és tan senzilla, no hi ha molt a dir, de manera que podem representar aquests tres senyals mitjançant valors sencers simples.

0. Restableix

  • Identificador al codi: SIG-R
  • Valor enter: 0
  • Finalitat: indiqueu a tots els dispositius que es troben dins de l'abast que deixin de fer el que fan i actuïn com si acabessin d'arrencar. Si aquest senyal arriba a tots els dispositius de la xarxa, es restablirà tota la xarxa i els usuaris podran iniciar un joc nou. Aquest senyal només es pot emetre mitjançant un dispositiu arrel.

1. Conversió A

  • Identificador al codi: SIG-A
  • Valor enter: 1
  • Finalitat: Informeu a qualsevol dispositiu que estigui en estat LISTEN_A, un cop rebi el senyal de conversió, que canviï a l'estat TEAM_A.

2. Conversió B

  1. Identificador al codi: SIG-B
  2. Valor enter: 2
  3. Finalitat: Informeu a qualsevol dispositiu que estigui en estat LISTEN_B, un cop rebi el senyal de conversió, que canviï a l'estat TEAM_B.

Pas 3: volem controlar les accions del dispositiu en funció del seu estat actual

Volem controlar les accions del dispositiu en funció del seu estat actual
Volem controlar les accions del dispositiu en funció del seu estat actual
Volem controlar les accions del dispositiu en funció del seu estat actual
Volem controlar les accions del dispositiu en funció del seu estat actual
Volem controlar les accions del dispositiu en funció del seu estat actual
Volem controlar les accions del dispositiu en funció del seu estat actual

Per fi, podem començar a escriure codi.

Primer, obriu un projecte nou a Make Code

  • Creeu una nova funció. He anomenat bucle meu perquè aquest és el bucle bàsic de l'aplicació
  • Afegiu un bloc de bucle que es repetirà indefinidament. He utilitzat while (true) perquè un literal true mai no serà fals, per tant, el flux de control de l'aplicació no sortirà mai del bucle
  • Afegiu prou blocs if-else per comprovar si el dispositiu es troba en algun dels seus cinc estats possibles
  • Creeu una variable per mantenir l'estat actual del dispositiu
  • Creeu variables per representar cadascun dels cinc estats possibles

    Nota: està bé que aquestes variables encara no tinguin cap valor assignat. Arribarem a això. En aquest moment, és més important que escrivim codi net i fàcil de llegir

  • Canvieu cada condició als blocs if-else per comparar l'estat actual amb un dels estats possibles
  • A la part inferior dels blocs if-else, afegiu una pausa durant un cert nombre de mil·lisegons i creeu una variable per contenir aquest número. L’inicialitzarem més endavant. Assegureu-vos que la variable tingui un nom descriptiu, com ara tick o batec del cor. Com que aquest és el bucle central del dispositiu, aquesta pausa determinarà la velocitat a la qual el dispositiu executa el bucle principal, de manera que és un valor molt important i és massa important per ser un número màgic sense nom.

Nota: no us preocupeu pels blocs grisos de la tercera imatge. Hi arribaré més endavant.

Pas 4: volem reaccionar a l'entrada de l'usuari

Volem reaccionar a la introducció de l'usuari
Volem reaccionar a la introducció de l'usuari
Volem reaccionar a la introducció de l'usuari
Volem reaccionar a la introducció de l'usuari

Ara volem dir al dispositiu com gestiona les pulsacions de botons. La primera idea podria ser simplement utilitzar els blocs "Quan es prem el botó" a la categoria d'entrada, però voldríem tenir un control més granular que això. Utilitzarem el bloc "on event from (X) with value (Y)" del bloc de la categoria de control de la secció avançada, perquè estem avançats en aquest tutorial.

  • Creeu quatre blocs "on event from …".

    • Dos d'aquests haurien de comprovar la font de l'esdeveniment "MICROBIT_ID_BUTTON_A"
    • Dos d'aquests haurien de comprovar la font de l'esdeveniment "MICROBIT_ID_BUTTON_B"
    • Dels dos esdeveniments orientats a cada botó:

      • S’ha de comprovar l’esdeveniment del tipus "MICROBIT_BUTTON_EVT_UP"
      • S’ha de comprovar l’esdeveniment del tipus "MICROBIT_BUTTON_EVT_DOWN"
    • Nota: aquestes opcions de totes les lletres majúscules són etiquetes que s’utilitzen al codi micro: bits de nivell inferior. Simplement són espais reservats que després se substitueixen per enters quan el codi es compila en un binari executable. És més fàcil per als éssers humans utilitzar aquestes etiquetes que buscar quin enter posar, tot i que tots dos funcionarien de la mateixa manera.
  • Vaig triar, per qüestió d'estil, que cada bloc "on event from …" cridés una funció que descrigui l'esdeveniment generat. Tot i que no és estrictament necessari, al meu entendre, això millora la llegibilitat. Si es vol fer-ho, poden posar el codi de gestió d'esdeveniments dins del mateix bloc "on event from …".

    Nota: El bloc de codi que gestiona la resposta del dispositiu a un esdeveniment s'anomena intuïtivament "controlador d'esdeveniments"

  • Afegiu, en cada controlador d'esdeveniments, la mateixa estructura if-else que s'utilitza per dividir el flux de control segons l'estat del dispositiu que l'estructura del bucle d'estat principal.
  • Afegiu blocs d'assignació que modifiquen l'estat del dispositiu tal com s'especifica al nostre diagrama d'estats

    • Sabem que quan el dispositiu està en estat NO ASSIGNAT, el dispositiu hauria de reaccionar al botó A premut per una transició a l’estat LISTEN_A i al botó B premut per una transició a l’estat LISTEN_B
    • També sabem que quan el dispositiu es troba en estat LISTEN_A o LISTEN_B, el dispositiu hauria de reaccionar al botó A alliberat i al botó B alliberat, respectivament, tornant a l'estat NO ASSIGNAT.
    • Finalment, sabem que quan el dispositiu està en estat TEAM_A o TEAM_B, el dispositiu hauria de reaccionar al botó A premut i al botó B premut emetent SIG_A i emetent SIG_B respectivament.

      En aquest moment no és necessari omplir els detalls dels senyals d’emissió. Hi arribarem més endavant. L’important és que indiquem a aquestes funcions que facin servir el codi que escriurem donant un nom a aquest bloc d’accions, com broadcastSignalSIG_A, que descriu el que s’hauria de fer en aquest moment

Pas 5: volem inicialitzar els valors de dades a la memòria dels dispositius quan el dispositiu arrenca

Volem inicialitzar els valors de dades a la memòria dels dispositius quan el dispositiu arrenca
Volem inicialitzar els valors de dades a la memòria dels dispositius quan el dispositiu arrenca
Volem inicialitzar els valors de dades a la memòria dels dispositius quan el dispositiu arrenca
Volem inicialitzar els valors de dades a la memòria dels dispositius quan el dispositiu arrenca
Volem inicialitzar els valors de dades a la memòria dels dispositius quan el dispositiu arrenca
Volem inicialitzar els valors de dades a la memòria dels dispositius quan el dispositiu arrenca

En aquest moment, hem utilitzat moltes variables (noms per a dades), però en realitat no els hem assignat valors. Volem que el dispositiu carregui els valors de totes aquestes variables a la memòria quan arrenca, de manera que posem la inicialització d’aquestes variables en un bloc “on start”.

Aquests són els valors que hem d’inicialitzar:

  • Constants de senyal, segons el protocol de senyal. Els valors DEUEN ser:

    • SIG_R = 0
    • SIG_A = 1
    • SIG_B = 2
    • Nota: He prefixat aquestes constants amb "EnumSignals" per indicar que aquestes variables es comportaran com si formessin part d'un tipus enumerat anomenat Signals. Així es poden implementar aquestes variables en altres llenguatges de programació. La definició i explicació dels tipus enumerats està fora de l’abast del meu tutorial. Es pot fer Google si així ho desitgen. Aquests prefixos són simplement opcions estilístiques i no són gens essencials per al bon funcionament del programa.
  • Constants d'estat, que poden ser arbitràries sempre que tinguin un valor. Vaig escollir un estil per utilitzar sencers sencers ascendents de 0, així:

    • NO ASSIGNAT = 0
    • LISTEN_A = 1
    • LISTEN_B = 2
    • EQUIP_A = 3
    • EQUIP_B = 4
    • Nota: Vaig prendre la mateixa decisió d'estil quant als prefixos d'aquestes variables. A més, esmentaré que tot el que fa a aquestes assignacions, els valors i l’ordre, és completament arbitrari. Ni tan sols importa que aquests valors siguin coherents d'un dispositiu a un altre, ja que només s'utilitzen internament i no per a la comunicació a través de la xarxa. L’important és que les variables tinguin un valor i que es puguin comparar entre elles per veure si són equivalents o no.
  • Per facilitar la llegibilitat, una constant anomenada BOOT_STATE i establir-la a UNASSIGNED. Això fa que el fet de restablir l'estat d'arrencada, en lloc d'un estat més arbitrari, sigui més explícit quan el dispositiu rep un senyal de restabliment, que implementarem més endavant.
  • Constants d'animació, que s'utilitzen al pas següent per crear animacions que permetin una interrupció de latència extremadament baixa mitjançant l'entrada de l'usuari. Fins ara no n’hem utilitzat, però segur que s’explicaran i s’utilitzaran a la secció següent. El significat d’alguns d’aquests hauria de ser intuïtiu a causa dels seus noms.

    • 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
  • Una altra variable de l'animació, aquesta vegada un comptador que definitivament no és constant. Com la majoria de comptadors, l’inicialitzem a 0

    iTickLoadingAnimation = 0

  • Creeu dues sèries de variables per contenir fotogrames d'animacions. La primera, que anomeno "animació de càrrega", hauria de tenir quatre imatges (que potser heu endevinat per la darrera inicialització constant) i la segona, que anomeno "animació de difusió", que hauria de tenir tres imatges. Recomano anomenar les variables perquè corresponguin a fotogrames de l'animació, per exemple. ringAnimation0, ringAnimation1 …

    Creeu els mateixos valors d’imatge que jo o creeu imatges més originals i més fresques

  • Per últim, però no menys important, hem d’establir el grup de ràdio del dispositiu a 0 mitjançant el bloc “grup de grups de ràdio (X)”
  • Opcionalment, escriviu el missatge "Inicialització finalitzada" a la sortida serial per dir-li a l'usuari que tot ha anat perfectament.
  • Ara que hem acabat de configurar el dispositiu, podem trucar a la funció de bucle d'estat.

Pas 6: volem mostrar animacions i gràfics mitjançant la pantalla LED 5 X 5

Volem mostrar animacions i gràfics mitjançant la pantalla LED 5 X 5
Volem mostrar animacions i gràfics mitjançant la pantalla LED 5 X 5
Volem mostrar animacions i gràfics mitjançant la pantalla LED 5 X 5
Volem mostrar animacions i gràfics mitjançant la pantalla LED 5 X 5
Volem mostrar animacions i gràfics mitjançant la pantalla LED 5 X 5
Volem mostrar animacions i gràfics mitjançant la pantalla LED 5 X 5

I ara per una cosa completament diferent.

Volem mostrar algunes animacions i alguns caràcters, però no volem interrompre el bucle d'estat principal. Malauradament, els blocs que mostren imatges i cadenes de text tenen un retard de 400 ms per defecte. No hi ha manera de canviar-ho sense editar la representació javascript del codi. Per tant, això és el que farem.

  • Creeu una funció per a cada imatge. Això permetrà utilitzar un bloc únic per mostrar la imatge en lloc d’editar javascript cada vegada. En aquest programa específic, no s'utilitza cap imatge més d'una vegada, però crec que aquest estil facilita la lectura del codi.
  • Afegiu, a cada nova funció, un bloc "mostra la imatge (X) en offset 0" amb el nom de variable d'imatge corresponent que substitueix (X)
  • Afegeix, al bucle d'estat principal. "Mostra els blocs de cadena (X)" a cada bloc a més del que gestiona l'estat NO ASSIGNAT. Afegiu un caràcter perquè el dispositiu es mostri per indicar-ne els diferents estats. Això és el que vaig fer:

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

      Per a l'estat NO ASSIGNAT, feu una trucada a una funció que actualitzarà l'animació de càrrega. A continuació, emplenarem els detalls d’aquesta funció

  • Canvia al mode javascript.
  • Cerqueu totes les trucades a X.showImage (0) i basic.showString (X)
  • Canvieu-ne totes a X.showImage (0, 0) o basic.showString (X, 0)

    • Si afegiu aquest argument addicional, el retard després de l'acció es definirà a 0. Per defecte, es deixa de banda i el dispositiu es posarà en pausa durant 400 ms després de l'execució de cadascun d'aquests blocs.
    • Ara, tenim un mecanisme gairebé lliure de latència per mostrar les nostres imatges als nostres blocs d’animació, que ara podem construir

En primer lloc, crearem la funció d'animació d'emissió relativament senzilla. És més senzill, ja que no volem que l'usuari pugui fer res fins que la funció estigui completa, per tal d'evitar que envieu el correu brossa a la funció d'emissió. Per aconseguir-ho, podem simplement restringir el flux de control al bloc fins que la funció es completi, que és un comportament estàndard.

  • Creeu una funció que mostrarà animació de difusió.
  • Dins d'aquest bloc, afegiu tres trucades de funció, una a cada fotograma de l'animació, en l'ordre en què s'han de mostrar
  • Afegiu un bloc "wait (us) (X)" després de cada trucada a una funció de visualització d'imatges.

    Nota: Aquest bloc, des de la secció de control avançat, anirà fins i tot més enllà de "pausa (ms)", ja que congelarà completament el processador fins que hagi transcorregut el temps especificat. Quan s’utilitza el bloc de pausa, és possible que el dispositiu realitzi altres tasques entre bastidors. Això és impossible amb el bloc d'espera

  • Substitueix (X) per (MS_PER_FRAME_BROADCAST_ANIMATION x MICROSECONDS_PER_MILLISECOND)
  • Ara l’animació hauria de funcionar correctament

En segon lloc, crearem el mecanisme per mostrar l'animació de càrrega. La idea darrere d’això és actualitzar la pantalla LED a un interval específic, que definim a la variable MS_PER_DEVICE_TICK. Aquest valor, la longitud de la marca del dispositiu, és el nombre de mil·lisegons que el dispositiu posa en pausa després de completar cada iteració del bucle d'estat. Com que aquest valor és prou petit, podem actualitzar la visualització una vegada durant cada iteració del bucle de visualització i a l’usuari li semblarà que l’animació progressa sense problemes i, quan l’estat canvia, hi haurà molt poca latència entre l’entrada de l’usuari. s'està actualitzant la pantalla. Comptant les paparres, que fem amb la variable iTickLoadingAnimation, podem mostrar el marc adequat de l’animació.

  • Creeu una funció que actualitzarà l'animació de càrrega
  • Afegiu una condició per comprovar si el comptador de tick ha assolit el seu valor màxim. Aquesta condició serà certa si el valor del comptador de tick és superior al nombre de fotogrames de l'animació de càrrega multiplicats pel nombre de paparres que es mostren cada frame

    Si la condició és certa, restableix iTickLoadingAnimation a 0

  • Afegiu un bloc de condicions if-else. Aquests determinaran quin marc de l'animació es mostrarà.

    Per a cada fotograma de l'animació, si el comptador de paparres és inferior al nombre de paparres de cada animació multiplicat pel nombre de fotogrames de l'animació (començant per 1), mostreu aquest fotograma; si no, comproveu si el fotograma següent és el es mostrarà

  • A la part inferior del bloc, incrementeu iTickLoadingAnimation
  • Ara l’animació hauria de funcionar correctament

Nota: Tots els blocs grisos que apareixen al meu exemple es generen quan s'edita la representació javascript d'un bloc. Simplement significa que el bloc representa un codi javascript que no es pot representar mitjançant el conjunt estàndard de blocs i que s’ha d’editar en forma de text.

Pas 7: volem transmetre dades sense fils mitjançant la ràdio del dispositiu

Volem transmetre dades sense fils mitjançant la ràdio del dispositiu
Volem transmetre dades sense fils mitjançant la ràdio del dispositiu

Aquest pas és molt més curt que l'anterior. De fet, probablement sigui el pas més curt de tot aquest tutorial.

Recordem que quan vam programar la resposta del dispositiu a l'entrada de l'usuari, tenia dos blocs a la captura de pantalla que no s'explicaven en aquesta secció. Es tractava de trucades a funcions que envien senyals per la ràdio. Més específicament:

  • Premut el botó A:

    • Si el dispositiu està en estat TEAM_A:

      Senyal d'emissió SIG_A

  • Premut el botó B:

    • Si el dispositiu està en estat TEAM_B

      Senyal d'emissió SIG_B

Creeu aquestes funcions si encara no existeixen.

En cada funció:

  • Truqueu a la funció d'animació de difusió. Això evitarà que passi qualsevol altra cosa fins que es completi, que serà en MS_PER_FRAME_BROADCAST_ANIMATION * 3 = 1,5 segons. La constant es multiplica per tres perquè hi ha tres fotogrames a l'animació. Això és arbitrari i es pot afegir més si l’actualització estètica és prou gran. Un segon propòsit d’aquesta animació és evitar que un usuari faci brossa la funció d’emissió.
  • Afegiu un bloc "número d'enviament de ràdio (X)", on és la constant de senyal esmentada al nom de la funció

Això és tot el que cal emetre per ràdio.

Pas 8: volem escoltar i rebre dades per la ràdio del dispositiu i processar-les en conseqüència

Volem escoltar i rebre dades per la ràdio del dispositiu i processar-les en conseqüència
Volem escoltar i rebre dades per la ràdio del dispositiu i processar-les en conseqüència
Volem escoltar i rebre dades per la ràdio del dispositiu i processar-les en conseqüència
Volem escoltar i rebre dades per la ràdio del dispositiu i processar-les en conseqüència

Aquest és l'últim pas per crear l'aplicació principal.

Anem a dir al dispositiu com processar els senyals de ràdio entrants. En primer lloc, el nostre dispositiu anomenarà el senyal rebut. A continuació, basant-se en el valor d’aquest senyal, decidirà quina acció emprendre, si escau.

Primer:

  1. Creeu un bloc de codi que comenci amb un bloc "a la ràdio rebuda (X)".
  2. Opcionalment, assigneu aquest valor rebut a una altra variable amb un nom més descriptiu.
  3. Truqueu a una funció que processarà el senyal

En segon lloc, en la funció de processament del senyal:

  1. Creeu un bloc d’instruccions if-else que controlin el flux en funció del valor del senyal.
  2. Si el senyal era SIG_R

    Estableix l'estat del dispositiu a BOOT_STATE (per això hem creat aquesta constant abans)

  3. Si el senyal era SIG_A i si l’estat actual és LISTEN_A

    Establiu l'estat del dispositiu a TEAM_A

  4. Si el senyal era SIG_B i si l’estat actual és LISTEN_B

    Establiu l'estat del dispositiu a TEAM_B

Això és. L'aplicació s'ha acabat.

Pas 9: Dispositiu arrel: volem ser capaços de seleccionar un senyal

Dispositiu arrel: volem ser capaços de seleccionar un senyal
Dispositiu arrel: volem ser capaços de seleccionar un senyal

Ara escriurem una aplicació senzilla per a un dispositiu "root", és a dir, un dispositiu que controlarà la xarxa.

Aquest dispositiu haurà de realitzar dues funcions:

  • Volem permetre a l'usuari seleccionar un dels nostres senyals
  • Volem permetre a l'usuari emetre el senyal

Com que l'especificació d'aquesta aplicació és un subconjunt de l'anterior, donaré una visió general, però no entraré en tants detalls com abans. La imatge superior conté el codi complet d'aquesta aplicació.

Per permetre a l'usuari seleccionar un senyal:

  1. Inicialitzeu 5 variables en un bloc "on start":

    1. Els tres senyals (0, 1, 2)
    2. El nombre de senyals (3)
    3. Una variable per contenir el senyal seleccionat actualment (inicialment establert al primer senyal, 0)
  2. Premeu el botó A:

    1. Incrementeu el senyal seleccionat
    2. Comproveu si el senyal seleccionat és superior o igual al nombre de senyals

      Si és així, configureu el senyal seleccionat a 0

  3. Després del bloc d'inici, executeu un bucle "per sempre" que mostri el valor del senyal seleccionat actual sense demora

Per permetre a l'usuari emetre un senyal

  1. Establiu el grup de ràdio a 0 al bloc "on start"
  2. Premeu el botó B:

    Emet el senyal seleccionat mitjançant un bloc "número d'enviament de ràdio (X)"

Això és. L'aplicació del node arrel és extremadament senzilla.

Pas 10: estem acabats

Estem acabats
Estem acabats

A la part superior es mostra una imatge dels dispositius que executen l'aplicació. Els dos de la dreta executen l'aplicació principal "usuari" i la de l'esquerra executa l'aplicació "arrel".

Vaig demostrar aquest joc a CS Connections 2018, una conferència d’estiu d’una setmana per a professors de secundària i secundària sobre educació informàtica. Vaig lliurar uns 40 dispositius als professors i vaig explicar les regles. A la majoria els va semblar entretingut el joc, i a molts els va semblar confús fins que van descobrir com jugar. La demostració va ser curta, però vam trobar que el joc era agradable entre una multitud força diversa.

Podeu trobar més informació sobre CS Connections 2018 aquí.

Recomanat: