1. diel - Vytvor si vlastný webovú hru
Vitaj u prvého dielu seriálu, v ktorom ti ukážem, ako vyrobiť vlastné 3D webovú hru. V tomto seriáli by som rád začal jednoduchú 3D scénou, ktorú budem postupne rozvíjať do plnohodnotnej 3D multiplayer realtime webové hry. Mám premyslených niekoľko článkov dopredu a ďalej nechávam všetko otvorené. Ak sa chceš pripojiť, môžeš prispievať na GitHub kde budeme vždy o krok vpred pred týmto tutorialom. Alebo môžeš napísať či prísť na Chatovacie zraz ITnetwork a povedať, čo by si rád zlepšil.
Všetko budem vyvíjať na GitHub a sem budem vždy písať posledný krok formou tutoriálu.
Keď bude mať hra serverovú časť umiestnim ju online na samostatnú doménu.
Hra na webe vs. webová hra
Hneď na začiatku by som rád vysvetlil, prečo robím hru v JavaScripte a nie v hernom engine ako napr. Unity, ktorú by som následne vyexportovali na web či dal na stiahnutie na svoj web a na Steam. Rád by som docielil toho, aby hra ktorú vytvorím, mala všetky vlastnosti, vďaka ktorým sú webové aplikácie tak skvelé:
- Nechcem žiadne zdĺhavé načítanie. Chcem, aby po zadaní adresy hra jednoducho bežala.
- Chcem mať možnosť hru spustiť na mnohých záložkách prehliadača, tak aby sa jednotlivé inštancie vzájomne nerozbili.
- Chcem plne využiť URL adresu. Tzn. keď v hre urobím nejaký postup, chcem aby sa mi premietol do URL. Pokiaľ toto URL niekomu pošlem, chcem aby bol v rovnakom stave ako ja.
- Chcem, aby mi fungovala prehliadačová tlačidla späť a vpred.
- Chcem, aby vyhľadávače vedeli moji hru prejsť a zaindexovať.
- Chcem, aby som mohol miesta a časti mojej hry zdieľať na Sociálna sieťach s plne fungujúcim nadpisom, popiskom a náhľadom.
Chcel by som sa tým zároveň odlíšiť od hier na webe, ktoré sám definujte nasledovne:
- Je umiestnená na jednej HTML stránke, ktorá zvyčajne slúži len ako "obal" na hru, ktorú zvyčajne obalí reklamou + nejakým stručným návodom a škaredým pozadím.
- Má jednu URL adresu.
- Ak stránku obnovím, mám po rozohranej hre. To isté platí pokiaľ omylom kliknem na nejaký odkaz či tlačidlo späť.
- Zvyčajne nie je responzívne.
Vývoj
Hru budem vytvárať vo WebGL frameworku BabylonJS, na držanie stave hry zvolím Redux + Immutable.js, na tvorbu UI využijem React, na mnoho rôznych vecí Lodash a určite ďalšie frameworky a nástroje. Prvých niekoľko článkov napíšem v ES6, aby všetko fungovalo priamo v nových prehliadačoch bez transpilace, potom prejdem na TypeScript a využijem Gulp a Webpack.
Ak ti bude pripadať, že sa dá niečo urobiť lepšie, určite mi napíš! Mám skúsenosti s vývojom webov, hier, hier na webe i webových hier, ale iste sa v mnohých veciach môžem mýliť, či používať horšie postup, než by si vedel ty. Sám by som rád zužitkoval mnohoročné skúsenosti s vývojom hry Towns a vývojom galérií na webe a vytvoril niečo nové zaujímavé.
Na konci dnešného článku budeš vedieť, ako vytvoriť editovateľnú a interaktívne 3D scénu pomocou WebGL frameworku BabylonJS.
Vytvorenie prvej jednoduchej 3D scény
Najskôr vytvorím čistý index.html a pridám do neho knižnice BabylonJS a polyfill HandJS, ktorý slúži k zjednoteniu udalostí myši a dotykových zariadení.
<script src="https://cdnjs.cloudflare.com/ajax/libs/babylonjs/2.5.0/babylon.max.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/handjs/1.3.11/hand.js"></script>
Potom do tela html stránky pridám canvas s id "scene".
<canvas id="scene"></canvas>
Canvas rozostriem na plnú veľkosť stránky.
#scene { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; touch-action: none; }
Potom definujú funkciu, ktorá vytvorí základný scénu, tá môže byť v samostatnom .js súbore alebo priamo v index.html.
function createScene(canvas, engine) { //Vytvoření scény a nastavení základní barvy na bílou const scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(1,1,1); //Vytvořím kameru, nastavím ji fov(field of view) a pomocí metody attachControl nastavím ať kamera reaguje na události. const camera = new BABYLON.ArcRotateCamera("Camera",Math.PI/4, Math.PI/4, 10, BABYLON.Vector3.Zero(), scene); camera.fov = 1.2; camera.attachControl(canvas, true); //Vytvořím osvětlení scény const light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 1/2), scene); //Vytvořím první mesh ve scéně - krychly o rozměrech 1x1x1. Mesh je 3D babylon objekt ve scéně, aby však nedocházelo ke zmatkům, budu je nazývat prostě mesh. const box = BABYLON.Mesh.CreateBox("box", 1, scene); return scene; }
Zatiaľ som len napísal funkciu, ktorá mi 3D scénu vytvoria. Teraz túto funkciu použijem: Kód ktorý píšem musí byť spustený až po vytvorení canvasu - tzn. script musí byť umiestnený pod Canvas alebo to celé musí byť obalené udalostí onload.
var canvas = document.getElementById("scene");//Najdu canvas v DOMu. var engine = new BABYLON.Engine(canvas, true);//Vytvořím Babylon engine. var scene = createScene(canvas, engine);//Pomocí mnou definované funce vytvořím scénu.
Ešte je potreba rozhýbať scénu.
engine.runRenderLoop(function() { scene.render(); });
Teraz už máme vytvorenú scénu s kockou, ktorá plne funguje. Ešte je potrebné zabezpečiť, aby sa pri zmene veľkosti okna scéna prispôsobovala.
window.addEventListener("resize", function() { engine.resize(); });
Udalosti
V scéne napísané vyššie si môžeme s 3D kockou otáčať a zoomovať (vďaka metóde attachControl na kamere), ale to je všetko. V ďalšej časti článku do scény pridám väčšiu interaktivitu.
Do funkcie createScene pridám na koniec poslucháč na udalosť pointerup na canvasu. Tá sa zavolá ako pri kliknutí myšou, tak pri dotyku na obrazovku (a na starších prehliadačoch funguje práve vďaka polyfillem HandJS, ktorý som pridával hneď na začiatku článku.)
Pri zavolaní funkcie onPointerUp sa kocky posunie o 1 na osi y.
function onPointerUp(event) { box.position.y++; } canvas.addEventListener("pointerup", onPointerUp, false);
Zatiaľ ukážka funguje tak, že sa pri kliknutí kamkoľvek na canvas posunie kocky o 1 hore. V nasledujúcej úprave to urobím tak, aby sa kocka posunula iba ak klepnem na ňu.
function onPointerUp(event) { //Zjistím informace o bodu, na který jsem klepl. const pickInfo = scene.pick(scene.pointerX, scene.pointerY); //Pomocí klíče hit zjistím, zda jsem klepl na nějaký mesh ve scéně nebo do prázdna. if (pickInfo.hit) { //Zjistím konkrétní mesh, na který jsem klepl a ten posunu. const currentMesh = pickInfo.pickedMesh; currentMesh.position.y++; } }
Ak by teraz bolo v scéne viac kociek, posunula by sa vždy tá, na ktorú som klikol.
Kocku však nemusím posúvať iba jedným smerom, môžem ich posunúť tým smerom, na ktorý som na jej povrch klikol. To docielim pomocou hodnoty pickInfo.pickedPoint.
function onPointerUp(event) { const pickInfo = scene.pick(scene.pointerX, scene.pointerY); if (pickInfo.hit) { const currentMesh = pickInfo.pickedMesh; currentMesh.position = pickInfo.pickedPoint.clone();//Je bezpečnější pozici naklonovat, než předávat tu samou instanci pozice. } }
Vytváranie nových kociek
Veľmi jednoduchou úpravou môžem na novej pozícii vytvárať nové kocky.
function onPointerUp(event) { const pickInfo = scene.pick(scene.pointerX, scene.pointerY); if (pickInfo.hit) { const currentMesh = pickInfo.pickedMesh; const newBox = currentMesh.clone(); newBox.position = pickInfo.pickedPoint.clone(); } }
Rozrobenú hru si môžeš stiahnuť pod článkom, alebo ísť do Git repozitára, kde nájdeš najnovšiu verziu zdrojových kódov. Alebo si ju rovno môžeš vyskúšať na webappgames.github.io/web-game. V ďalšom diele ukážem, ako môžem kocky zarovnať do mriežky, ako kocky mazať. Napíšem niečo k materiálom a ako vďaka tomu môžem vykonávať hoover efekt podobný css.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 269x (2.23 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript