{"id":3754,"date":"2018-12-11T13:13:58","date_gmt":"2018-12-11T12:13:58","guid":{"rendered":"https:\/\/moe.it.slotshaven.dk\/wp\/?p=3754"},"modified":"2018-12-11T13:13:58","modified_gmt":"2018-12-11T12:13:58","slug":"tegn-og-gaet-med-websockets","status":"publish","type":"post","link":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/tegn-og-gaet-med-websockets\/","title":{"rendered":"Tegn og g\u00e6t med websockets og node.js"},"content":{"rendered":"<p>I denne \u00f8velse skal vi fors\u00f8ge at g\u00f8re vores template til et lille spil &#8211; n\u00e6rmere bestemt tegnelegen &#8220;Tegn &amp; G\u00e6t&#8221;. Vi starter med en klient\/server template, der kun akkurat kan det mest n\u00f8dvendige.<\/p>\n<p><a href=\"https:\/\/minhaskamal.github.io\/DownGit\/#\/home?url=https:\/\/github.com\/simmoe\/digidaktik\/tree\/master\/sockets\/sockets_multiplayer_template\">Hent multiplayer server template her\u00a0<\/a><\/p>\n<div>\n<div>\n<div>2G INF: Hent midlertidig fremgang her:\u00a0<a href=\"https:\/\/moe.it.slotshaven.dk\/wp\/wp-content\/uploads\/2018\/12\/sockets_multiplayer_temp-2.zip\">sockets_multiplayer_temp<\/a><\/div>\n<\/div>\n<div><\/div>\n<h2>Fremgangsm\u00e5de trin for trin<\/h2>\n<p>Lad os f\u00f8rst teste applikationen i en lokal browser.<\/p>\n<p>Vi kan se at server konsollen registrerer at der kommer nye forbindelser og klienten forbinder<\/p>\n<p>Lad os f\u00f8rst s\u00f8rge for at klienter f\u00e5r deres eget socket.id at vide, n\u00e5r de forbinder sig:<\/p>\n<p>Send beskeden &#8220;yourId&#8221; fra serveren s\u00e5 snart en klient har forbundet:<\/p>\n<p>socket.emit(&#8216;yourId&#8217;, socket.id);<\/p>\n<p>Modtag beskeden hos klienten og gem den i en variabel<\/p>\n<div><\/div>\n<pre>socket.on('yourId', setId);\nfunction setId(id){\n    myId = id;\n}<\/pre>\n<div>Lad os s\u00e5 s\u00e6tte noget spilmekanik op p\u00e5 serveren. Vi vil lave et spil tegn og g\u00e6t.<\/div>\n<div>Vi skal bruge minimum tre klienter, et array med ord, et antal sekunder hver tur skal tage,<\/div>\n<div>og s\u00e5 skal vi holde styr p\u00e5 hvis tur det er til at tegne og hvis tur det er til at g\u00e6tte<\/div>\n<div>Vi kan dele opgaverne op som f\u00f8lger:<\/div>\n<h3>OPRET VARIABLE P\u00c5 SERVEREN<\/h3>\n<div>let players = [];<\/div>\n<div>let words = [&#8216;ged&#8217;, &#8216;ko&#8217;, &#8216;hjerne&#8217;, &#8216;sylfide&#8217;];<\/div>\n<div>const turnSeconds = 30;<\/div>\n<div>const prepareSeconds = 10;<\/div>\n<div>let whosTurn = 0;<\/div>\n<div>const noOfPlayers = 3;<\/div>\n<h3>OPRET VARIABLE P\u00c5 KLIENTEN<\/h3>\n<div>P\u00e5 klienten har vi f\u00f8rst brug for at vide om spillet er g\u00e5et i gang (og om vi er med)<\/div>\n<div>Vi kunne vise et input felt til brugernavn og pr\u00f8ve at sende det for at se om serveren har plads til os<\/div>\n<div>Senere skal vi vise spillere og deres point samt noget tid der t\u00e6ller ned<\/div>\n<div>til sidst skal vi ogs\u00e5 kunne vise enten det ord man skal tegne eller et felt til at indtaste g\u00e6t i<\/div>\n<div>let myTurn, brugernavnInput, guessInput, scoreboard, timeCounter;<\/div>\n<div>Lad os oprette felterne i setup(), fx:<\/div>\n<div>usernameInput = createInput().attribute(&#8216;placeholder&#8217;, &#8216;Skriv brugernavn og tryk enter&#8217;).changed(sendUsername);<\/div>\n<div>Nu bliver der oprettet et felt &#8211; usernameInput &#8211; som kalder funktionen sendUsername, n\u00e5r brugeren \u00e6ndrer i feltet og trykker ENTER &#8211; etc&#8230;<\/div>\n<h3>SEND BRUGERNAVN FRA KLIENT(ERNE)<\/h3>\n<div>Det n\u00e6ste vi skal g\u00f8re er at oprette en funktion p\u00e5 klienten der sender et brugernavn (og dermed fors\u00f8ger at deltage i spillet):<\/div>\n<div>function sendUsername(){<\/div>\n<div>socket.emit(&#8216;username&#8217;, usernameInput.value());<\/div>\n<div>}<\/div>\n<h3>MODTAG BRUGERNAVNE P\u00c5 SERVEREN<\/h3>\n<div>Serveren skal nu have en funktion der venter p\u00e5 brugernavne.<\/div>\n<div>Hver gang der kommer et brugernavn skal den selvf\u00f8lgelig<\/div>\n<div>-tjekke om der er plads til flere spillere<\/div>\n<div>-l\u00e6gge spillerne til i spiller arrayet<\/div>\n<div>-vi kan bygge arrayet s\u00e5dan her:<\/div>\n<pre>players.push({\n    id: socket.id,\n    brugernavn: brugernavn,\n    point: 0,\n});<\/pre>\n<div>Derefter skal serveren<\/div>\n<div>-tjekke om der er 3 spillere &#8211; alts\u00e5 nok til at starte et spil<\/div>\n<div>-og hvis det er tilf\u00e6ldet sende et startsignal til spillerne<\/div>\n<h3>START SPIL FRA SERVEREN<\/h3>\n<div>Det f\u00f8rste serveren skal g\u00f8re, er at sende et signal om at spillerne er klar<\/div>\n<div>Vi kan oprette en funktion: playersReady(), som g\u00f8r alt det der skal til for at begynde en nye runde:<\/div>\n<div>-v\u00e6lge en spiller der skal tegne og et ord der skal g\u00e6ttes<\/div>\n<div>-s\u00e6tte sekunderne til prepareSeconds<\/div>\n<div>-v\u00e6lge n\u00e6ste spiller ved at opskrive currentTurn, og nulstille den hvis den er lig noOfPlayers<\/div>\n<div>-nulstille en timer, og starte en timer<\/div>\n<div>-s\u00e6tte currentWord &#8211; og slette det fra arrayet<\/div>\n<div>-sende spillerarray med point til klienterne<\/div>\n<div>-sende n\u00e6ste ord til den spiller som har currentTurn<\/div>\n<h3>MODTAG RUNDE P\u00c5 KLIENTERNE<\/h3>\n<div>Nu skal klienterne s\u00e5 starte en runde.<\/div>\n<div>De f\u00e5r alts\u00e5 beskeden playersReady, som indeholder alle de oplysninger de skal bruge<\/div>\n<div>Undtagen sekunderne, men dem ordner vi lidt senere<\/div>\n<div>Lad os starte med at g\u00f8re de n\u00f8dvendige ting klar<\/div>\n<div>Klienten s\u00e6tter<\/div>\n<div>-background til startfarven, s\u00e5 tidligere tegninger bliver ryddet<\/div>\n<div>-myturn = false (s\u00e5 vi ikke risikerer en eller anden gammel variabel)<\/div>\n<div>-visk pointtavlen ud (s\u00e5 den er klar til at blive udfyldt)<\/div>\n<div>-gem g\u00e6tteordet<\/div>\n<div>-vis g\u00e6ttefeltet (skal alligevel g\u00f8res for alle, undtagen den der om lidt f\u00e5r besked om at tegne)<\/div>\n<div>-opdat\u00e9r scoreboard<\/div>\n<h3>MODTAG ORD FRA SERVEREN<\/h3>\n<div>Hvis det er denne klients tur til at tegne, sender vi beskeden yourTurn fra serveren med et tegneord.<\/div>\n<div>S\u00e5 skal klienten..<\/div>\n<div>-\u00e5bne tegnefunktionen<\/div>\n<div>-skjule g\u00e6tte input<\/div>\n<div>-vise tegneord<\/div>\n<h3>START TIMER P\u00c5 SERVEREN<\/h3>\n<div>Hvert sekund sender serveren en besked med systemets tilstand og sekunder<\/div>\n<div>Arrayet kan fx bygges s\u00e5dan:<\/div>\n<pre>function tick() {\n  if (state == 'prepare' &amp;&amp; seconds &lt;= 0) {\n    state = 'playing';\n    seconds = turnSeconds;\n  }\n  if (state == 'playing' &amp;&amp; seconds &lt;= 0) {\n    playersReady();\n  }\n  let stateMessage = {\n    state: state,\n    seconds: seconds,\n  }\n  io.sockets.emit('gameControl', stateMessage);\n  console.log(stateMessage);\n  seconds--;\n}<\/pre>\n<h3>MODTAG TIDST\u00c6LLER P\u00c5 KLIENTER<\/h3>\n<div>Nu modtager klienterne hvert sekund besked om at der spillet enten venterforberedes eller er i gang<\/div>\n<div>De skal s\u00e5..<\/div>\n<div>-Sende g\u00e6t hvis der skal g\u00e6ttes (og state=&#8217;playing&#8217;)<\/div>\n<div>-Sende tegning hvis der skal tegnes (og spillerens tur=true og state=&#8217;playing&#8217;)<\/div>\n<div>-Vise forberedelsestid, hvis state=&#8217;prepare&#8217;<\/div>\n<div>-Vise Sekunder hvis state=&#8217;playing&#8217;<\/div>\n<h3>MODTAG G\u00c6T P\u00c5 SERVEREN<\/h3>\n<div>Nu laver vi s\u00e5 funktionen p\u00e5 serveren der modtager g\u00e6t &#8211; hvis det rigtige ord er g\u00e6ttet, skal serveren..<\/div>\n<div>-Uddele point<\/div>\n<div>-Genstarte spil med ny runde<\/div>\n<\/div>\n<div><\/div>\n<div>Nu skulle arkitekturen gerne v\u00e6re s\u00e5dan, at serveren bare skal kalde playersReady, for at starte en ny runde. S\u00e5 er det bare at tegne og g\u00e6tte derud af (indtil der ikke er flere ord i words arrayet, s\u00e5 er det bare at kode videre og f\u00e5 spillet til at ligne noget man har lyst til at v\u00e6re med til i det hele taget).<\/div>\n<div><\/div>\n<div>Go forn\u00f8jelse<\/div>\n<div><\/div>\n<div>F\u00e6rdigt projekt:<\/div>\n<div><a href=\"https:\/\/minhaskamal.github.io\/DownGit\/#\/home?url=https:\/\/github.com\/simmoe\/digidaktik\/tree\/master\/sockets\/done\/draw_guess_done\">Hent zip her<\/a><\/div>\n<div><a href=\"https:\/\/github.com\/simmoe\/digidaktik\/tree\/master\/sockets\/done\/draw_guess_done\">Github her<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>I denne \u00f8velse skal vi fors\u00f8ge at g\u00f8re vores template til et lille spil &#8211; n\u00e6rmere bestemt tegnelegen &#8220;Tegn &amp; G\u00e6t&#8221;. Vi starter med en klient\/server template, der kun akkurat kan det mest n\u00f8dvendige. Hent multiplayer server template her\u00a0 2G INF: Hent midlertidig fremgang her:\u00a0sockets_multiplayer_temp Fremgangsm\u00e5de trin for trin Lad os f\u00f8rst teste applikationen i &#8230; <a title=\"Tegn og g\u00e6t med websockets og node.js\" class=\"read-more\" href=\"https:\/\/digitalteknik.slotshaven.it\/wordpress\/tegn-og-gaet-med-websockets\/\" aria-label=\"Read more about Tegn og g\u00e6t med websockets og node.js\">L\u00e6s mere <\/a><\/p>\n","protected":false},"author":3,"featured_media":3600,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[39],"class_list":["post-3754","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-den-fysiske-verden","tag-sockets"],"_links":{"self":[{"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/wp\/v2\/posts\/3754","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/wp\/v2\/comments?post=3754"}],"version-history":[{"count":0,"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/wp\/v2\/posts\/3754\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/wp\/v2\/media?parent=3754"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/wp\/v2\/categories?post=3754"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/digitalteknik.slotshaven.it\/wordpress\/wp-json\/wp\/v2\/tags?post=3754"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}