Innholdsfortegnelse:

Network Rivalry: a Low-Latency Game for BBC Micro: bit: 10 Steps (med bilder)
Network Rivalry: a Low-Latency Game for BBC Micro: bit: 10 Steps (med bilder)

Video: Network Rivalry: a Low-Latency Game for BBC Micro: bit: 10 Steps (med bilder)

Video: Network Rivalry: a Low-Latency Game for BBC Micro: bit: 10 Steps (med bilder)
Video: IQ TEST 2024, November
Anonim
Network Rivalry: a Low-Latency Game for BBC Micro: bit
Network Rivalry: a Low-Latency Game for BBC Micro: bit
Network Rivalry: a Low-Latency Game for BBC Micro: bit
Network Rivalry: a Low-Latency Game for BBC Micro: bit

I denne opplæringen vil jeg forklare hvordan du implementerer et grunnleggende flerspillerspill på BBC micro: bit med følgende funksjoner:

  • Et enkelt grensesnitt
  • Lav ventetid mellom knappetrykk og skjermoppdateringer
  • Et fleksibelt antall deltakere
  • Enkel kontroll over spillet ved hjelp av en hovedkontrollenhet ("root")

Spillet er egentlig en simulering av politikk. Alle spillerne starter uten tildeling til ethvert lag, bortsett fra to spillere. En av disse spillerne er tildelt Team A, og den andre er tildelt Team B.

Målet med spillet for hver spiller å være på laget med flertallet av spillerne på det tidspunktet hvor alle blir konvertert.

Diagrammet ovenfor illustrerer en endelig tilstandsmaskin, dvs. en spesifikasjon av tilstandene som enheten kan være i og overgangene mellom disse tilstandene.

En tilstand kan betraktes som det nåværende datasettet som beskriver minnet til enheten siden den ble slått på. Basert på disse dataene kan enheten utføre visse handlinger eller reagere annerledes på brukerens input.

En overgang er en logisk tilstand som, når den er sann, får enheten til å endre tilstanden. En overgang kan være fra en stat til en annen stat. En stat kan ha flere overganger.

Diagrammet ovenfor angir følgende tilstander:

  • Ikke tilordnet
  • Hør etter A.
  • Lytt til B.
  • Lag A
  • Lag B

En enhet som kjører spillkoden kan være i en av disse fem delstatene, men bare én om gangen, og bare disse fem.

Jeg vil i hele veiledningen anta at du bruker Microsofts MakeCode -editor, som du finner på:

Den fullstendige implementeringen av spillet finner du her:

makecode.microbit.org/_CvRMtheLbRR3 ("microbit-demo-user" er prosjektnavnet)

Og implementering av master ("root") nettverkskontrolleren finner du her:

makecode.microbit.org/_1kKE6TRc9TgE ("microbit-demo-root" er prosjektnavnet)

Jeg vil referere til disse eksemplene gjennom hele opplæringen min.

Trinn 1: Big Picture Design -hensyn

Før vi skriver noen kode, må vi tenke på hvordan vi vil at sluttproduktet skal se ut. med andre ord, hva er kravene til søknaden? Hva skal koden vår fortelle enheten å gjøre når den er ferdig? Jeg har delt funksjonaliteten til hovedprogrammet inn i seks kategorier, som hver kan vurderes fra et annet designperspektiv.

  1. Vi ønsker å kontrollere enhetens handlinger basert på den nåværende tilstanden
  2. Vi vil at enheten skal reagere på brukerens innspill
  3. Det kan være lurt å vise animasjoner og grafikk ved å bruke 5 x 5 LED -skjermen
  4. Vi ønsker å initialisere dataverdier i enhetsminnet når enheten starter opp
  5. Vi ønsker å overføre data trådløst ved hjelp av enhetens radio
  6. Vi ønsker å lytte etter og motta data over enhetens radio og behandle dem deretter

La meg gå inn på litt mer detaljert informasjon om hver enkelt.

1. Vi ønsker å kontrollere enhetens handlinger basert på den nåværende tilstanden

Som de fleste andre programmer skjer utførelsen av instruksjonene spesifisert av koden én linje om gangen. Vi vil at enheten skal utføre visse instruksjoner basert på dens interne tilstand, som illustrert av diagrammet øverst i denne opplæringen. Vi kan skrive en serie betingelser etter hver blokkblokk som sjekker at enheten skal gjøre, men denne tilnærmingen kan bli veldig rotete veldig raskt, så vi vil i stedet bruke en uendelig sløyfe som bare sjekker en variabel, og basert på den variabelen, utfører et bestemt sett med instruksjoner eller gjør ingenting i det hele tatt. Denne variabelen vil bli identifisert med suffikset "_state" i både brukerprogrammet og rootprogrammet.

2. Vi vil at enheten skal reagere på brukerinngang

Til tross for at normal utførelse av koden skjer sekvensielt, det vil si én linje om gangen, trenger vi at enheten reagerer på knappetrykk mens hovedtilstandsløyfen bestemmer hva enheten skal gjøre til enhver tid. For dette formålet har enheten muligheten til å sende signaler til programvaren på lavere nivå som samhandler med maskinvaren, og utløser det som kalles en hendelse. Vi kan skrive kode som forteller enheten om å gjøre noe når den oppdager en bestemt type hendelse.

3. Vi ønsker å vise animasjoner og grafikk ved hjelp av 5 x 5 LED -skjermen

Mekanismen for å gjøre dette ser ut til å være enkel, men blokken viser et bilde og legger til en skjult forsinkelse på 400 ms. Fordi vi vil at enheten skal fortsette å utføre tilstandssløyfen med så lite ventetid som mulig, må vi redigere javascript -koden for å minimere forsinkelsen.

4. Vi ønsker å initialisere dataverdier i enhetsminnet når enheten starter opp

Før enheten vår gjør noe, må programmet laste dataene inn i minnet. Dette inkluderer konstante variabler oppkalt etter kodelesbarhet, variabler som inneholder bilder, som kan være en del av en animasjon, og motvariabler som må starte på 0 for å fungere skikkelig. Vi vil ende opp med en lang liste med variabelnavn og deres nylig tildelte verdier. Som et personlig stilvalg vil jeg betegne konstante verdier, dvs. verdier som jeg aldri trenger å endre, ved hjelp av ALL_CAPS. Jeg vil også prefiks hovedvariabelidentifikatorer med et kategorinavn som refererer til en slags objekt eller type som identifikatoren faller under. Dette er et forsøk på å gjøre koden lettere å følge. Jeg vil aldri bruke et variabelnavn som "element" eller "x" på grunn av tvetydigheten som oppstår når jeg prøver å tyde koden.

5. Vi ønsker å overføre data trådløst ved hjelp av enhetens radio

Dette er faktisk en ganske enkel oppgave når du bruker MakeCode -blokkeringsspråket. Vi setter ganske enkelt alle enheter til den samme radiogruppen ved oppstart, og når vi vil sende et signal, kan vi sende et enkelt nummer til "Radio send nummer" -blokken som er gitt oss. Det er viktig at avsenderen og mottakeren jobber med den samme radiogruppen, for hvis ikke vil de sende eller motta på forskjellige frekvenser, og kommunikasjonen vil mislykkes.

6. Vi ønsker å lytte etter og motta data over enhetens radio og behandle dem deretter

Når vi tar i betraktning de samme hensynene som det forrige elementet, vil vi lytte etter innkommende overføringer på samme måte som vi vil lytte etter brukerinngang: med en hendelsesbehandler. Vi skriver en kodeblokk som undersøker alle innkommende signaler og sjekker om det skal gjøres noe uten å forstyrre hovedstatusløkken.

I tillegg bør vi kort vurdere utformingen av den langt enklere rotprogrammet, et program som lar en enhet kontrollere hele nettverket. Jeg vil ikke bruke mye tid på dette, da det er langt enklere enn designet ovenfor, og mye av det er bare gjentagelse. Jeg har delt funksjonaliteten til rotdeisen i tre kategorier.

  1. Vi ønsker å kunne velge et signal
  2. Vi ønsker å kunne overføre et signal

-

1. Vi ønsker å kunne velge et signal

Dette kan gjøres ved ganske enkelt å ha en knapp som går gjennom de mulige signalene. Siden det bare er tre, vil denne tilnærmingen være tilstrekkelig. Samtidig kan vi ha en sløyfe som stadig viser det valgte signalet på nytt, slik at brukeren kan trykke på en knapp og se det valgte signalet vises på LED -displayet med svært liten ventetid.

2. Vi ønsker å kunne overføre et signal

Siden det er to knapper, kan vi angi en for valg og den andre for bekreftelse. I likhet med brukerprogrammet sender vi ganske enkelt signalet over nettverket som et tall. Det kreves ingen annen informasjon.

Jeg vil snakke mer om den enkle signalprotokollen i neste avsnitt.

Trinn 2: Signalprotokollen: et enkelt språk for nettverkskommunikasjon

Følgende signaler kan betraktes som settet med alle mulige ord som enhetene kan bruke til å snakke med hverandre. Fordi nettverket er så enkelt, er det ikke mye å si, og derfor kan vi representere disse tre signalene med enkle heltallsverdier.

0. Tilbakestill

  • Identifikator i koden: SIG-R
  • Heltall verdi: 0
  • Formål: Fortell alle enheter innenfor rekkevidde å slippe det de gjør og opptre som om de nettopp ble startet opp. Hvis dette signalet når alle enheter i nettverket, blir hele nettverket tilbakestilt og brukerne kan starte et nytt spill. Dette signalet kan bare sendes av en rotenhet.

1. Konvertering A

  • Identifikator i koden: SIG-A
  • Heltall verdi: 1
  • Formål: Fortell enhver enhet som er i tilstand LISTEN_A, når de mottar konverteringssignalet, å bytte til tilstand TEAM_A.

2. Konvertering B

  1. Identifikator i koden: SIG-B
  2. Heltall verdi: 2
  3. Formål: Fortell enhver enhet som er i tilstand LISTEN_B, når de mottar konverteringssignalet, å bytte til tilstanden TEAM_B.

Trinn 3: Vi ønsker å kontrollere enhetens handlinger basert på dens nåværende tilstand

Vi ønsker å kontrollere enhetens handlinger basert på dens nåværende tilstand
Vi ønsker å kontrollere enhetens handlinger basert på dens nåværende tilstand
Vi ønsker å kontrollere enhetens handlinger basert på dens nåværende tilstand
Vi ønsker å kontrollere enhetens handlinger basert på dens nåværende tilstand
Vi ønsker å kontrollere enhetens handlinger basert på den nåværende tilstanden
Vi ønsker å kontrollere enhetens handlinger basert på den nåværende tilstanden

Endelig kan vi begynne å skrive kode.

Først åpner du et nytt prosjekt i Make Code

  • Lag en ny funksjon. Jeg ringte mine loop fordi dette er kjernesløyfen i applikasjonen
  • Legg til en loop -blokk som vil gjenta seg på ubestemt tid. Jeg brukte mens (true) fordi en bokstavelig sant aldri vil være falsk, derfor vil kontrollflyten til applikasjonen aldri gå ut av løkken
  • Legg til nok if-else-blokker for å sjekke om enheten er i noen av de fem mulige tilstandene
  • Lag en variabel for å beholde gjeldende enhetstilstand
  • Lag variabler for å representere hver av de fem mulige tilstandene

    Merk: Det er OK at disse variablene ikke har noen tildelte verdier ennå. Det kommer vi til. På dette tidspunktet er det viktigere at vi skriver ren, lettlest kode

  • Endre hver tilstand i if-else-blokkene for å sammenligne gjeldende tilstand med en av de mulige tilstandene
  • Nederst i if-else-blokkene legger du til en pause for et antall millisekunder, og oppretter en variabel for å beholde dette tallet. Vi vil initialisere det senere. Sørg for at variabelen har et beskrivende navn, for eksempel kryss eller hjerteslag. Fordi dette er kjernesløyfen til enheten, vil denne pausen bestemme hastigheten enheten utfører hovedsløyfen med, så det er en veldig viktig verdi, og er for viktig til å være et magisk tall uten navn.

Merk: Ikke bekymre deg for de grå blokkene i det tredje bildet. Jeg kommer til dem senere.

Trinn 4: Vi ønsker å reagere på brukerinput

Vi ønsker å reagere på brukerinput
Vi ønsker å reagere på brukerinput
Vi ønsker å reagere på brukerinput
Vi ønsker å reagere på brukerinput

Nå vil vi fortelle enheten hvordan du håndterer knappetrykk. Den første tanken din kan være å bare bruke blokkene "Når du trykker på knappen" i inngangskategorien, men vi vil ha mer detaljert kontroll enn det. Vi vil bruke blokkeringen "på hendelse fra (X) med verdi (Y)" fra kontrollkategorien under den avanserte delen, fordi vi er avanserte i denne opplæringen.

  • Lag fire "on event from …" blokker.

    • To av disse bør sjekke hendelseskilden "MICROBIT_ID_BUTTON_A"
    • To av disse bør sjekke hendelseskilden "MICROBIT_ID_BUTTON_B"
    • Av de to hendelsene som er rettet mot hver knapp:

      • Man bør se etter hendelsen av typen "MICROBIT_BUTTON_EVT_UP"
      • Man bør se etter hendelsen av typen "MICROBIT_BUTTON_EVT_DOWN"
    • Merk: Disse alternativene i alle store bokstaver er etiketter som brukes i mikro-bit-koden på lavere nivå. De er rett og slett plassholdere som senere erstattes av heltall når koden kompileres til en kjørbar binær. Det er lettere for mennesker å bruke disse etikettene enn å slå opp hvilket heltall de skal sette inn, selv om begge ville fungere på samme måte.
  • Jeg valgte, som et spørsmål om stil, å ha hver "på hendelse fra …" blokkanrop til en funksjon som beskriver den hevede hendelsen. Selv om det ikke er strengt nødvendig, forbedrer dette etter min mening lesbarheten. Hvis en ønsker å gjøre det, kan de sette hendelseshåndteringskoden inne i "on event from …" -blokken selv.

    Merk: Kodeblokken som håndterer enhetens svar på en hendelse kalles intuitivt en "hendelsesbehandler"

  • Legg til i hver hendelsesbehandler den samme if-else-strukturen som ble brukt til å dele kontrollflyt basert på enhetstilstand som strukturen i hovedtilstandsløkken.
  • Legg til tildelingsblokker som endrer enhetens tilstand som angitt av vårt tilstandsdiagram

    • Vi vet at når enheten er i status UNASSIGNED, bør enheten reagere på knapp A trykket ved en overgang til tilstand LISTEN_A, og til knapp B trykket ved en overgang til tilstand LISTEN_B
    • Vi vet også at når enheten er i tilstanden LISTEN_A eller LISTEN_B, bør enheten reagere på henholdsvis knapp A slippes og knapp B slippes ved å gå tilbake til tilstanden UMERKET.
    • Til slutt vet vi at når enheten er i tilstanden TEAM_A eller TEAM_B, skal enheten reagere på knapp A trykket og knapp B trykket ved å kringkaste SIG_A og ved å kringkaste SIG_B.

      Det er ikke nødvendig på dette tidspunktet å fylle ut detaljene for kringkastingssignaler. Det kommer vi til senere. Det som er viktig er at vi instruerer disse funksjonene til å bruke koden som vi vil skrive ved å gi denne handlingsblokken et navn, som broadcastSignalSIG_A, som beskriver hva som bør gjøres på det tidspunktet

Trinn 5: Vi vil initialisere dataverdier i enhetsminnet når enheten starter opp

Vi ønsker å initialisere dataverdier i enhetsminnet når enheten starter opp
Vi ønsker å initialisere dataverdier i enhetsminnet når enheten starter opp
Vi ønsker å initialisere dataverdier i enhetsminnet når enheten starter opp
Vi ønsker å initialisere dataverdier i enhetsminnet når enheten starter opp
Vi ønsker å initialisere dataverdier i enhetsminnet når enheten starter opp
Vi ønsker å initialisere dataverdier i enhetsminnet når enheten starter opp

På dette tidspunktet har vi brukt mange variabler (navn på data), men vi har faktisk ikke tilordnet verdier til disse navnene. Vi vil at enheten skal laste inn verdiene til alle disse variablene i minnet når den starter, så vi plasserer initialiseringen for disse variablene i en "på start" -blokk.

Dette er verdiene vi må initialisere:

  • Signalkonstanter, i henhold til signalprotokollen. Verdiene MÅ være:

    • SIG_R = 0
    • SIG_A = 1
    • SIG_B = 2
    • Merk: Jeg prefikset disse konstantene med "EnumSignals" for å angi at disse variablene skal oppføre seg som om de var en del av en oppregnet type kalt Signaler. Slik kan disse variablene implementeres i andre programmeringsspråk. Definisjonen og forklaringen på oppregnede typer er utenfor omfanget av opplæringen min. Man kan google det hvis de ønsker det. Disse prefiksene er ganske enkelt stilistiske valg og er slett ikke avgjørende for at programmet skal fungere ordentlig.
  • Statskonstanter, som kan være vilkårlige så lenge de har en verdi. Jeg tok et stilvalg for å bare bruke heltall som stiger fra 0, slik:

    • UTILSIGTET = 0
    • LISTEN_A = 1
    • LISTEN_B = 2
    • TEAM_A = 3
    • TEAM_B = 4
    • Merk: Jeg tok den samme stilbeslutningen når det gjelder prefikser også for disse variablene. I tillegg vil jeg nevne at alt om disse oppdragene, verdiene og rekkefølgen, er helt vilkårlig. Det spiller ingen rolle at disse verdiene er konsistente fra enhet til enhet, fordi de bare brukes internt og ikke for kommunikasjon over nettverket. Det eneste som betyr noe er at variablene har en verdi og at de kan sammenlignes med hverandre for å se om de er likeverdige eller ikke.
  • For lesbarhet, kalles en konstant BOOT_STATE og setter den til UNASSIGNED. Dette gjør det faktum at vi tilbakestiller til oppstartstilstanden, i stedet for en mer vilkårlig tilstand, mer eksplisitt når enheten mottar et tilbakestillingssignal, som vi vil implementere senere.
  • Animasjonskonstanter, brukt i det følgende trinnet for å lage animasjoner som gir mulighet for ekstremt lav latensavbrudd via brukerinngang. Vi har ikke brukt disse så langt, men de vil sikkert bli forklart og brukt i den følgende delen. Betydningen av noen av disse burde være intuitive på grunn av navnene deres.

    • 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
  • En annen variabel for animasjon, denne gangen en teller som definitivt ikke er konstant. Som de fleste tellere initialiserer vi det til 0

    iTickLoadingAnimation = 0

  • Lag to serier med variabler for å holde rammer med animasjoner. Den første, som jeg kaller "lasteanimasjonen", skal ha fire bilder (som du kanskje har gjettet ved den siste konstante initialiseringen), og den andre, som jeg kaller "kringkastingsanimasjonen", som skal ha tre bilder. Jeg anbefaler å navngi variablene for å korrespondere med animasjonens rammer, f.eks. ringAnimation0, ringAnimation1 …

    Lag de samme bildeverdiene som jeg gjorde, eller lag mer originale og kulere bilder

  • Sist, men ikke minst, må vi sette radiogruppen til enheten til 0 ved hjelp av "radiosettgruppe (X)" -blokken
  • Du kan også skrive meldingen "Initialisering fullført" til seriell utgang for å fortelle brukeren at alt gikk bra.
  • Nå som vi er ferdige med å sette opp enheten, kan vi kalle vår tilstandsløyfefunksjon.

Trinn 6: Vi ønsker å vise animasjoner og grafikk ved å bruke 5 x 5 LED -skjermen

Vi ønsker å vise animasjoner og grafikk ved hjelp av 5 x 5 LED -skjermen
Vi ønsker å vise animasjoner og grafikk ved hjelp av 5 x 5 LED -skjermen
Vi ønsker å vise animasjoner og grafikk ved hjelp av 5 x 5 LED -skjermen
Vi ønsker å vise animasjoner og grafikk ved hjelp av 5 x 5 LED -skjermen
Vi ønsker å vise animasjoner og grafikk ved å bruke 5 x 5 LED -skjermen
Vi ønsker å vise animasjoner og grafikk ved å bruke 5 x 5 LED -skjermen

Og nå for noe helt annet.

Vi ønsker å vise noen få animasjoner og noen få tegn, men vi ønsker ikke å avbryte hovedstatusløkken. Dessverre har blokkene som viser bilder og tekststrenger som standard en forsinkelse på 400 ms. Det er ingen måte å endre dette uten å redigere JavaScript -representasjonen av koden. Så dette er hva vi skal gjøre.

  • Lag en funksjon for hvert bilde. Dette vil tillate en å bruke en enkelt blokk for å vise bildet i stedet for å redigere javascript hver gang. I dette spesifikke programmet brukes ikke noe bilde mer enn én gang, men jeg tror fortsatt denne stilen gjør koden lettere å lese.
  • Legg til i hver nye funksjon en "vis bilde (X) ved forskyvning 0" -blokk med det tilsvarende bildevariabelnavnet som erstatter (X)
  • Legg til i hovedstatusløkken. "Vis streng (X)" -blokker til hver blokk i tillegg til den som håndterer tilstanden UTILSIGTET. Legg til et tegn for enheten å vise for å indikere de forskjellige tilstandene. Her er hva jeg gjorde:

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

      For tilstanden UTILSIGT, ring til en funksjon som oppdaterer lasteanimasjonen. Vi vil fylle ut detaljene for denne funksjonen nedenfor

  • Bytt til javascript -modus.
  • Finn hver samtale til X.showImage (0) og basic.showString (X)
  • Endre hver enkelt til enten X.showImage (0, 0) eller basic.showString (X, 0)

    • Hvis du legger til dette ekstra argumentet, settes forsinkelsen etter handlingen til 0. Som standard er dette utelatt, og enheten vil stoppe i 400 ms etter at hver av disse blokkene ble utført.
    • Nå har vi en nesten latensfri mekanisme for å vise bildene våre i animasjonsblokkene våre, som vi nå kan bygge

Først skal vi bygge den relativt enkle kringkastingsanimasjonsfunksjonen. Det er enklere fordi vi ikke vil at brukeren skal kunne gjøre noe før funksjonen er fullført, for å hindre dem i å spamme kringkastingsfunksjonen. For å oppnå dette kan vi ganske enkelt holde kontrollstrømmen begrenset til blokken til funksjonen er fullført, som er standard oppførsel.

  • Lag en funksjon som viser kringkastingsanimasjon.
  • I den blokken legger du til tre funksjonsanrop, ett til hver ramme i animasjonen, i den rekkefølgen de skal vises
  • Legg til en "vent (oss) (X)" -blokk etter hver samtale til en bildevisningsfunksjon.

    Merk: Denne blokken fra den avanserte kontrolldelen vil gå enda lenger enn "pause (ms)" ved at den vil fryse prosessoren helt til den angitte tiden har gått. Når pauseblokken brukes, er det mulig at enheten vil utføre andre oppgaver bak kulissene. Dette er umulig med venteblokken

  • Erstatt (X) med (MS_PER_FRAME_BROADCAST_ANIMATION x MICROSECONDS_PER_MILLISECOND)
  • Animasjonen skal nå fungere skikkelig

For det andre skal vi bygge mekanismen for visning av lasteanimasjonen. Tanken bak dette er å oppdatere LED -displayet med et bestemt intervall, som vi definerer i variabelen MS_PER_DEVICE_TICK. Denne verdien, enhetens krysslengde, er antall millisekunder som enheten stopper etter at hver iterasjon av tilstandssløyfen er fullført. Fordi denne verdien er liten nok, kan vi oppdatere skjermen én gang under hver iterasjon av skjermsløyfen, og det vil vises for brukeren at animasjonen går sømløst, og når tilstanden endres, vil det være svært liten ventetid mellom brukerens inngang displayet oppdateres. Ved å telle flått, som vi gjør med varianten iTickLoadingAnimation, kan vi vise passende ramme for animasjonen.

  • Lag en funksjon som oppdaterer lasteanimasjonen
  • Legg til en betingelse for å sjekke om flåttelleren har nådd sin maksimale verdi. Denne betingelsen vil være sann hvis flåttellerens verdi er større enn antall rammer i lasteanimasjonen multiplisert med antall flått for å vise hver ramme

    Hvis betingelsen er sann, tilbakestill iTickLoadingAnimation til 0

  • Legg til en blokk med if-else-betingelser. Disse bestemmer hvilken ramme i animasjonen som skal vises.

    For hver ramme i animasjonen, hvis kryssetelleren er mindre enn antall flått i hver animasjon multiplisert med animasjonsrammen (fra 1), må du vise den rammen, ellers sjekke om den neste rammen er den vises

  • Nederst i blokken øker du iTickLoadingAnimation
  • Animasjonen skal nå fungere skikkelig

Merk: Alle de grå blokkene som vises i eksemplet mitt, genereres når man redigerer javascript -representasjonen av en blokk. Det betyr ganske enkelt at blokken representerer javascript -kode som ikke kan representeres ved hjelp av standardsettet med blokker og må redigeres i tekstform.

Trinn 7: Vi ønsker å overføre data trådløst ved hjelp av enhetens radio

Vi ønsker å overføre data trådløst ved hjelp av enhetens radio
Vi ønsker å overføre data trådløst ved hjelp av enhetens radio

Dette trinnet er langt kortere enn det forrige. Faktisk er det sannsynligvis det korteste trinnet i hele denne opplæringen.

Husk at da vi programmerte enhetens svar på brukerinngang, hadde jeg to blokker i skjermbildet som ikke ble forklart i den delen. Dette var anrop til funksjoner som sender signaler over radioen. Mer spesifikt:

  • På knappen A trykket:

    • Hvis enheten er i tilstanden TEAM_A:

      Kringkastingssignal SIG_A

  • Trykk på knappen B:

    • Hvis enheten er i tilstanden TEAM_B

      Kringkastingssignal SIG_B

Lag disse funksjonene hvis de ikke allerede eksisterer.

I hver funksjon:

  • Ring til kringkastingsanimasjonsfunksjonen. Dette vil blokkere alt annet som skjer før det er fullført, som vil være i MS_PER_FRAME_BROADCAST_ANIMATION * 3 = 1,5 sekunder. Konstanten multipliseres med tre fordi det er tre rammer i animasjonen. Dette er vilkårlig og mer kan legges til hvis den estetiske oppgraderingen er stor nok. Et annet formål med denne animasjonen er å forhindre en bruker i å spamme kringkastingsfunksjonen.
  • Legg til en "radiosendingsnummer (X)" -blokk, hvor er signalkonstanten nevnt i funksjonsnavnet

Det er alt man trenger å kringkaste over radioen.

Trinn 8: Vi ønsker å lytte etter og motta data over enhetens radio og behandle den deretter

Vi ønsker å lytte etter og motta data over enhetens radio og behandle den deretter
Vi ønsker å lytte etter og motta data over enhetens radio og behandle den deretter
Vi ønsker å lytte etter og motta data over enhetens radio og behandle den deretter
Vi ønsker å lytte etter og motta data over enhetens radio og behandle den deretter

Dette er det siste trinnet for å lage hovedprogrammet.

Vi skal fortelle enheten hvordan de skal behandle innkommende radiosignaler. Først skal enheten navngi det mottatte signalet. Basert på verdien av det signalet, vil det deretter avgjøre hvilken handling som skal iverksettes.

Først:

  1. Lag en kodeblokk som begynner med en "på radio mottatt (X)" blokk.
  2. Tilordne eventuelt den mottatte verdien til en annen variabel med et mer beskrivende navn.
  3. Ring til en funksjon som vil behandle signalet

For det andre, i signalbehandlingsfunksjonen:

  1. Lag en blokk med if-else-utsagn som forgrener kontrollflyten basert på verdien av signalet.
  2. Hvis signalet var SIG_R

    Sett enhetens tilstand til BOOT_STATE (det er derfor vi opprettet denne konstanten tidligere)

  3. Hvis signalet var SIG_A og hvis gjeldende tilstand er LISTEN_A

    Sett enhetens tilstand til TEAM_A

  4. Hvis signalet var SIG_B og hvis gjeldende tilstand er LISTEN_B

    Sett enhetens tilstand til TEAM_B

Det er det. Søknaden er ferdig.

Trinn 9: Rootenhet: Vi vil være i stand til å velge et signal

Rootenhet: Vi vil være i stand til å velge et signal
Rootenhet: Vi vil være i stand til å velge et signal

Nå skal vi skrive en enkel applikasjon for en "root" -enhet, det vil si en enhet som skal kontrollere nettverket.

Denne enheten må utføre to funksjoner:

  • Vi ønsker å la brukeren velge et av signalene våre
  • Vi vil tillate brukeren å kringkaste signalet

Fordi spesifikasjonen til denne applikasjonen er en delmengde av den forrige, vil jeg gi en oversikt, men jeg vil ikke gå så detaljert inn som jeg hadde før. Bildet ovenfor inneholder den komplette koden for denne applikasjonen.

Slik lar brukeren velge et signal:

  1. Initialiser 5 variabler i en "på start" -blokk:

    1. De tre signalene (0, 1, 2)
    2. Antall signaler (3)
    3. En variabel for å holde det valgte signalet (opprinnelig satt til det første signalet, 0)
  2. Håndter et trykk på A -knappen:

    1. Øk det valgte signalet
    2. Kontroller om det valgte signalet er større enn eller lik antallet signaler

      Sett i så fall det valgte signalet til 0

  3. Etter startblokken, kjør en "evig" sløyfe som viser gjeldende valgt signalverdi uten forsinkelse

For å la brukeren kringkaste et signal

  1. Sett radiogruppen til 0 i blokken "på start"
  2. Håndter et trykk på B -knappen:

    Kringkast det valgte signalet med en "radiosendernummer (X)" -blokk

Det er det. Rotnodeprogrammet er ekstremt enkelt.

Trinn 10: Vi er ferdige

Vi er ferdige
Vi er ferdige

Over er et bilde av enhetene som kjører applikasjonen. De to til høyre kjører hoved "bruker" -programmet, og den til venstre kjører "root" -appen.

Jeg demonstrerte dette spillet på CS Connections 2018, en ukelang sommerkonferanse for lærere på ungdomsskolen og videregående om informatikkutdanning. Jeg ga ut rundt 40 enheter til lærerne og forklarte reglene. De fleste syntes spillet var underholdende, og mange syntes det var forvirrende til de fant ut hvordan de skulle spille. Demonstrasjonen var kort, men vi syntes spillet var hyggelig blant en ganske mangfoldig mengde.

Mer informasjon om CS Connections 2018 finner du her.

Anbefalt: