2014 Android apps met App Inventor 2 antwoorden F. Vonk versie 1 11-11-2014
inhoudsopgave Mollen Meppen... - 2 - Schrandere Scholier... - 15 - Meteoor... - 21 - Dit werk is gelicenseerd onder een Creative Commons Naamsvermelding NietCommercieel GelijkDelen 3.0 Unported licentie De afbeelding op het voorblad is verkregen via INFOwrs. Copyright 2010 INFOwrs Serviços em informatica. - 1 -
Mollen Meppen Opgave 4.2 De mol wordt iedere keer dat je erop klikt 50 pixels naar rechts (X+50) en 50 pixels naar beneden (Y+50) verplaatst. Dit wordt gerealiseerd door de instructies die in de afbeelding hierna zijn omrand. Hierbij wordt rekening gehouden met de breedte en de hoogte van het canvas en de breedte en hoogte van de mol sprite (sprmol). Hiervoor wordt het modulo of blok gebruikt. Hierbij moet je er rekening mee houden dat de oorsprong van het canvas en de sprite in de linkerbovenhoek liggen en aangeduid worden door de coördinaten (0,0). Dit alles wordt gerealiseerd door de instructies die in de afbeelding hierna zijn omrand. Opgave 4.3 Een voor de hand liggende oplossing is de vaste waarden van 50 vervangen door willekeurige waarden. We kunnen een willekeurige waarde genereren met het random integer blok. Bij dit blok moeten we een onder- en bovengrens opgeven. Hierbij zou je bijvoorbeeld de getallen 25 en 75 kunnen gebruiken. Dit alles wordt gerealiseerd door de instructies die in de afbeelding hierna zijn omrand. Dit is een oplossing maar misschien niet de meest handige. Wat we ook kunnen doen is direct een positie in het canvas genereren. Dit kun je als volgt doen. - 2 -
Dit brengt de sprite van de mol heel dicht bij de randen van het canvas. Daarom is het mooier om een rand van bijvoorbeeld 5 pixels in te bouwen als volgt. Maar natuurlijk kun je ook een rand van 10 pixels nemen. Opgave 4.4 & 4.5 Geluid kun je toevoegen in het Media gedeelte van het "Designer" scherm of the "Blocks Editor". Dit gedeelte is hierna afgebeeld. Als je op Upload File... klikt kun je het geluid aan je project toevoegen en krijg je wat je in de afbeelding hierna ziet. - 3 -
Vervolgens kun je het toegevoegde geluid gebruiken. Hiervoor moet je in het "Designer" scherm bij de Media categorie in het Palette zijn. Hierin zit de Sound component zoals hierna afgebeeld. Je ziet deze component bij de Non-visible components. Dit is op zich logisch want geluid kun je horen maar niet echt zien. Dit ziet er als volgt uit. Sound1 is niet echt een zinvolle naam. In het Components gedeelte kun je er een nieuwe naam aan geven, bijvoorbeeld SoundGeraakt. Dat ziet er dan als volgt uit. - 4 -
Vervolgens kun je het eerder toegevoegde MP3 bestand in het Properties gedeelte toevoegen als je de SoundGeraakt component geselecteerd hebt. Dat ziet er dan als volgt uit. Nu we alles in het "Designer" scherm hebben geregeld kunnen we weer gaan programmeren in de "Blocks Editor". Ons toegevoegd geluid vinden we bij de Screen blokken zoals je hierna ziet afgebeeld. - 5 -
Als we de mol raken willen het geluid afspelen. Dat doen we door het call Sound- Geraakt.Play blok te gebruiken binnen het when sprmol.touched blok. Hierna is afgebeeld hoe je dat moet doen. Je kunt ook de blokken call SoundGeraakt.Play en to verplaatsmol omdraaien, dan klinkt het geluid meer synchroon met het verplaatsen van de sprite. Opgave 4.6 De Clock component is ook een onzichtbare component net als de Sound component. De Clock vind je in de Sensors categorie in het Palette. Standaard heet deze component Clock1. Ook dat is weer niet zo'n zinvolle naam, een betere naam is bijvoorbeeld MolClock omdat we de klok gaan gebruiken om de mol te laten bewegen. Dat ziet er als volgt uit. - 6 -
Figuur 1: de MolClock component en zijn properties Opgave 4.7 Net zoals SoundGeraakt staat MolClock in de "Blocks Editor" bij de Screen blokken zoals je hierna ziet afgebeeld. - 7 -
In Figuur 1 bij de Properties zie je een eigenschap genaamd "TimerInterval". Deze staat op 1000. Dat wil zeggen dat het interval waarmee de klok een signaal (event) afgeeft 1000 milliseconde oftewel 1 seconde is. Deze waarde is voorlopig goed genoeg. Bij de MolClock blokken groep is een block dat when MolClock.Timer heet. Dit is het blok dat het event van de klok opvangt. Dit event treedt nu dus elke seconde op. In plaats van to verplaatsmol aanroepen vanuit when sprmol.touched gaan we deze procedure nu aanroepen vanuit when MolClock.Timer. Dat ziet er als volgt uit. Hier zie je dat het handig was om een aparte procedure te maken voor to verplaatsmol, we hoeven nu maar één block te verslepen. Opgave 4.8 Horizontal Arrangements zitten in het Layout Palette en Labels zitten in het User Interface Palette van je "Designer" scherm. Je moet een nieuw horizontal arrangement aanmaken met een zinvolle naam. Noem de labels LabelGemistTekst en LabelGemistTeller. De tekst die je in de app gaat zien kun je aanpassen bij de Properties van een label in het vakje Text. Het Viewer gedeelte ziet er dan als volgt uit. - 8 -
De Components en Properties gedeeltes zien er dan als volgt uit. en Dan komt nu het programmeren in de "Blocks Editor". Hier wordt het iets moeilijker. Allereerst moet je bedenken hoe je kunt detecteren dat je de mol mist. Hiervoor kun je kijken of het canvas geraakt wordt. Dat kan in ons geval via het block when CanvasVeld.Touched. Het probleem is alleen dat als je op de mol klikt, je ook op het canvas klikt en dat daarom het block when CanvasVeld.Touched ook reageert. Daar moet je dus iets slims voor bedenken. Gelukkig hebben we de beschikking over een when CanvasVeld.Touched blok, waarin we kunnen zien of de sprite in het canvas geraakt wordt. Het when sprmol.touched blok hebben we nu niet meer nodig. Een oplossing zie je in de volgende afbeelding. - 9 -
De x, y en touchedsprite in when CanvasVeld.Touched doen het volgende. Wanneer het canvas aangeraakt wordt, dan krijg je via x en y te zien op welke x (dus horizontale) en y (dus verticale) coördinaat het canvas geraakt wordt. Via touchedsprite krijg je te zien of er een sprite aangeraakt wordt op het plek waar het canvas geraakt wordt. Als er inderdaad een sprite geraakt wordt, dan komt er in touchedsprite de waarde true te staan. Om het onderscheid te maken tussen of de sprite wel of niet wordt geraakt hebben we een if-then-else blok nodig. Dit blok vind je bij de Built-in blokken in de categorie Control. Het if-then-else blok vind je niet standaard tussen de blokken. Je moet het zelf bouwen van een if-then blok. Dat doe je als volgt. Je sleept een if-then blok in de "Blocks Editor" en klikt op het blauwe wieltje in het blok, zoals je ziet afgebeeld in de volgende afbeeldingen. en - 10 -
Vervolgens moet je de else van links naar rechts in de if slepen. Je krijgt dan wat je in de volgende afbeelding ziet. Als (if) de sprite wel wordt geraakt dan (then) moeten we de blokken die voorheen bij when sprmol.touched stonden uitvoeren, anders (else) moeten we de waarde van de gemist teller met 1 ophogen. Zoals gezegd heb je het when sprmol.touched blok nu niet meer nodig. Opgave 4.9 Een horizontal arrangement met labels toevoegen zou je intussen zelf moeten kunnen. Dat zou er dan als volgt uit moeten zien. - 11 -
Verder hoef je alleen de code in het when CanvasVeld.Touched blok uit te breiden om de score bij te houden. Dat ziet er als volgt uit. Opgave 4.10 De score kan alleen veranderen als het canvas geraakt wordt. Dat is daarom de plaats waar we moeten controleren wat de score is. Omdat de score ook naar beneden kan gaan, moeten we zelf beslissen wat we doen als de score bijvoorbeeld boven de 50 is geweest en er daarna weer onder zakt. De makkelijkste oplossing is dat de snelheid ook weer omlaag kan. Om dat te realiseren moet je de snelheid na het if-then-else blok aanpassen, omdat in dat blok de TimerInterval property van de MolClock component wordt aangepast. Dat ziet er als volgt uit. - 12 -
Via het quotient blok kunnen we de uitkomst van een deling zonder decimalen krijgen. Deze uitkomst keer het getal 50 (van 50 milliseconde) is de hoeveelheid tijd die we af moeten trekken van het initiële timer interval dat we op 1000 hebben gezet. In de oplossing hiervoor versnellen we de mol telkens als de score een veelvoud van 10 is. In de opgave staat dat we een veelvoud van 50 moeten gebruiken, maar met het getal 10 is het sneller te testen. Eigenlijk is het niet netjes in de oplossing de waarde 1000 zomaar te gebruiken. Als we nu namelijk de beginwaarde voor de TimerInterval property willen veranderen dan moeten we dat op twee plaatsen doen. Daarom is de volgende oplossing netter. We hebben hier een globale variabele gemaakt waarin we de initiële waarde van het timer interval zetten. Deze kunnen we vervolgens gebruiken om het de Timer- - 13 -
Interval property van de MolClock component een beginwaarde te geven en in plaats van de waarde 1000. Als we nu met de waarde 2000 willen beginnen hoeven we dat maar op één plaats te veranderen. Het Screen1.Initialize blok wordt één keer aangeroepen op het moment dat dat scherm (dus Screen1) actief wordt binnen de app. Nu moeten we nog zorgen dat de mol nooit sneller kan bewegen dan bijvoorbeeld de helft van het initiële timer interval. Dat kunnen we als volgt doen. Door het maximum met InitTimerInterval / 2 te gebruiken kan het timer interval nooit lager worden dan de waarde daarvan. Ook hier heb je weer voordeel van het aanmaken van de InitTimerInterval variabele. - 14 -
Schrandere Scholier Opgave 5.1 Volg de aanwijzingen goed op. Je Components gedeelte zou er dan als volgt uit moeten zien. Opgave 5.2 Volg de aanwijzingen op. Je Components gedeelte zou er dan als volgt uit moeten zien. Opgave 5.3 Volg de aanwijzingen op en je krijgt het volgende. - 15 -
Opgave 5.4 Opgave 5.5 In het "Designer" scherm zie je nu als het goed is het volgende. In de "Blocks Editor" zie je nu als het goed is het volgende. Je moet nu 40 (5 x 8) als vaste waarde gebruiken en zorgen dat je via het blauwe wieltje een extra getal aan de optelling kunt toevoegen. Opgave 5.6 In het "Designer" scherm zie je nu als het goed is het volgende. - 16 -
Opgave 5.7 Volg de aanwijzingen op. De dingen die je op zouden moeten vallen zijn: Wanneer je op de knop drukt, dan verdwijnt de inhoud van de textbox niet en dat is irritant. De opmaak van de afgebeelde lijst cijfers is niet echt mooi. Wanneer je niks invult in de textbox dan wordt er toch iets aan de lijst toegevoegd. Opgave 5.8 Volg de aanwijzingen op. Voor we beginnen met de ingevoerde cijfers aan somvancijfers toe te voegen moeten we deze variabele eerst initialiseren (een beginwaarde geven) op 0. Als we dat niet doen dan blijft somvancijfers maar groeien. Met het length of list blok halen we de huidige lengte van een lijst op. In ons geval de lijst met cijfers. We tellen daar nog 1 bij op omdat we het volgende cijfer moeten bepalen, dus we hebben voor de berekening één cijfer meer dan het aantal cijfers in de lijst. Opgave 5.9 Het "Designer" scherm kan er dan als volgt uitzien. - 17 -
En je moet dan het volgende stuk code toevoegen in de "Blocks Editor". Dit stuk code laten we niet steeds zien in de oplossingen van de opgaves die hierna nog komen. Opgave 5.10 De volgende oplossing is de meest makkelijke, maar niet de beste. - 18 -
De procedure berekentebehalencijfer doet namelijk meer dan alleen rekenen. Het laat ook het resultaat in de gebruikersinterface zien en dat is niet netjes. We zeggen dan dat de procedure een side effect (een bijeffect) heeft. We moeten daarom eigenlijk een procedure met resultaat gebruiken zoals je kunt zien in de volgende oplossing. Opgave 5.11 Dit zou makkelijk moeten zijn omdat je iets soortgelijks al hebt gedaan in opgave 5.9. - 19 -
Opgave 5.12 Het "Designer" scherm kan er dan als volgt uitzien. Er is hier besloten om de foutmelding met een horizontal arrangement achter de textbox te zetten. De code zou je dan als volgt aan moeten passen. - 20 -
Meteoor Opgave 6.3 Opgave 6.4 Opgave 6.5 Deze oplossing doet telkens als het event optreedt veel berekening. De uitkomst van CanvasVeld.Width - sprraket.width is altijd hetzelfde. Het is daarom handig - 21 -
om deze niet in het when OrientationSensor1.OrientationChanged blok uit te rekenen, maar in een globale variabele. Dat zie je in de volgende oplossing. Het zou makkelijker zijn geweest om CanvasVeld.Width - sprraket.width te doen bij het initialize global blok, maar dat mag niet van App Inventor 2, dus moet je het in het when Screen1.Initialize blok doen. Opgave 6.6 Opgave 6.7 Doe wat er staat. - 22 -
Opgave 6.8 Opgave 6.9 Opgave 6.10 Opgave 6.11-23 -
Opgave 6.12-24 -