Les på det språket du foretrekker:
Et kurs av Eirik Vågeskar, med hjelp fra Johannes Moskvil, Brede Kristensen, Marcus Goplen, Arve Seljebu og flere kolleger i Knowit Objectnet.
Svelte er et språk som brukes til å skrive enkeltstående nettsider. Man kan også bruke det til å skrive komponenter som man legger inn på eksisterende nettsider (selv om nettsiden er skrevet på et annet språk enn Svelte).
Sveltes hjemmeside presenterer det på følgende måte
Svelte er en radikal ny tilnærming til å lage brukergrensesnitt. Mens tradisjonelle rammeverk som React og Vue gjør storparten av arbeidet sitt i nettleseren, flytter Svelte det til et kompileringssteg som finner sted når man bygger en app.
I stedet for å bruke teknikker som virtuell-dom-sammenligning, skriver Svelte kode som oppdaterer domen med kirurgisk presisjon når tilstanden i appen endrer seg.
Vi er stolte over at Svelte nylig ble stemt frem som det best likte rammeverket med de mest fornøyde utviklerne i to store undersøkelser blant programvareutviklere. Vi tror du også vil like det svært godt. Les bloggposten som introduserte Svelte versjon 3 for å lære mer.
Ifølge flere sammenlignende tester blir en applikasjon mindre om man skriver den i Svelte enn i React eller Vue. De følgende sitatene og bildene er fra A RealWorld Comparison of Front-End Frameworks with Benchmarks (2019 update):
… The smaller the file, the faster the download, and less to parse.
… Svelte — The magical disappearing UI framework — really holds true to its punch line.
… This shows how succinct given library/framework/language is. How many lines of code do you need to implement almost the same app (some of them have a bit more belts and whistles) accordingly to the specification.
… If you care about you LoC you should check out ClojureScript, AppRun, and Svelte.
SvelteKit gjør prosjekter med mange filer skrevet i Svelte om til webapplikasjoner med høy ytelse
, for å sitere Hva er SvelteKit?
-delen av SvelteKit-dokumentasjonen. Hvis du har litt erfaring med webutvkling (null stress hvis du ikke har det) så er SvelteKit for Svelte det Next.js er for React og Nuxt.js er for Vue.
Å bygge en app som følger alle kunstens regler i dag er djevelsk komplisert. Deriblant finner vi byggoptimaliseringer, slik at du kan laste inn så lite kode som mulig; bruk uten nettilkobling; forhåndsinnlasting av sider før brukeren trykker på siden; og mulighet for å konfigurere sideopptegningen slik at du kan bestemme om appen skal tegnes på tjeneren eller i nettleseren idet appen kjører eller idet den bygges. SvelteKit gjør alle de kjedelige oppgavene for deg slik at du kan konsentrere deg om de kreative.
Denne workshoppen veklegger å lære bort Svelte. Du vil også få med deg grunnleggende SvelteKit på veien.
Vår erfaring er at både Svelte og SvelteKit har en hang til å forsvinne i bakgrunnen så snart du blir vant med dem. Kanskje vil du si deg enig med oss i at å bruke Svelte og SvelteKit føles mer som å fjerne hindre fra eksisterende webteknologier heller enn å legge til noe.
Hvis webutvikling er nytt for deg, lurer du kanskje på hvorfor verktøy som SvelteKit og de andre vi har nevnt trengs. Det korte svaret er for å holde konstnadene nede.
Å skrive et tradisjonelt, statisk nettområde kan være så enkelt som å lage en HTML-fil for hver enkelt side og laste dem opp på en tjener. En webapp (eller webapplikasjon, om du vil) er en samling interaktive nettsider (i motsetning til statiske). I en webapplikasjon kan sidene se annerledes ut avhengig av hva slags data som er lagret på tjeneren og de handlingene som brukeren har foretatt seg på det daværende tidspunktet. For eksempel kan en side se annerledes ut basert på:
- hva en bruker har foretatt seg på tidligere sider
- hvorvidt brukeren har logget seg inn
- toppskårene som andre brukere har sendt inn til en toppliste (ja, det var et frempek)
Å lage en webapplikasjon er vanskeligere enn å lage et nettområde: Sider kan ikke lagres som statiske filer; de må lages fortløpende. Å se på en side krever at tjeneren og maskinen som brukeren ser på siden med utfører ekstraarbeid for å tegne opp den endrede siden.
Å lage en ny side og laste den ned har bokstavelig talt sin pris:
- Tjeneren og brukerens maskin bruker strøm på å regne seg frem til den nye nettsiden. Strøm er penger.
- De som eier tjeneren betaler for dataen den sender ut. De fleste bruker en telefon til å surfe på nettet, ofte med en begrenset mobildataplan. Data er penger.
- Brukeren bruker tiden sin på å vente på siden. Brukere pleier å forlate trege applikasjoner, som gjør at de som lager webapplikasjonen tjener mindre penger. Penger er penger.
Webutviklere kan ta grep for å få ned disse kostnadene. Dessverre krever dette tid. Tid er penger.
- node
- En tekstbehandler, fortrinnsvis en der man kan installere støtte for Svelte.
- En klone av Vages/svelte-snake-workshop
Hvis du trenger hjelp til å installere ting, kan du sjekke SETUP.md.
Repoet Vages/svelte-snake-workshop inneholder alt du trenger. Du kan bestemme tempo selv. Det er mulig å fullføre kurset helt på egen hånd.
Når vi holder kurset fysisk eller digitalt, pleier kursholderne å gå gjennom oppgaver og spørsmål i fellesskap med ujevne mellomrom. Du kan be om hjelp fra kursholderne når som helst.
Vi har laget så å si all styling på forhånd, slik at man kan bruke mest mulig tid på kode.
Vi har delt kurset i 6 deler, hver bestående av flere oppgaver. Hver oppgave starter med oppgavetekst, som av og til blir fulgt av hint. Du kan la være å lese hintene dersom du trenger en ekstra utfordring
Hver oppgave har en tilhørende mappe: src/routes/tasks/X.Y
der X
angir kursdelen og Y
angir oppgaven innad i delen. For eksempel inneholder mappen src/routes/tasks/2.1
første oppgave i del to.
Hver oppgavemappe inneholder to undermapper: problem
og solution
. Mappen problem
inneholder den uferdige koden. Mappen solution
inneholder løsningen på oppgaven.
SvelteKit gjør en fil innenfor mappen src/routes
og dennes undermapper om til en nettside dersom, og bare dersom, filen heter +page.svelte
. Filer som starter med andre tegn enn +
(for eksempel mine-funksjoner.js
og MinKomponent.svelte
) brukes til å lagre gjenbrukbare funksjoner og komponenter som vi kan bygge nettsider med. SvelteKit importerer elementer fra slike filer dersom en +page.svelte
-fil ber om det, men gjør dem ikke om til nettsider.
Hva man skriver inn i nettleseren sin for å se resultatet av en gitt +page.svelte
-fil avhenger av navnene på mappene som følger src/routes
før man finner filen. Noen eksempler:
Filplassering | URL mens man utvikler | URL når man gir ut appen |
---|---|---|
src/routes/+page.svelte |
http://localhost:5173 | https://svelte-snake-workshop.vercel.app |
src/routes/finished-game/+page.svelte |
http://localhost:5173/finished-game | https://svelte-snake-workshop.vercel.app/finished-game |
src/routes/tasks/1.1/problem/+page.svelte |
http://localhost:5173/tasks/1.1/problem | https://svelte-snake-workshop.vercel.app/tasks/1.1/problem |
Hvis du vil vite mer om hvordan filnavn konverteres til ruter, sjekk Svelte kit-dokumentasjonen for ruting.
SvelteKit behandler noen filer annerledes dersom navnet deres starter med +
, for eksempel:
- Filer som heter
+layout.svelte
påfører en utforming (layout) på+page.svelte
-filene i mappen den befinner seg i og dennes undermapper.- Filen
src/routes/+layout.svelte
legger til en bunntekst og dokumenttittel på alle sider i dette prosjektet, så vel som overskrifter på oppgavesidene.
- Filen
- Filer som heter
+server.js
file gjøres om til ressurser som du kan samhandle med ved hjelp av HTTP.- Filen
src/routes/api/scores/+server.js
oppretter en enkel high score database med et API.
- Filen
- Filer som heter
+page.js
brukes til å gjøre valg for hvordan en+page.svelte
-fil skal tegnes opp og å hente data for å tegne den opp.- Filen
src/routes/+page.js
ber SvelteKit om å forhåndsopptegne forsiden.
- Filen
Du trenger ikke å skrive slike filer selv i dette kurset.
Når du er ferdig med denne delen, skal spillet vise hvor slangen og eplet er på brettet.
Svelte er en sammensmeltning av HTML, CSS og Javascript med noen forbedringer. I Svelte kan man skrive disse tre språkene i én og samme fil. Delene kalles for «script», «template» og «styling».
<!-- script -->
<script>
let answer = 42;
let color = "red";
</script>
<!-- template -->
<div style="color: {color}">
Hello world, svaret er {answer}
</div>
<!-- styling -->
<style>
div {
font-weight: bold;
}
</style>
Merk: Du kan kjøre det foregående eksempelet og de fleste eksemplene i dette dokumentet ved å lime inn kildekoden i Svelte REPL-en. Du kan lagre dem og dele dem med hvem som helst ved hjelp av en URL, slik som her: https://svelte.dev/repl/8376ae2d58464f76bb13f9d511f6f81f
Man bruker krøllparenteser inni template for å sette inn variabler, utregninger og funksjonskall.
<script>
let answer = 42;
</script>
<div>Meningen med livet er {a}.</div>
<div>Kvadratet av meningen er {a * a}</div>
<div>Meninngen med livet har fortegnet {Math.sign(a)}</div>
Løs oppgaven fra Svelte-opplæringen om å sette inn data før du går videre.
Åpne filen src/routes/tasks/1.1/problem/+page.svelte
.
Brettet inneholder en <div class="apple" />
. Variabelen apple
inneholder en koordinat. Oppgaven din er å plassere eplet på den ruten på brettet som koordinaten angir.
Brettets X-akse peker mot høyre, og Y-aksen peker nedover. Konstanten CELL_SIZE
inneholder sidelengden til hver rute.
Når du er ferdig, skal det se slik ut:
For å overstyre og legge til stil på elementer i HTML (ikke bare Svelte), kan man bruke attributtet style
. Inni style skriver man CSS-utsagn.
<div style="font-weight: bold;">Fet skrift</div>
Bruk CSS-egenskapene left
og top
for å forskyve elementer langs henholdsvis x
- og y
-aksene.
<div style="top: 20px; left: 10px;">Flyttet</div>
For å plassere eplet, må du gjøre omtrent som følger:
<div class="apple" style="left: {regnestykke1}px; top: {regnestykke2}px;" />
Du må benytte deg av apple.x
og apple.y
samt CELL_SIZE
for å få til disse regnestykkene.
Neste oppgave kommer til å kreve en each-blokk.
Løs denne oppgaven fra Svelte-opplæringen for å lære hvordan each-blokker fungerer.
Oppgaven din er å tegne slangen på brettet.
Slangen er en samling koordinater som ligger i variabelen snake
. Det første elementet er hodet. Tegn hver koordinat i kroppen som en <div class="body-part" />
.
Slangen skal se slik ut når du er ferdig:
Vi bruker utregningen (left: {foo.x * CELL_SIZE}px; top: {foo.y * CELL_SIZE}px
) flere ganger i koden. Koden blir lettere å vedlikeholde dersom vi legger denne utregningen ett sted.
Oppgaven din er å flytte den nevnte utregningen over i en funksjon, calculatePositionAsStyle(coordinate)
, og erstatte alle tilfeller der vi bruker utregningen med et kall til denne funksjonen. Funksjonen skal ta inn en koordinat og gi tilbake en streng med verdier for top og left.
Når du er ferdig med denne delen, skal det gå an å styre slangen med piltastene.
Løs følgende oppgaver fra Svelte-opplæringen før du går videre:
Oppgaven din er å lytte etter trykk på tastaturet og sende dem videre til funksjonen console.log
. Applikasjonen skal kunne «høre» tastetrykk uansett hvilken del av nettsiden som har fokus, slik at brukeren ikke skal måtte trykke på et spesifikt element på siden for at spillet skal registrere tastetrykkene.
Unngå å lytte på tastetrykk fra hele vinduet (svelte:window
viser til vinduet i sin helhet). Legg heller til en lytter på det Svelte-spesifikke elementet som viser til document.body
.
Tastetrykk-hendelsen heter keydown
. I Svelte lytter man etter den med on:keydown
.
Man lytter til document.body
ved å bruke elementet <svelte:body />
. Man kan lytte etter hendelser på det som med et hvilket som helst HTML-element.
Du kommer til å måtte vite hvordan du endrer variabler i den kommende seksjonen. Gjør følgende oppgaver fra Svelte-opplæringen før du fortsetter:
I den neste oppgaven blir du bedt om å importere fra en fil som befinner seg i src/lib
ved å bruke $lib
. For å sitere SvelteKit-dokumentasjonen om $lib
:
Dette er et enkelt alias til
src/lib
, eller hva enn slags mappe som er oppgitt som verdi forconfig.kit.files.lib
. Det lar deg bruke felleskomponenter og -moduler uten../../../../
-sludder.
Slik importerer du fra filer som finnes i src/lib
med aliaset:
// Importere en Javascript-funksjon fra filen src/lib/bar.js
import { foo } from "$lib/bar.js";
// Importere en Svelte-komponent fra filen src/lib/Baz.svelte
import Qux from "$lib/Qux.svelte";
Oppgaven din er å oversette tastetrykk til bevegelse. Slangen skal bevege seg ett steg i oppgitt retning hver gang man trykker på en piltast. Unngå at slangen beveger seg når man trykker på andre taster.
For å gjøre dette lettere, har vi laget en funksjon convertKeyboardKeyToDirection
i src/lib/game-helpers.js
, som oversetter fra tastetrykk til en retning. Vi bruker himmelretningene for å vise til retningene på brettet: Vest er venstre, nord er opp.
+page.svelte
importerer allerede en funksjon fra $lib/game-helpers.js
. For å bruke convertKeyboardKeyToDirection
, legger du til funksjonen blant de som er opplistet i det eksisterende import { … } from "$lib/game-helpers.js"
-utsagnet. Mange av funksjonene i game-helpers.js
er nyttige i denne såvel som senere oppgaver. Du kommer til å spare tid dersom du bruker et øyeblikk på å gjøre deg kjent med filens innhold.
Inntil videre skal slangen bevege seg også om den treffer seg selv eller en vegg. Game over kommer i en senere oppgave.
- Den enkleste måten å legge til elementer i starten eller slutten i et array, er å bruke spredning (spreading):
[a, ...b]
. (Svelte reagerer ikke på push og pop; dette kommer vi tilbake til senere.) - Funksjonen Array.prototype.slice er nyttig når man vil fjerne elementer fra starten og slutten av et array.
I $lib/game-helpers.js
finner man:
add(coordinateA, coordinateB)
, for å legge sammen to vektorer/koordinater.DIRECTION_TO_VECTOR
, for å gå fra himmelretning til retningsvektor.
Legg elementene DIRECTION_TO_VECTOR, add,
til de importerte elementene i utsagnet import { … } from "$lib/game-helpers.js"
på toppen av <script>
-blokken for å bruke dem.
Når du er ferdig med denne delen, skal spilleren få poeng når slangen spiser et eple. Spillet skal stoppe hvis slangen er på en ulovlig posisjon. Og spillklokka skal tikke, slik at slangen beveger seg på jevnlige tidspunkter, heller enn når man trykker på piltastene.
I regneark, som Microsoft Excel, kan man skrive formler i cellene, for eksempel =A1*B3
. Da havner resultatet av regnestykket i cellen, og resultatet oppdaterer seg automatisk når man endrer innholdet i cellene som regnestykket avhenger av. Slik er det vanligvis ikke i programmering: Man kan ikke si a = 2; b = a * 2; a = 8
og regne med at b
nå er 16 i stedet for 4 fordi det dobbelte av 8 er 16. Men du kan få det til i Svelte.
I Svelte kan vi få datamaskinen til å kjøre et utsagn (statement) på nytt som reaksjon på endringer. Dette gjør vi ved å sette et dollartegn foran utsagnet. Utsagn som starter med et slikt dollartegn kalles for et reaktivt utsagn, fordi utsagnet kjøres på nytt som en reaksjon på noe annet.
Hvis utsagnet inneholder en tilegning til en variabel, kan Svelte holde verdien oppdatert for oss.
<script>
let b = 3;
let c = 4;
$: a = (b * c) / 2; // a === 6
b = 6;
</script>
<div>
<!--
Uten `$: …`, ville a hatt verdien 6,
men den får automatisk verdien 12 idet
b får en ny verdi.
-->
Trekantens grunnlinje er {b}, dens høyde er {c}, og arealet dens er {a}.
</div>
Løs oppgaven om reaktive utsagn fra Svelte-opplæringen før du går videre.
Nesten et hvilket som helst utsagn kan stå etter dollartegnet, ikke bare utregninger. Man kan også skrive funksjonskall og if-setninger:
<script>
let lastUserInput = "";
$: if (lastUserInput === "hello") {
// Åpne konsollen for å se denne beskjeden
console.log("hello to you too");
}
</script>
<label>Skriv noe: <input bind:value={lastUserInput} /></label>
<script>
let lastUserInput = "";
// Det brukeren sa, som om en papegøye gjentok det
$: parrotOutput = parrot(lastUserInput);
function parrot(something) {
return something + ", sqawk!";
}
</script>
<label>Si noe: <input bind:value={lastUserInput} /></label>
<div>
Papegøyen sier: {parrotOutput}
</div>
Et reaktivt utsagn kjøres én gang når appen lastes inn. Svelte kjører utsagnet på nytt hver gang en variabel som brukes inni utsagnet får en ny verdi. Svelte finner automatisk ut hvilke verdier et reaktivt utsagn avhenger av. Man trenger ikke oppgi avhengighetene selv, slik som med for eksempel React.useEffect
.
Merk: Svelte merker bare endringer som kommer som følge av man bruker tilegnelsesoperatoren, =
(for eksempel foo.bar = "baz"
), og ikke som følge av metodekall (som .push
og .pop
). Se opplæringsoppgaven om reaktivitet med objekter og arrays for en dypere forklaring.
Når man skriver spill-logikk, kan man ofte oversette regler nesten direkte til reaktive utsagn: «Hvis x === foo
, så gjør a, b og c» blir til $: if (x === foo) { a(); b(); c(); }
.
Oppgaven din er å skrive et reaktivt utsagn med en if-setning slik at når slangehodet er på samme koordinat som eplet, øker antallet poeng med 1.
Lag en variabel score
. Dette er antallet epler slangen har spist.
Når du har poeng-økningen til å virke, kan du sørge for at eplet får en ny, tilfeldig plassering på brettet idet slangen spiser det.
Merk: I denne oppgaven sparer du mye arbeid ved å bruke hjelpefunksjoner fra game-helpers.js
.
I game-helpers.js
finner man funksjonen isEqual
som sier om to koordinater er like, og funksjonen pickRandomOpenSpace
, som trekker en passelig plassering for det nye eplet.
Oppgaven din er å få slangen til å vokse etter at den har spist et eple.
For å gjøre det lettere for deg, har vi trukket ut logikken for å regne ut neste slange som funksjonen getNextSnake(snake, direction, ?shouldGrow)
. shouldGrow
er et valgfritt tredje argument, og er en boolsk.
For å løse den kommende oppgaven, kommer du til å måtte kunne det du lærer av følgende oppgaver i Svelte-opplæringen:
- Oppgaven om
onMount
- Oppgaven om
onDestroy
(som inneholder litt omsetInterval
)
Oppgaven din er å få slangen til bevege seg ved faste tidsintervaller i stedet for idet man trykker på piltaster. Når tiden for å bevege seg er inne, skal slangen bevege seg i den retningen som spilleren sist oppga. I demoversjonen av spillet er tidsintervallet 100 ms, men du kan endre dette om du vil.
Når slangen treffer seg selv eller en vegg, er det game over.
Oppgaven din er å innføre game over ved å stoppe spillklokka dersom en av de nevnte tilstandene inntreffer. Spillet skal stoppe som en reaksjon på at slangen har beveget seg, og ikke som en del av moveSnake
.
For å stoppe tikkingen, har vi trukket ut en funksjon stopTicking
som du kan bruke.
I game-helpers.js
finner man de nyttige funksjonene isInsideBoard
og isSnakeEatingItself
.
Husk reaktivitet og if-setninger, $: if (x) { … }
, og hvordan man nesten ordrett kan oversette spill-logikk til slike.
Hvis vi skulle formulert reglene for game over muntlig, hadde vi sagt noe slikt som:
- «Hvis slangehodet er utenfor brettet eller inni slangen selv, er det game over»
- «Hvis spillet er slutt, stopper tikkingen.»
Idet du har fått game over til å virke, kommer du kanskje til å oppdage et problem: Slangen dør når man trykker tasten som går i motsatt retning av der slangen beveger seg for øyeblikket, fordi den spiser sin egen hals. Dette kan også skje når man er litt rask idet man prøver å ta en U-sving. I denne og den neste oppgaven skal vi prøve å unngå dette.
Oppgaven din er å sørge for at slangen kun reagerer på tastetrykk som er vinkelrette på slangens nåværende retning. Hvis slangen går nordover, skal spillet bare registrere tastetrykk på venstre og høyre piltast. Som med mange andre oppgaver, finnes det en funksjon som kan hjelpe deg i game-helpers.js
.
Dette er en utfordringsoppgave som har mer å gjøre med programmering enn Svelte i seg selv. Du kan hoppe til neste oppgave hvis du ønsker.
I løsningen på oppgave 3.5 som man finner i tasks/3.5-end
, kan man fortsatt fremprovosere at slangen spiser seg selv hvis man er rask. Hvis slangen for eksempel beveger seg nordover og spilleren raskt trykker ⬅️ fulgt av ⬇️, ender spillet opp med å registrere ⬇️ som neste bevegelse.
Vi kan unngå problemet ved å bruke en kø til å ta vare på retningene som slangen skal bevege seg i. Når slangen skal bevege seg, henter vi neste planlagte retning og beveger slangen i den. Dette gjør det mulig å trykke inn avanserte bevegelser raskt uten å tenke på timing.
Vi har laget variabelen headDirectionQueue
, et array som holder styr på retningene brukeren har planlagt at slangen skal bevege seg i. I stedet for å legge neste planlagte retning rett i headDirection
, skal du legge retningen sist i headDirectionQueue
. Når tiden for at slangen skal bevege seg er inne, skal programmet bruke den første vinkelrette retningen i køen som ny verdi for headDirection
. Med andre ord: Fjern alle ikke-vinkelrette bevegelser fra starten av køen frem til du finner en vinkelrett bevegelse. Bruk denne som neste headDirection
og la påfølgende bevegelser bli liggende i køen som de er.
Gjør de endringene som trengs i moveSnake
og handleKeydown
.
Når du er ferdig med denne delen, skal spillet ha en animert slange, hodeskalle og epler.
I Svelte følger modulen svelte/transition
med. Den gjør at man kan animere et element som dukker opp i eller forsvinner fra dokumentet.
- transition-attributtet
- Hvordan man kan legge parametere på overganger
- Forskjellige overganger for inn og ut
Oppgaven din er å få det nye eplet til å sprette opp på plassen sin når slangen spiser det forrige eplet.
For å få til dette skal du importere overgangen scale
fra svelte/transition
og legge den på riktig element. For å begrense animasjonen til når eplet dukker opp, skal du bruke in:
i stedet for transition:
. (Du kan også prøve andre overganger.)
Vanligvis pleier Svelte bare å animere elementer når de dukker opp i eller forsvinner fra dokumentet. Man kan fortelle Svelte at elementet skal animeres på nytt når en verdi endrer seg ved å bruke en key-blokk: {#key <verdi>}<innhold>{/key}
. Da vil Svelte animere innhold
på nytt når verdi
endrer seg.
I stylingen finnes det en klasse skull
. Oppgaven din er å få en <div/>
med klassen skull
til å dukke opp når slangen dør. Den skal ha samme koordinat som slangehodet.
For å animere hodeskallen, legg på en transition:scale
med en forsinkelse på 300 ms.
I style-blokken finnes det en klasse head
. Denne sørger for styling og animasjon av slangehodet så lenge man legger den på et element med klassen body-part
. Oppgaven din er å legge inn et animert slangehode ved hjelp av denne klassen.
Du trenger ikke å bruke noen transition:…
her. Stylingen tar seg av animasjonen så lenge du legger riktig klasse på rett sted.
Oppgaven din er å animere halen. Det finnes en klasse, tail
, som man kan legge på et element for å få den samme gli-animasjonen som for hodet, men uten å forstørre kroppsdelen.
Legg til en animert hale på slangen.
Advarsel: Halen kommer til å blinke litt i alle nettlesere utenom Firefox (deriblant Chrome og Safari) på grunn av en bug i layout-motoren. Du kan regne oppgaven som ferdig når du har en animert hale som blinker av og til. Fasiten inneholder et triks som fjerner blinkingen. Vi kan dessverre ikke fortelle hva trikset er, fordi det ville avslørt løsningen på hovedoppgaven.
Når du er ferdig med denne delen, skal spillet ha en game-over-skjerm med toppliste hentet fra en tjener. På skjermen skal man også kunne registrere navnet sitt og sende det til tjeneren sammen med siste poengsum.
Gjør følgende oppgaver fra Svelte-opplæringen:
Filen GameOver.svelte
ligger klar i samme mappe som +page.svelte
. Oppgaven din er å sørge for at komponenten vises på skjermen når spillet er over og at den viser poengsummen som spilleren fikk.
Det er litt knotete å få komponenten til å vises på skjermen på en elegant måte. Derfor har vi lagt inn noen div-er nederst i template-delen av +page.svelte
der man kan montere <GameOver>
-komponenten.
+page.svelte
er blitt litt overveldende. Den tar seg av to ting på én gang: å holde styr på spillet og vise det frem. Vi kan gjøre filen lettere å lese ved å la en annen komponent ta seg av å vise frem spillet.
Oppgaven din er å lage en fil kalt Board.svelte
inni src/routes/tasks/5.2/problem
. Trekk ut koden som har ansvar for å vise frem brettet, eplet og slangen i +page.svelte
(fra både script-, styling- og template-delene). Bestem hvilke data som skal kopieres og hvilke som skal sendes som egenskaper (properties).
Importer og monter den nye komponenten i +page.svelte
, slik at den erstatter koden som tidligere pleide å vise frem spillet. Slett de ubrukte delene i style og script-blokkene
Du kan bruke kommandoen git restore
for å stille src/routes/tasks/5.2/problem/+page.svelte
tilbake til sin opprinnelige tilstand.
Åpne terminalen din og naviger til rotmappen i prosjektet. Lim inn kommandoen git restore src/routes/tasks/5.2/problem/+page.svelte
og trykk enter. Filen skal nå være slik den var da du begynte på oppgaven.
Denne oppgaven blir unødvendig vanskelig hvis du starter for dypt nedi HTML-elementene. Start så høyt oppe og så langt ute som det lar seg gjøre.
Dette hintet vil avsløre nesten alt. Les det kun hvis du står fullstendig fast.
Begynn med å kopiere <div class="board" … >
og innholdet den omslutter. Lim dem inn i Board.svelte
. Kopier hele <style>
-blokken fra +page.svelte
.
Tekstbehandleren din skal umiddelbart klage over hvilke data og funksjoner fra <script>
som mangler i Board.svelte
. Dataen eller funksjonene som fortsatt brukes i +page.svelte
må sendes inn som til Board
s egenskaper. Data og funksjoner som er ubrukt i +page.svelte
kan klippes ut og limes inn i <script>
-delen av Board
.
Importer Board
til +page.svelte
med import Board from "./Board.svelte". Monter komponenten der
<div class="board" … >` pleide å være. Send data til alle egenskapene du bestemte deg for.
Når du ser at ting virker, se på utdataen i terminalen der du startet npm run dev
. Denne utdataen sier deg hvilke deler av style som er ubrukt og i hvilke filer. Slett de delene som utdataen forteller deg at er ubrukt i filene som du har endret.
Advarsel: Oppgavene i denne delen er for folk som har erfaring med nettverkskall, løfter (promises) og lignende i Javascript. Om du synes oppgavene blir for vanskelige å løse, kan du hoppe til del 7.
Man bruker Javascript-løfter (promises på engelsk) til handlinger som kan ta tid og muligens kan mislykkes, ofte nettverksforespørsler. Svelte har en egen blokk for å ta seg av løfter, og denne heter await-blokken.
Løs oppgaven om await-blokker fra Svelte-opplæringen før du går videre.
SvelteKit-prosessen som kjøres under utvikling inneholder en liten i-minne-database som holder styr på en toppliste som man kan hente ut tidligere poengsummer fra og poste sin siste poengsum til.
Funksjonen fetchScores
fra src/lib/api-helpers.js
henter topplista. Oppgaven din er å importere denne funksjonen og vise topplista i «Game Over»-komponenten du har laget.
Dersom du ønsker å holde deg til samme visuelle tema som i resten av spillet, kan du sjekke dokumentasjonen for stilarket Nes.css (eller fasiten).
Advarsel: Akkurat når man jobber med løfter, kan navngitte funksjoner (de som er definert med nøkkelordet function
) oppføre seg rart. For å unngå bugs, bruk pilfunksjoner (altså const foo = () => {…}
).
Løs oppgaven om tekst-input og binding før du går videre.
Oppgaven din er å lage et felt der folk kan fylle inn navnet sitt. Lag også en knapp som folk kan trykke på for å sende inn navn og poengsum på formatet { name: string, score: number }
. Du kan bruke funksjonen postScore
fra api-helpers.js
til dette.
Når poengsummen er sendt inn, skal komponenten hente den oppdaterte topplisten.
Merk: Fordi databasen ikke lagres til noe permanent minne, vil alt man har lagt til i den forsvinne når man starter utviklingstjeneren på nytt. Hvis du ødelegger databasen ved å sende inn feilformatert data, kan du starte utviklingstjeneren på nytt for å starte med blanke ark.
Gratulerer! Du var veldig flink som leste gjennom oppgavesettet før du begynte! Eller kanskje du faktisk har gjort alle oppgavene? Wooooaaahh!!!!!1
Del 7 er en sandkasse der du kan gjøre omtrent hva du vil.
Det finnes fortsatt noen mulige forbedringer av spillet:
Følgende funksjoner har vi ikke selv prøvd å lage (ennå), men vi tror de er både løsbare – og gøyale:
- Hull i kantene: Hull i brettets kanter som gjør at man kan komme ut av et tilsvarende hull på den andre siden, som i Pacman.
- Hindre: Visse områder midt på brettet er umulige å gå gjennom – kall dem vegger, øyer eller hva som helst. De er som kanten av brettet: Slangen dør når den treffer et slikt område.
- Gullepler: Få gullepler til å dukke opp i ny og ne i tillegg til det vanlige eplet. Disse gir 5 ekstra poeng hvis man spiser dem innen en viss tid.
- Lydeffekter: Legg på lyder når slangen spiser eplet, når den dør og lignende. Husk å bruke hodetelefoner dersom du deler arbeidslokale med andre.
Hvis du ikke føler deg klar for å jobbe uten fasit ennå, kan du prøve deg på en oppgave du finner løsningen på i mappen src/routes/finished-game
.
Spillet som ligger i mappen src/routes/finished-game
har noen funksjoner som det ikke er laget oppgaver for:
- Pause
- Startskjerm
- Omstart-knapp på game-over-skjermen
Prøv å legge til disse funksjonene uten å se på koden i src/routes/finished-game
. Du kan bruke koden på siste oppgave som et utgangspunkt.
Kanskje du kan lage et av følgende spill:
Om man synes Svelte er gøy og vil lære mer, har vi følgende anbefalinger:
- Gjør hele Svelte-opplæringen
- Sjekk ut dokumentasjonen etterpå. Man kan nesten alt som står der etter opplæringen.
- Prøv ut SvelteKit, Sveltes motsvar til for eksempel Next.js og Nuxt.js.
- Ditt første prosjekt kan for eksempel være en hjemmeside fylt av alle spillene dine. Legg den ut i påvente av at «flash-spill» kommer på moten igjen.
Da gjenstår det kun å si at vi håper du har kost deg med kurset vårt. Game over!