IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 1 - Vytvoř si vlastní webovou hru

Vítej u prvního dílu seriálu, ve kterém ti ukážu, jak vyrobit vlastní 3D webovou hru. V tomto seriálu bych rád začal jednoduchou 3D scénou, kterou budu postupně rozvíjet do plnohodnotné 3D multiplayer realtime webové hry. Mám promyšlených několik článků dopředu a dál nechávám vše otevřené. Pokud se chceš připojit, můžeš přispívat na GitHubu kde budeme vždy o krok napřed před tímto tutoriálem. Nebo můžeš napsat či přijít na Povídací sraz ITnetwork a říct, co bys rád zlepšil.

Vše budu vyvíjet na GitHubu a sem budu vždy psát poslední krok formou tutoriálu.

Až bude mít hra serverovou část umístím ji online na samostatnou doménu.

Webová hra - WebGL a BabylonJS - 3D webová hra

Hra na webu vs. webová hra

Hned na začátku bych rád vysvětlil, proč dělám hru v JavaScriptu a ne v herním enginu jako např. Unity, kterou bych následně vyexportoval na web či dal na stažení na svůj web a na Steam. Rád bych docílil toho, aby hra kterou vytvořím, měla všechny vlastnosti, díky kterým jsou webové aplikace tak skvělé:

  • Nechci žádné zdlouhavé načítání. Chci, aby po zadání adresy hra prostě běžela.
  • Chci mít možnost hru spustit na mnoha záložkách prohlížeče, tak aby se jednotlivé instance vzájemně nerozbily.
  • Chci plně využít URL adresu. Tzn. když ve hře udělám nějaký postup, chci aby se mi promítl do URL. Pokud toto URL někomu pošlu, chci aby byl ve stejném stavu jako já.
  • Chci, aby mi fungovala tlačítka prohlížeče - zpět a vpřed.
  • Chci, aby vyhledávače uměli moji hru projít a zaindexovat.
  • Chci, abych mohl místa a části mé hry sdílet na sociálních sítích s plně fungujícím nadpisem, popiskem a náhledem.

Chtěl bych se tím zároveň odlišit od her na webu, které sám definuju takto:

  • Je umístěna na jedné HTML stránce, která obvykle slouží pouze jako "obal" na hru, kterou obvykle obalí reklamou + nějakým stručným návodem a ošklivým pozadím.
  • Má jednu URL adresu.
  • Pokud stránku obnovím, mám po rozehrané hře. To samé platí pokud omylem kliknu na nějaký odkaz či tlačítko zpět.
  • Obvykle není responzivní.

Vývoj

Hru budu vytvářet ve WebGL frameworku BabylonJS, na držení stavu hry zvolím Redux+Immutable.js, na tvorbu UI využiji React, na mnoho různých věcí Lodash a jistě další frameworky a nástroje. Prvních několik článků napíšu v ES6, aby vše fungovalo přímo v nových prohlížečích bez transpilace, potom přejdu na TypeScript a využiji Gulp a Webpack.

Pokud ti bude připadat, že se dá něco udělat lépe, určitě mi napiš! Mám zkušenosti s vývojem webů, her, her na webu i webových her, ale jistě se v mnohých věcech můžu mýlit, či používat horší postup, než bys uměl ty. Sám bych rád zužitkoval mnohaleté zkušenosti s vývojem hry Towns a vývojem galerií na webu a vytvořil něco nového a zajímavého.

Na konci dnešního článku budeš vědět, jak vytvořit editovatelnou a interaktivní 3D scénu pomocí WebGL frameworku BabylonJS.

Vytvoření první jednoduché 3D scény

Nejdříve vytvořím čistý index.html a přidám do něj knihovny BabylonJS a polyfill HandJS, který slouží ke sjednocení událostí myši a dotykových zařízení.

<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 těla html stránky přidám canvas s id "scene".

<canvas id="scene"></canvas>

Canvas roztáhnu na plnou velikost stránky.

#scene {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  touch-action: none;
}

Poté definuji funkci, která vytvoří základní scénu, ta může být v samostatném .js souboru nebo přímo 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ě - krychli 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;
}

Zatím jsem pouze napsal funkci, která mi 3D scénu vytvoří. Nyní tuto funkci použiji: Kód který píšu musí být spuštěn až po vytvoření canvasu - tzn. script musí být umístěn pod canvasem nebo to celé musí být obaleno událostí 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é funkce vytvořím scénu.

Ještě je potřeba rozhýbat scénu:

engine.runRenderLoop(function() {
  scene.render();
});

Teď už máme vytvořenou scénu s krychlí, která plně funguje. Ještě je potřeba zajistit, aby se při změně velikosti okna scéna přizpůsobovala:

window.addEventListener("resize", function() {
  engine.resize();
});

Události

Ve scéně napsané výše si můžeme s 3D krychlí otáčet a zoomovat (díky metodě attachControl() na kameře), ale to je vše. V další části článku do scény přidám větší interaktivitu.

Do funkce createScene() přidám na konec posluchač na událost pointerup na canvasu. Ta se zavolá jak při klepnutí myši, tak při dotyku na obrazovku (a na starších prohlížečích funguje právě díky polyfillu HandJS, který jsem přidával hned na začátku článku.)

Při zavolání funkce onPointerUp se krychle posune o 1 na ose y.

function onPointerUp(event) {
    box.position.y++;
}

canvas.addEventListener("pointerup", onPointerUp, false);

Zatím ukázka funguje tak, že se při klepnutí kamkoliv na canvas posune krychle o 1 nahoru. V následující úpravě to udělám tak, aby se krychle posunula pouze pokud klepnu na ni.

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++;
    }
}

Pokud by nyní bylo ve scéně více krychlí, posunula by se vždy ta, na kterou jsem klikl.

Krychli však nemusím posouvat pouze jedním směrem, mohu je posunout tím směrem, na který jsem na její povrch klikl. To docílím pomocí hodnoty pickInfo.picked­Point.

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áření nových krychlí

Velmi jednoduchou úpravou mohu na nové pozici vytvářet nové krychle:

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();
    }
}

Rozdělanou hru si můžeš stáhnout pod článkem, nebo jít do Git repozitáře, kde najdeš nejnovější verzi zdrojových kódů. Nebo si ji rovnou můžeš vyzkoušet na webappgames.git­hub.io/web-game.

WebGL a BabylonJS - 3D webová hra

V dalším díle, Vylepšování základní scény, ukáži, jak mohu krychle zarovnat do mřížky a jak je mazat. Napíši něco k materiálům a jak díky tomu mohu provádět hover efekt podobný css.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 265x (2.23 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Všechny články v sekci
WebGL a BabylonJS - 3D webová hra
Přeskočit článek
(nedoporučujeme)
Vylepšování základní scény
Článek pro vás napsal Pavol Hejný
Avatar
Uživatelské hodnocení:
16 hlasů
/^(web )?(app )?developer$/
Aktivity