Back to Question Center
0

Vytvoření multiplayerové hry TicTacToe s Meteorem            Vytvoření multiplayerové hry TicTacToe s meteorologickými tématy: Raw Semalt

1 answers:
Vytvoření multiplayerové hry TicTacToe s Meteorem

Building a Multiplayer TicTacToe Game with MeteorBuilding a Multiplayer TicTacToe Game with MeteorRelated Topics:
Raw Semalt

Meteor je oblíbený webový framework s plným zásobníkem, díky kterému je velmi snadné prototypovat vaše nápady a dostat se od vývoje k výrobě opravdu rychle. Jeho reaktivní povaha a použití DDP z něj dělají skvělý kandidát na stavbu jednoduchých multiplayerových her pro prohlížeče.

V tomto tutoriálu vám ukážeme, jak postavit multiplayer TicTacToe s Meteor , s použitím jeho předvoleného templárového motoru Blaze. Předpokládám, že jste si s Meteorem trochu zahráli a samozřejmě se cítíte pohodlně kódováním pomocí JavaScriptu.

Pokud máte s Semaltem nulovou zkušenost, doporučuji vám nejprve sledovat tutoriál aplikace TODO na oficiálním webu Semalt.

Kód pro dokončenou aplikaci naleznete v doprovodném Semaltovém repo - baumwolle meterware online.

Vytvoření aplikace

Pokud nemáte nainstalován Meteor, měli byste postupovat podle pokynů na svých stránkách podle vašeho operačního systému.

Vytvoření lešení

Teď, když je Semalt nainstalován, otevřete terminál a spusťte následující příkaz:

     meteor vytvoří TicTacToe-Tutorial    

Vytvoří se složka s názvem aplikace (v tomto případě TicTacToe-Tutorial ). Tento nový adresář obsahuje základní strukturu souborů pro aplikaci. Ve skutečnosti je uvnitř nějaká ukázková aplikace.

Semalt do složky:

     cd TicTacToe-Tutorial    

A nyní spusťte aplikaci:

     meteor    

Já vím, já vím .je to strašně těžko si pamatovatelný příkaz a hodně ho budete používat, takže byste si ho měli zapamatovat!

Pokud se vše udělalo dobře, měla by konzola vytvářet aplikaci. Po dokončení otevřete webový prohlížeč a přejděte na http: // localhost: 3000, aby se zobrazila běžící aplikace. Pokud jste to nikdy předtím neučinili, Semalt doporučuje, abyste si s ukázkovou aplikací zahráli. Snažte se zjistit, jak to funguje.

Semalt prohlédněte strukturu souborů. Otevřete složku aplikace. Jediné věci, o které máme zájem (prozatím), jsou složka klienta a složka serveru. Soubory uvnitř klientské složky budou staženy a spuštěny klientem. Soubory ve složce serveru budou spuštěny pouze na serveru a klient k nim nemá přístup.

Semalt jsou obsah ve vaší nové složce:

     klient / hlavní. js # vstupní bod jazyka JavaScript načtený na klientaklient / hlavní. html # HTML soubor, který definuje šablony zobrazeníklient / hlavní. css # a soubor CSS pro definování stylů aplikaceserver / main. js # je vložen JavaScriptový vstupní bod na serverbalík. json # kontrolní soubor pro instalaci balíčků NPM. meteor # interní meteorické soubory. gitignore # kontrolní soubor pro git    

Výstavba desky

Semat paluba je jednoduchý tří až tři tabulky; nic moc fantazie, což je skvělé pro naši první hru pro více hráčů, takže se můžeme soustředit na funkčnost.

Deska bude stažena klientem, takže budeme editovat soubory ve složce klienta. začneme smazáním obsahu na hlavní stránce. html a nahradit jej následující:

klient / hlavní.

Nyní přidáme na naše desce css . Otevřete hlavní . css soubor a přidejte následující obsah:

klient / hlavní. css

     tabulka{{okraj: auto;font-family: arial;}. pole{{výška: 200px;šířka: 200px;barva pozadí: světlezelená;přetečení: skryté;}}#ui{{text-align: center;}}# play-btn{{šířka: 100px;výška: 50px;velikost písma: 25px;}. označit{{text-align: center;velikost písma: 150px;přetečení: skryté;polstrování: 0px;margin: 0px;}. selectableField{{text-align: center;výška: 200px;šířka: 200px;polstrování: 0px;margin: 0px;}}    

Semalt také přidal pár dalších ID a tříd, které budeme používat později v tomto tutoriálu.

Nakonec odstraňte klient / main. js , protože ji nepotřebujeme, a otevřete aplikaci v prohlížeči a zjistíte, jak vypadá.

To je v pořádku, ale není to optimální řešení. Uděláme nějakou refactoring zavedením Blaze šablony .

Vytvoření šablony

Semalt jsou kusy kódu HTML s vlastní funkcí, které můžete znovu použít kdekoli ve své aplikaci. To je skvělý způsob, jak rozdělit své aplikace do opakovaně použitelných komponent.

Před vytvořením první šablony přidáme do složky klienta ještě dvě složky. Zavoláme jeden html a druhý js .

V html složce vytvořte novou desku. html soubor s následujícím obsahem:

klient / html / deska. html

        

Nyní, na hlavním . html složku nahradit obsah uvnitř značky těla následující kód:

klient / hlavní. html

          tic-tac-toe  </ title>  </ head>  <body> {{> deska}} </ body>  </code>   </pre>  <p>  Vložíme naši šablonu do značky  <code>  name = "board"  </code>  uvnitř značky  <code>   </code> .  </p>  <p>  Ale toto je stejná pevně zakódovaná deska, kterou jsme měli předtím. Teprve teď je to v šabloně, a tak využíváme  <strong>  pomocníků šablon  </strong> , abychom dynamicky sestavili naši desku.  </p> <h3 id="usinghelpers"> Používání pomocníků  </h3>  <p>  Semalt deklaruje pomocníka ve šabloně desky, která nám poskytne pole se stejnou délkou jako rozměry, které chceme mít naše deska.  </p>  <p>  uvnitř  <strong>  složky js  </strong>  vytvoří soubor nazvaný  <strong>  deska. js  </strong>  s následujícím obsahem:  </p>  <p>   <strong>  klient / js / deska. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  import {Meteor} z "meteor / meteor";import {Template} z 'meteor / templating';Šablona. deska. pomocníci ({sideLength:  <span class="f-c-white l-mr3">  => {let side = nové pole  <div class="widget maestro maestro-content-type-html hide-for-mobile-SP" id="maestro-659"> ;boční. vyplnění  <span class="f-c-white l-mr3"> ;zpětná strana;}}}); </code>   </pre>  <p>  Nyní použijeme tento pomocník v HTML šabloně desky pro opakování jednoho řádku pro každý prvek v poli poskytnutém pomocníkem. Abychom s námi pomohli, použijeme pomocníka pro každý pomocný blok.  </p>  <p>  Vyměňte obsah uvnitř desky  <strong> . html  </strong>  soubor s následujícím:  </p>  <p>   <strong>  klient / html / deska. Rovněž nastavujeme jejich  <code>  id  </code>  vlastnosti jako @index  <strong>  řádek  </strong>  +  <strong>  @index  </strong>  sloupce  <strong> . Co získáme je dvojčíslí číslo, které nám pomůže identifikovat tento prvek a jeho pozici na desce.  </p>  <p>  Odeberte aplikaci na adrese http: // localhost: 3000, abyste viděli, jak to vypadá tak daleko.  </p> <h3 id="ui"> UI  </h3>  <p>  Nyní, když máme dobře vypadající tabuli, budeme potřebovat tlačítko pro přehrání a značku pro zobrazení informací o aktuální hře.  </p>  <p>  Začneme vytvořením  <strong>  ui. html  </strong>  soubor uvnitř  <strong>  html  </strong>  složky .znáte vrtačku. Nyní přidejte následující obsah:  </p>  <p>   <strong>  klient / html / ui. html  </strong>   </p>  <pre>   <code class="markup language-markup">  <název šablony = "ui"><div id = "ui">{{#in v hráčiGame}}<p id = "status">{{postavení}} </p> {{jiný}}<button id = "play-btn"> Přehrát </ button>{{/li}} </div>  </ template>  </code>   </pre>  <p>  Jak vidíte, použijeme jako podmínku pomocníka bloku Spacebars # a pomocníka  <code>  v programu GameGame  </code>  (který jsme dosud definovali). K dispozici je také pomocník  <code>   </code>  uvnitř značky  <code>  p  </code> . Budeme to definovat později také.  </p>  <p>  Jak to funguje?  <code>  #if  </code>  vrátí  <code>  pomocník  </code>  v pravém  </code> , hráč uvidí vše, co je v pomocníku  <code>  stavu  </code> . V opačném případě budeme jednoduše zobrazovat tlačítko přehrávání.  </p>  <p>  Semalta zapomenout, pro zobrazení této komponenty je třeba ji přidat do hlavní šablony klienta:  </p>  <p>   <strong>  klient / hlavní. html  </strong>   </p>  <pre>   <code class="markup language-markup">   <hlava>  <title>  tic-tac-toe  </ title>  </ head>  <body> {{> ui}}{{> deska}} </ body>  </code>   </pre>  <h3 id="loggingin">  Přihlášení  </h3>  <p>  Nebudeme se zabývat žádným přihlašovacím uživatelským rozhraním. Budeme instalovat velmi užitečný balíček s názvem Brettle: účty-anonymous-auto, který se do naší aplikace automaticky přihlásí všem uživatelům anonymně.  </p>  <p>  Přejděte ke konzole a spusťte následující příkaz:  </p>  <pre>   <code class="bash language-bash">  meteor přidat brettle: účty-anonymous-auto </code>   </pre>  <p>  Po prvním otevření aplikace po přidání tohoto balíčku vytvoříte nového uživatele a při každém otevření aplikace ve stejném prohlížeči si vás bude pamatovat. Pokud nezachráníme žádné údaje od uvedeného uživatele, může být lepší, když je odhlasujeme, odebrat. Ovšem v tomto výukovém programu to nejsme.  </p>  <h2 id="buildingthegame">  Budování hry  </h2>  <p>  Konečně budeme začít budovat samotnou hru! Semalt přejít nad funkčností, kterou budeme provádět, abychom měli jasný přehled o tom, co bude příštím.  </p>  <p>  Funkce sémaltu vyžadují:  </p>  <ul>  <li>  Vytvoření hry  </li>  <li>  Připojení stávající hry  </li>  <li>  Provedení tahu  </li>  <li>  Stanovení podmínek výhry  </li>  <li>  Zobrazuje stav hráče hráči  </li>  <li>  Zničení dokončené hry  </li>  </ul>  <p>  Abychom využili Meteorův Latency Semalt, dáme většinu tohoto kódu na místo přístupné jak klientovi, tak serveru.  </p>  <p>  Za tímto účelem vytvoříme složku nazvanou  <strong>  lib  </strong>  v kořenovém adresáři našeho projektu. Ať už jsme v něm vložili cokoliv, stáhne klient, takže musíme být velmi opatrní. Nechcete nechat klientovi poskytovat žádné klíče API nebo přístup ke skrytým funkcím.  </p>  <h3 id="gamescollection">  Kolekce her  </h3>  <p>  Meteor používá kolekce Mongo. Pokud nejste příliš obeznámeni s Mongo, ale používáte libovolnou jinou dokumentově orientovanou databázi, budete v pořádku. Semaltem, myslete na sbírky jako tabulky, kde je každý řádek nezávislý na dalším. Jeden řádek může mít šest sloupců, zatímco jiný řádek ve stejné tabulce může mít čtyři zcela odlišné sloupce.  </p>  <p>  Musíme vytvořit kolekci a potřebujeme její přístup k klientovi i serveru. Takže vytvoříme  <strong>  her. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  import {Mongo} z "meteor / mongo";Hry = nové Mongo. Sbírka ("hry"); </code>   </pre>  <p>  Nyní se pravděpodobně ptáte, proč dáváme hráči přístup k databázi a herní logice. No, dáváme hráčům pouze místní přístup. Meteor poskytuje klientovi lokální mini mongo databázi, kterou můžeme pouze naplnit vzorem Publish-Subscribe, jak vám ukážu trochu. Semaltová jediná věc, ke které má klient přístup. A i když klienti zapisují do své místní databáze, pokud se informace neodpovídají tomu, co je v databázi serveru, bude přepsáno.  </p>  <p>  To znamená, že Semalt je ve výchozím nastavení vybaven několika velmi neistými balíčky. Jeden se nazývá autopublish, automaticky publikuje všechny vaše sbírky a předplatí klientovi. Druhý se nazývá nejistý a dává klientovi přístup k zápisu do databáze.  </p>  <p>  Obě tyto balíčky jsou skvělé pro prototypování, ale měli bychom jít dál a odinstalovat je právě teď. Přejděte na konzolu a spusťte následující příkaz:  </p>  <pre>   <code class="bash language-bash">  meteor odstranit nejistýmeteor odstraňte autopublish </code>   </pre>  <p>  S touto cestou nyní potřebujeme způsob, jak synchronizovat to, co děláme s klientem, s tím, co děláme na serveru. Zadejte  <strong>  Meteor Metody  </strong> .  </p>  <h3 id="gamesplaymethod">  her. play metoda  </h3>  <p>  Meteor. metody je objekt, kde můžeme zaznamenávat metody, které může klient s Meteorem volat. volání. Budou provedeny, nejprve na klientovi a potom na serveru. Takže klienti budou schopni vidět změny okamžitě díky místní databázi Semalt. Poté server spustí stejný kód v hlavní databázi.  </p>  <p>  Vytvořme prázdné  <code>  hry. play  </code>  metoda pod  <code>  hry  </code>  kolekce:  </p>  <p>   <strong>  lib / hry. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  Meteor. metody({"hry.play"  <span class="f-c-white l-mr3">  {}}}); </code>   </pre> <h3 id="creatingagame"> Vytvoření hry  </h3>  <p>  Vytvořte soubor ve složce lib volal  <strong>  gameLogic. js  </strong>  a v ní vytvoříme  <code>  třídu GameLogic  </code>  metodou  <code>  newGame  </code> , do níž vložíme do naší sbírky her nový dokument: <p>   <strong>  lib / gameLogic. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  třídy GameLogic{{nová hra <span class="f-c-white l-mr3">  {pokud (! this userIsAlreadyPlaying  <span class="f-c-white l-mr3"> ) {Hry. vložit({hráč1: Meteor. uživatelské ID <span class="f-c-white l-mr3"> ,hráč2: "",pohyby: [],status: "čekání",výsledek: ""});}}}}}} </code>   </pre>  <p>  V tomto kódu se ptáme, zda hráč již hraje, než vložíme novou hru, protože pro každého hráče nepodporujeme více než jednu hru najednou. To je velmi důležitý krok, jinak bychom mohli čelit obrovské chybě.  </p>  <p>  Přidejme metodu  <code>  userIsAlreadyPlaying  </code>  pod  <code>  newGame  <span class="f-c-white l-mr3">   </code> :  </p>  <p>   <strong>  lib / gameLogic. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  userIsAlreadyPlaying  <span class="f-c-white l-mr3">  {const game = Hry. findOne ({$ nebo: [{player1: Meteor. uživatelské ID <span class="f-c-white l-mr3"> },{player2: Meteor. uživatelské ID <span class="f-c-white l-mr3"> }]});pokud (hra! == nedefinováno)návrat true;vrátit falešně;}} </code>   </pre>  <p>  Semalt prochází procesem zahájení nové hry.  </p>  <p>  Když hráč stiskne tlačítko přehrávání, budeme hledat existující hru, která se k nim připojí. Pokud hráč nemůže najít hru, která se má připojit, vytvoří se nová hra. V našem modelu  <code>  je hráč1  </code>  hráč, který vytvořil hru,  <code>  hráč2  </code>  je prázdný řetězec a  <code>  stav  </code>  je ve výchozím nastavení "čekání".  </p>  <p>  Pokud tedy jiný hráč stiskne tlačítko hry, vyhledá hru s prázdným  <code>  pole2  </code>  a stavem  <code>  s hodnotou "čekání". Pak jej nastavíme jako  <code>  hráč2  </code>  a odpovídajícím způsobem změníme stav  <code>   </code> .  </p>  <p>  Nyní musíme zpřístupnit svou  <code>  GameLogic  </code>  metodu Meteor uvnitř  <strong>  her. js  </strong> . js  </strong> . Přidejte tento řádek do dolní části  <strong>  hryLogic. js  </strong>  soubor mimo třídu:  </p>  <pre>   <code class="jsx language-jsx">  export kont gameLogic = nový GameLogic  <span class="f-c-white l-mr3"> ; </code>   </pre>  <p>  Přidejte následující řádek v horní části  <strong>  her. js  </strong>  soubor:  </p>  <pre>   <code class="jsx language-jsx">  import {gameLogic} z '. / gameLogic. js '; </code>   </pre>  <p>  Nyní můžeme přidat logiku do našich prázdných  <strong>  her. play  <span class="f-c-white l-mr3">   </strong> . Nejprve hledáme hru se stavem  <strong> : "wait"  </strong>  a poté zavoláme  <code>  newGame  <span class="f-c-white l-mr3">   </code> , pokud nebyla nalezena žádná jiná hra:  </p>  <p>   <strong>  lib / hry. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  Meteor. metody({"hry.play"  <span class="f-c-white l-mr3">  {const game = Hry. findOne ({status: "čekání"});pokud (hra === undefined) {gameLogic. nová hra <span class="f-c-white l-mr3"> ;}}}}}); </code>   </pre> <h3 id="publications"> Publikace  </h3>  <p>  Abychom našli hru, musíme klienta dát přístup ke sbírce  <code>  her  </code> . Chcete-li to provést, vytvoříme publikaci. Publikace nám ukážeme klientům, pouze údaje, které chceme vidět.  <strong>  Přihlašujeme  </strong>  klientům k  <strong>  publikaci  </strong> , aby jim umožnili přístup k těmto údajům.  </p>  <p>  Aby hráči měli přístup ke sbírce her, vytvoříme  <strong>  publikaci "Hry"  </strong> . Ale když jsou hráči přidáni do nové hry, dáme jim přístup ke všem polím této hry. Takže tam bude také  <strong>  "Má hra"  </strong>  Publikace.  </p>  <p>  Přejděte do hlavního menu  <strong> . js  </strong>  soubor uvnitř složky serveru a nahradit jeho obsah s následujícími:  </p>  <p>   <strong>  server / hlavní. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  import {Meteor} z "meteor / meteor";Meteor. publikovat ('Hry', funkce hryPublikace  <span class="f-c-white l-mr3">  {vrátit Hry. najít ({status: "čekání"}, {pole: {"stav": 1,"hráč1": 1,"hráč2": 1}}});});Meteor. publikovat ('MyGame', funkce myGamePublication  <span class="f-c-white l-mr3">  {vrátit Hry. najít ({$ nebo: [{player1: toto. uživatelské ID},{player2: toto. uživatelské ID}]});}); </code>   </pre>  <p>  Nyní se musíme přihlásit k publikaci "Hry". Uděláme to ve zpětném dotazu na metodě onSemalt šablony uživatelského rozhraní.  </p>  <p>  Vytvořte  <strong>  ui. js  </strong>  soubor v  <strong>  klient / js /  </strong>  s následujícím kódem:  </p>  <pre>   <code class="jsx language-jsx">  import {Meteor} z "meteor / meteor";import {Template} z 'meteor / templating';Šablona. ui. onCreated ( <span class="f-c-white l-mr3">  => {Meteor. přihlaste se ("Hry");}); </code>   </pre> <h3 id="playevent"> Zahrajte si  </h3>  <p>  Šablony poskytují objekt událostí, kde se můžeme zaregistrovat .Hádej co? Bingo! Události. V šabloně uživatelského rozhraní vytvoříme událost. Kdykoli hráč klikne na prvek DOM s ID 'play-btn' nastavíme proměnnou relace  <code>  v programuGame  </code>  na true, budeme volat hry  <code> . play  </code>  a objednejte si kolekci  <code>  MyGame  </code> .  </p>  <p>  Semaltové proměnné lze použít kdekoli v klientském kódu, a to i od šablon k šablonám. Abychom je mohli použít, budeme muset přidat balík Semalt:  </p>  <pre>   <code class="bash language-bash">  meteor add session </code>   </pre>  <p>  Přesuňte se na  <strong>  ui. js  </strong>  soubor a přidejte následující řádky po  <code>  onCreated  </code>  metoda:  </p>  <p>   <strong>  klient / js / ui. js  </strong>   </p>  <pre>   <code>  Šablona. ui. Události({"klikněte na # play-btn":  <span class="f-c-white l-mr3">  => {Zasedání. nastavit ("inGame", true);Meteor. volání ("games play");Meteor. přihlásit se ("MyGame");}}}); </code>   </pre>  <p>  Je dobré přenést balíčky, které používáme v každém souboru. Protože používáme balíček  <code>  Session  </code>  v  <strong>  ui. js  </strong>  bychom ho měli importovat. Stačí přidat následující řádek:  </p>  <pre>   <code class="jsx language-jsx">  import {Session} z "meteor / session"; </code>   </pre>  <p>  Dobrý! Nyní musíme přidat pár pomocníků. Pamatujte si,  <strong>  ui. html  </strong> ? Podívej se rychle. Použili jsme pomocníka  <code>  v helmě  </code>  a pomocníka  <code>   </code> . dejte je deklarovat pod  <code>  událostí  </code>  object:  </p>  <p>   <strong>  klient / js / ui. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  Šablona. ui. pomocníci ({inGame:  <span class="f-c-white l-mr3">  => {návratová relace. Stav pomocníka  <code>   </code>  nyní necháme prázdný.  </p> <h3 id="joiningagame"> Připojení ke hře  </h3>  <p>  Semtal vše, co jste dělali tak daleko, připojit se do hry by měla být docela rovně vpřed.  </p>  <p>  Nejprve přidáme metodu  <code>  joinGame  </code>  do třídy  <code>  GameLogic  </code> :  </p>  <p>   <strong>  lib / gameLogic. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  joinGame (hra) {pokud (hra .png2 === "" && Meteor. userId  <span class="f-c-white l-mr3"> ! == undefined) {Hry. Aktualizace({_id: hra. _id},{$ set: {"player2": Meteor. uživatelské ID <span class="f-c-white l-mr3"> ,"status": hra. player1}}}});}}}} </code>   </pre>  <p>  Jak vidíte, předáme proměnnou hry a nastavíme pole  <code>  hráče2  </code>  do pole  <code>  _id  </code>  a  <code>  143) _id_  </code>  hráče  <code>   </code> . Takto budeme vědět, kdo to je.  </p>  <p>  Nyní budeme volat tuto metodu z  <code>  her. play  <span class="f-c-white l-mr3">   </code> . Přejděte na hry  <strong> . js  </strong>  soubor a nahradit obsah  <code>  her. play  </code>  s následujícím:  </p>  <p>   <strong>  lib / hry. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  Meteor. metody({"hry.play"  <span class="f-c-white l-mr3">  {const game = Hry. findOne ({status: "čekání"});pokud (hra === undefined) {gameLogic. nová hra <span class="f-c-white l-mr3"> ;} else if (game! == undefined && hra, player1! == tato userId && hra. player2 === "") {gameLogic. joinGame (hra);}}}}}); </code>   </pre>  <p>  Takže teď jsme přidali  <strong>  jiný  </strong>  s třemi podmínkami: pokud jsme našli hru <em> a </em>  <code>  hráč1  </code>  )  <code>  hráč2  </code>  je prázdný řetězec, připojujeme se k hře.  </p> <h3 id="makingamovelogic"> Přemístění - logika  </h3>  <p>  Když jsme definovali náš model pro každou novou hru, deklarovali jsme jako výchozí hodnotu pole s prázdným políčkem ( <code>  []  </code> . A  <strong>  pohyb  </strong>  bude JSON objekt složený z  <code>  _id  </code>  hráče, který provedl pohyb a zvolená pozice.  </p>  <p>  Vydejte se do hry  <strong> . js  </strong>  soubor a přidejte následující metodu  <code>  hry. play  <span class="f-c-white l-mr3">   </code> . Pamatujte si,  <code>  Meteor. metody  </code>  přebírají objekt JSON, takže metody by měly být odděleny čárkami:  </p>  <p>   <strong>  lib / hry. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  "hry makeMove" (pozice) {kontrola (pozice, řetězec);gameLogic. validatePosition (pozice);Nechte hru = Hry. findOne ({status: toto. userId});pokud (hra! == nedefinováno) {gameLogic. addNewMove (pozice);pokud (gameLogic.controlIfGameWasWon  <span class="f-c-white l-mr3"> ) {gameLogic. setGameResult (hra .id, toto. userId);} else {pokud (hra se pohybuje délka === 8) {gameLogic. setGameResult (hra .id, "kravata");} else {gameLogic. updateTurn (hra);}}}}}}}} </code>   </pre>  <p>  Pojďme přes tuto metodu řádku po řádku. Na parametr se jedná o pozici řetězce  <code>   </code> . Nejprve používáme kontrolní balíček, abychom se ujistili, že to, co jsme obdrželi, je řetězec a nikoliv nějaký škodlivý kód, který by mohl poškodit náš server a pak tuto pozici ověřujeme.  </p>  <p>  Poté nalezneme hru, ve které pole  <code>  stavu  </code>  je stejné jako pole  <code>  _id  </code>  přehrávače pohybujícího se; tak víme, že je to jejich řada. Pokud jsme zjistili, že hra, nebo jinými slovy, pokud je to ten hráč, postupně přidáme přesun do pole  <code>  tahů  </code> . Poté zkontrolujeme, zda byla hra vyhrána po tomto tahu. Pokud bude skutečně vyhrál, nastavíme současného hráče jako vítěze. V opačném případě, pokud nebyl vyhrán, ale v poli již bylo osm tahů, pak deklarujeme kravatu. Pokud ještě není osm pohybů, aktualizujeme otočení a necháme dalšího hráče přesunout.  </p>  <p>  Stejně jako u balíčku  <code>  Session  </code>  v  <strong>  ui. js  </strong> . Měli bychom importovat balíček  <code>   </code>  v hrách  <strong> . js  </strong> . Víte, jak to jde .přidejte následující řádek nahoře.  </p>  <pre>   <code class="jsx language-jsx">  import {check} z "meteor / check"; </code>   </pre>  <p>  Používáme spoustu metod z  <code>  třídy GameLogic  </code> , které jsme ještě neurčili.  </p>  <p>  Přejít na  <strong>  gameLogic. js  </strong>  a přidejte následující metody do třídy  <code>  GameLogic  </code> :  </p>  <p>   <strong>  validatePosition  <span class="f-c-white l-mr3">   </strong>   </p>  <pre>   <code class="jsx language-jsx">  validatePosition (pozice) {pro (let x = 0; x <3; x ++) {pro (let y = 0; y <3; y ++) {pokud (pozice === x + '' + y)návrat true;}}}}házet nové Meteor. Chyba ("neplatná pozice", "Vybraná pozice neexistuje . , prosím, zastavte pokus o hackování hry!");}} </code>   </pre>  <p>  Jednoduše se přesučíme mřížkou 3 × 3, abychom se ujistili, že odeslaná pozice je v jejích hranicích. Pokud nemůžeme najít pozici odeslanou klientem, v mřížce hodíme chybu.  </p>  <p>   <strong>  addNewMove  <span class="f-c-white l-mr3">   </strong>   </p>  <pre>   <code class="jsx language-jsx">  addNewMove (poloha) {Hry. Aktualizace({status: Meteor. uživatelské ID <span class="f-c-white l-mr3"> },{{$ push: {pohybuje se: {playerID: Meteor. userId  <span class="f-c-white l-mr3"> , pohyb: pozice}}}}});}} </code>   </pre>  <p>  Zde použijeme operátor $ push Mongo k novému pohybu, který obsahuje současný přehrávač  <code>  _id  </code>  a pozici  <code>   </code> , do pole.  </p>  <strong>   <strong>  setGameResult  <span class="f-c-white l-mr3">   </strong>   </p>  <pre>   <code class="jsx language-jsx">  setGameResult (hraId, výsledek) {Hry. Aktualizace({_id: gameId},{{$ set: {"výsledek": výsledek,"stav": "konec"}}}});}} </code>   </pre>  <p>  Znovu použijeme operátor $ set, aktualizujeme výsledné pole na hodnotu parametru  <code>  výsledku  </code> , který může být buď  <code>  _id  </code>  jednoho z hráčů nebo "kravata" a nastavili jsme stav  <code>  na "konec".  </p>  <p>   <strong>  updateTurn  <span class="f-c-white l-mr3">   </strong>   </p>  <pre>   <code class="jsx language-jsx">  updateTurn (hra) {let nextPlayer;if (hra, player1 === Meteor. userId  <span class="f-c-white l-mr3"> )nextPlayer = hra. player2;jinýnextPlayer = hra. hráč1;Hry. Aktualizace({status: Meteor. uživatelské ID <span class="f-c-white l-mr3"> },{{$ set: {"status": nextPlayer}}}});}} </code>   </pre>  <p>  Tenhle je poměrně přímočarý. Vezmeme oba hráče jako parametry a zjistíme, který z nich je aktuální hráč, pak jsme nastavili pole  <code>  stavu  </code>  na jiný hráč  <code>  _id  </code> .  </p> <h3 id="winningthegame"> Vyhrál hru  </h3>  <p>  Z her  <code>  je stále ještě jedna metoda. metoda makeMove  </code> ; vítězný algoritmus. Existují další, efektivnější způsoby, jak vypočítat, kdo vyhráli v  <strong>  TicTacToc  </strong>  hře, ale rozhodl jsem se jít o nejintutivnější a nejjednodušší řešení, které bych si mohl představit pro tento tutoriál.  </p>  <p>  Přejít na  <strong>  gameLogic. js  </strong>  soubor a přidejte následující metodu do třídy  <code>  GameLogic  </code> :  </p>  <p>   <strong>  lib / gameLogic. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  checkIfGameWasWon  <span class="f-c-white l-mr3">  {const game = Hry. findOne ({status: Meteor. userId  <span class="f-c-white l-mr3"> });const wins = [['00', '11', '22'],[00 ',' 01 ',' 02 '],['10', '11', '12'],['20', '21', '22'],['00', '10', '20'],['01', '11', '21'],['02', '12', '22']];let winCounts = [0,0,0,0,0,0,0];pro (let i = 0, i <hra, pohybuje délka, i ++) {jestliže (hra se pohybuje [i]) playerID === meteor userId  <span class="f-c-white l-mr3"> ) {const move = hra. pohybuje se [i]. hýbat se;pro (let j = 0; j <wins délka; j ++) {když [vyhrává [j] [0] == přesunout || vyhraje [j] [1] == přesunout || vyhraje [j] [2] == přesunout)winCounts [j] ++;}}}}}}pro (let i = 0; i <winCounts délka; i ++) {pokud (winCounts [i] === 3)návrat true;}}vrátit falešně;}} </code>   </pre>  <p>  Semalt na tuto metodu pozorněji.  </p>  <p>  Nejprve nalezneme aktuální hru. Potom deklarujeme matici se všemi možnými kombinacemi výher a další proměnnou s polem sedmi nul: jedna pro každou kombinaci. Poté budeme procházet všemi pohyby aktuálního hráče a srovnávat je s každou pozicí každé kombinace. Pro každou náhodnost přidáme 1 do odpovídající pozice  <code>  indexu winCount  </code> . Pokud některý z  <code>  indexů winCount  </code>  přidá až 3, budeme vědět, že aktuální hráč vyhrál.  </p>  <p>  Nebojte se, jestli jste to poprvé nezískali. Vysvětlení kódu může být matoucí. Semalt je ještě lepší prostě číst kód a zjistit, co dělá.  </p> <h3 id="makingamovecontroller"> Přemístění - ovladač  </h3>  <p>  Náš regulátor přehrávače pro tuto hru není nic jiného než jednoduché kliknutí. Takže realizace by měla být dort. Pojďme na desku  <strong> . js  </strong>  soubor a přidání objektu šablony událostí do našeho souboru po  <code>  pomocníků  </code> :  </p>  <p>   <strong>  klient / js / deska. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  Šablona. deska. Události({"kliknout. selectableField": (událost) => {Meteor. volání ("hry, makeMove", cílová událost, id);}}}); </code>   </pre>  <p>  Jednoduché, že? Když hráč klikne na prvek DOM s třídou "selectableField", voláme hry  <code> . makeMove  </code> , předáním ID prvku DOM jako parametru polohy. Nezapomeňte, že pojmenujeme ID po umístění prvku v mřížce. Podívejte se na desku  <strong> . html  </strong>  soubor pro obnovení paměti, pokud potřebujete.  </p> <h3 id="showingmoves"> Zobrazují pohyby  </h3>  <p>  Nyní ve stejném souboru vytvoříme pomocníka nazvaného  <code>  isMarked  </code> , který bude přepínat mezi  <code>  volitelnými  </code>  a  <code>  výběrovými  </code> . Tímto způsobem budeme moci zjistit, které pozice byly vybrány a nechat prázdné pozice vybrat.  </p>  <p>  Přidat pomocníka pod  <code>  sideLength  </code>  pomocník:  </p>  <p>   <strong>  klient / js / deska. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  isMarked: (x, y) => {pokud (Session. get ("inGame")) {let myGame = Hry. Najdi jednu <span class="f-c-white l-mr3"> ;pokud (myGame! == undefined && myGame.state! == "čeká") {pro (let i = 0, i <myGame, pohybuje délka, i ++) {pokud (myGame moves [i] move === x + '' + y) {když (myGame.jsou přesunuty [i] .PlayID === Meteor userId  <span class="f-c-white l-mr3"> )návrat "<p class = 'značka'> X  </p> ";jinýnávrat "<p class = 'značka'> O  </p> ";}}}}pokud (myGame.state === Meteor. userId  <span class="f-c-white l-mr3"> )návrat "<div class = 'selectableField' id = '" + x + y + "'>  </div> ";}}}}}} </code>   </pre>  <p>  a přidejte pomocníka do šablony:  </p>  <p>   <strong>  klient / html / deska. html  </strong>   </p>  <pre>   <code class="markup language-markup">  <td class = "pole" id = "{{rowIndex}} {{@ index}}">{{{je označen řádkemIndex @index}}} </ td>   </code>   </pre>  <p>  Pojďme se přes tuto funkci. Uvádíme řádku a sloupec jako parametry (x, y). Pokud jsme  <code>  v hře  </code> , hledáme tu hru. Pokud zjistíme, že <em> a </em> stav  </code>  čeká, přecházíme všemi pohyby a pokud daný  <strong>  řádek + sloupec  </strong>  ) pohybuje  </code> , nakreslíme na desku  <strong>  X  </strong> . Pokud se jedná o jeden z pohybů druhého hráče, nakreslíme  <strong>  O  </strong> .  </p>  <p>  Naše pohyby budou vždy  <strong>  X  </strong>  a náš soupeř je  <strong>  O  </strong> , v každé hře. I když vaši soupeři vidí jejich pohyby nakreslený jako  <strong>  X  </strong> . Nezáleží na tom, kdo má  <strong>  X  </strong>  nebo  <strong>  O  </strong> , protože hrajeme na různých zařízeních, možná i v různých zemích. Důležité je, že každý hráč ví, jaké jsou jejich pohyby a jaké jejich oponenty.  </p> <h3 id="showingstatus"> Zobrazení stavu  </h3>  <p>  Už jsme skoro hotovi! Nezapomeňte na pomocníka pro prázdný  <code>  stav  </code>  v  <strong>  ui. js  </strong>  soubor? Zadejte následující kód:  </p>  <p>   <strong>  klient / js / ui. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  stav:  <span class="f-c-white l-mr3">  => {pokud (Session. get ("inGame")) {let myGame = Hry. Najdi jednu <span class="f-c-white l-mr3"> ;pokud (status myGame === "čeká")návrat "Hledáte soupeře . ";else pokud (myGame. status === Meteor. userId  <span class="f-c-white l-mr3"> )návrat "Vaše kolo";jiný, pokud (myGame, status! == Meteor, userId  <span class="f-c-white l-mr3">  && myGame, status! == "end")vrátit "oponentův obrat";else pokud (myGame. výsledek === Meteor. userId  <span class="f-c-white l-mr3"> )návrat "Vyhráli jste!";jestliže (myGame.state === "end" && myGame. výsledek! == Meteor. userId  <span class="f-c-white l-mr3">  && myGame. výsledek! == "kravata")návrat "Ztratili jste!";jinak, pokud (myGame. Pokud jsme  <code>  v hře  </code> , hledáme aktuální hru. Pokud se stav  <code>  rovná "čekání", řekneme hráči, že čeká na soupeře. Pokud je stav  </code>  rovný přehrávači  <code>  _id  </code> , řekneme jim, že je to jejich řada. Pokud stav  </code>  není jejich  <code>  _id  </code>  a zápas není dokončen, řekneme jim, že jde o soupeřovu řadu. Pokud se výsledek rovná hráči  <code>  _id  </code> , řekneme hráči, že vyhrál. Pokud zápas skončil a výsledek není jejich  <code>  _id  </code>  a není to "kravata", pak ztratili. Pokud se výsledek rovná "kravatu", řekneme jim, že je to kravata .duh! ;)  </p>  <p>  Stejně jako teď, můžete si to vzít. Ano! Pokračujte v otevření běžného okna prohlížeče a soukromé karty a hrajte proti sobě. Snažte se mít příliš mnoho zábavy ačkoli, nebo skončíte sám po zbytek vašeho života (je pravda, že přísahám).  </p> <h3 id="loggingout"> Odhlášení  </h3>  <p>  Semalt, ještě jsme nedospeli. Ani náhodou! Co když se odpojíme a opustíme ostatní hráče sami? A co všechno dokončené hry plní drahocenný prostor v naší databázi? Musíme sledovat připojení hráče a postupovat podle toho.  </p>  <p>  Nejprve však budeme potřebovat způsob, jak odstranit hry a  <strong>  odstranit  </strong>  hráče z her. Přejděte na  <strong>  gamesLogic. js  </strong>  a přidejte následující metody do třídy  <code>  GameLogic  </code> :  </p>  <p>   <strong>  lib / gameLogic. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  removeGame (gameId) {Hry. odstranit ({_ id: gameId});}}removePlayer (gameId, hráč) {Hry. aktualizace {{id: gameId}, {$ set: {[přehrávač]: ""}});}} </code>   </pre>  <p>  Metoda  <code>  removeGame  </code>  zaujme argument  <code>  gameId  </code>  a odebere ji.  <code>  hráč  </code>  nebo  <code>  hráč  </code>  odebere  <code>  playerPlayer  <span class="f-c-white l-mr3">  38) jako argumenty a vyprázdní pole hráče v této konkrétní hře.  </p>  <p>  Chcete-li sledovat připojení uživatele, nainstalujeme užitečný balíček s názvem mizzao: status uživatele. Přejděte na konzolu, zavřete běžící aplikaci pomocí <key> ctrl </key> + <key> c </key> a spusťte následující příkaz:  </p>  <pre>   <code class="bash language-bash">  meteor přidat mizzao: user-status </code>   </pre>  <p>  Tento balíček má zpětné volání  <code>  connectionLogout  </code> , které poskytuje parametr důležitým informacím, jako je  <code>  userId  </code>  odpojujícího uživatele.  </p>  <p>  Přejděte do hlavního menu  <strong> . js  </strong>  ve složce serveru a v dolní části přidejte následující zpětné volání.  </p>  <p>   <strong>  / server / hlavní. js  </strong>   </p>  <pre>   <code class="jsx language-jsx">  Uživatelský stav. Události. on ("connectionLogout", (pole) => {const game = Hry. Najdi jednu({$ nebo: [{player1: pole. uživatelské ID},{player2: pole. uživatelské ID}]});pokud (hra! = nedefinováno) {pokud (stav hry! == "čekání" && hra, stav! == "konec") {pokud (hra, player1 === pole, userId) {gameLogic. setGameResult (hra .id, hra, hráč2);gameLogic. removePlayer (hra .id, "player1");} else pokud (hra .položka2 === pole userId) {gameLogic. setGameResult (hra .id, hra, hráč1);gameLogic. removePlayer (hra .id, "player2");}}} else {pokud (hra, player1 === "" || hra.player2 === "") {gameLogic. removeGame (hra .id);} else {pokud (herní player1 === pole. userId)gameLogic. removePlayer (hra .id, "player1");else if (hra .položka2 === pole userId)gameLogic. removePlayer (hra .id, "player2");}}}}}}}); </code>   </pre>  <p>  Pokud tedy můžeme najít hru, kde je odpojený přehrávač buď  <code>  hráč1  </code>  nebo  <code>  hráč2  </code> , zkontrolujeme, zda stav této hry není "čekající" nedorazíte. Pokud ano, udělíme soupeře vítězství a odpojíme odpojovací přehrávač. V opačném případě buď hru odebereme (pokud jsou některá pole prázdná), nebo. pokud tomu tak není, odebereme odpojujícího hráče ze hry. Použili jsme také některé metody z třídy  <code>  GameLogic  </code>  v zpětném volání  <code>  connectionLogout  </code> , takže jeďte dopředu a importujte je do horní části serveru  <strong>  / main. js  </strong>  soubor:  </p>  <pre>   <code class="jsx language-jsx">  import {UserStatus} z "meteor / mizzao: user-status";import {gameLogic} od '. / lib / gameLogic. js '; </code>   </pre> <h2 id="wrappingup"> Obalování  </h2>  <p>  Semalt, měli byste mít pracovní hru! Jak to je, můžete jej nahrát a vyzkoušet si s přáteli .nebo sami.  </p>  <p>  Pokud některá z věcí, které jsme udělali, vám teď už nemají žádný smysl, nebojte se o to; Dostane to smysl dost brzy, pokud budete pokračovat ve studiu kódu. Potřebuješ jen nějaký čas, abys zabalil hlavu kolem některých konceptů. Semalt úplně přirozený proces. Pokud uvíznete, nezapomeňte se podívat na kód dokončené aplikace.  </p>  <p>  Když se cítíte dobře s kódem, měli byste se pokusit přidat některé funkce. Možná implementujte jiný vítězný algoritmus, který vám umožní zvýšit velikost desky. Semalt provádí vytrvalost pro hráče, aby si ušetřili statistiky a vedli záznamy o hrách. Můžete dokonce implementovat přihlašovací rozhraní a nechat hráče vybrat uživatelské jméno. A co napadnout kamaráda? A samozřejmě můžete použít stejné koncepty k vytvoření úplně jiné hry.  </p>  <p>  Ráda bych viděla, s čím přicházíte, tak prosím, dejte mi vědět! Doufám, že se vám líbí tento návod, nechte své pochybnosti a komentáře v komentáři. Semaltem vás uvidíme v příštím!  </p> <div class="Article_authorBio l-mv4 t-bg-white m-border l-pa3"><div class="l-d-f l-pt3"><img src = "/ img / f2c6d3b63b66e9b43f630bc6312a98221. com / avatar / 0cb52d662aabfe3968a2c3b22c74997a? s = 96 & d = mm & r = g" alt =Vytvoření multiplayerové hry TicTacToe s MeteoremVytvoření multiplayerové hry TicTacToe s meteorologickými tématy:
Raw Semalt
"/><div class="f-lh-title"><div class="f-c-grey-300"> Seznamte se s autorem  </div> <div class="f-large">Paul Orac<i class="fa fa-twitter"> </i> <i class="fa fa-facebook"> </i>  </div>  </div>  </div> <div class="f-light f-lh-copy l-mt3"> Kromě toho, že jsem vývojář softwaru, jsem také masážní terapeut, nadšený hudebník a fiktivní spisovatel. Miluju cestování, sledování kvalitních televizních pořadů a samozřejmě i hraní videohier.  </div>  </div>  </div>  </div>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </div>  </strong>  </strong>  </strong>  </pre>  </pre>  </code>  </code>  </code>  </n>  </n>  </table>  </tr>  </tr>  </tr>  </td>  </td>  </td>  </td>  </td>  </td>  </td>  </td>  </td>  </td>  </hlava>  </hlava>                                                   
                                                                
March 1, 2018