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 2 - Vylepšování základní scény

V minulém díle, Vytvoř si vlastní webovou hru, jsem ukázal, jak vytvořit jednoduchou scénu, kam se dají přidávat krychličky pomocí klikání myší.

V tomto díle napíšu jak krychle zarovnám do mřížky, jak je z této scény mohu mazat pomocí pravého tlačítka myši, něco o materiálech a jak docílit hover efektu.

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

Zarovnání do mřížky

Pokud chci, aby se mi nová krychle zarovnala do mřížky, nemůžu používat přímo hodnotu pickInfo.picked­Point(viz. předchozí článek), ale musím to napsat malinko složitěji.

function onPointerUp(event) {
    const pickInfo = scene.pick(scene.pointerX, scene.pointerY);
    if (pickInfo.hit) {
        const currentMesh = pickInfo.pickedMesh;
        const newBox = currentMesh.clone();
        newBox.position = currentMesh.position.clone();// vytvářím novou krychli na stejné pozici.

        const diff = currentMesh.position.subtract(pickInfo.pickedPoint);// Beru rozdíl mezi středem krychle, na kterou jsem klikl a bodem na jejím povrchu, na který jsem klikl.
        // Pro každou dimenzi zjišťuji, zda v ní došlo k posunu právě o 0.5. Nepoužívám přesně 0.5, ale dávám tam toleranci 0.001, je to kvůli častému problému, kdy mám v proměnné místo 5 0.499999...
        ['x', 'y', 'z'].forEach((dimension) => {
            if (diff[dimension] >= 0.5 - 0.001) {
                newBox.position[dimension]--;
            } else
            if (diff[dimension] <= -0.5 + 0.001) {
                newBox.position[dimension]++;
            }
        });
    }
}

Mazání krychlí

Do funkce onPointerUp() přidáme switch, abychom určili, zda klikáme levým či pravým tlačítkem:

function onPointerUp(event) {
    const pickInfo = scene.pick(scene.pointerX, scene.pointerY);
    if (pickInfo.hit) {
        const currentMesh = pickInfo.pickedMesh;
        switch (event.button) {

            case 0:
                const newBox = BABYLON.Mesh.CreateBox("box", 1, scene);
                newBox.position = currentMesh.position.clone();

                const diff = currentMesh.position.subtract(pickInfo.pickedPoint);
                ['x', 'y', 'z'].forEach((dimension) => {
                    if (diff[dimension] >= 0.5 - 0.001) {
                        newBox.position[dimension]--;
                    }else
                    if (diff[dimension] <= -0.5 + 0.001) {
                        newBox.position[dimension]++;
                    }
                });
                break;

            case 2:
                currentMesh.dispose();// Každý mesh můžeme smazat velmi jednoduše zavoláním metody dispose.
                break;
        }

    }
}

Pokud však klikám na canvas pravým tlačítkem, vyskočí mi kontextové menu a to nechci. Pomocí události contextmenu a metody preventDefault() tomu zabráním:

function onContextMenu(event){event.preventDefault()}
canvas.addEventListener("contextmenu",onContextMenu, false);

Materiály

Všechny vytvořené krychle zatím dostávali defaultní šedý povrch. Abychom mohli docílit jiné, než základní šedé, potřebujeme použít materiály. Materiály určují vzhled jednotlivých meshů. Každý materiál se skládá ze 4 složek:

  • Ambient - Okolní konstantní osvětlení, co osvětluje předmět rovnoměrně bez ohledu na směr osvětlení.
  • Diffuse - Světlo rozptýlené do všech stran. Díky této složce je na předmětu vytvořený "3D efekt".
  • Specular - Světlo odrážející se převážně v jednom směru, co tvoří odlesk.
  • Emissive - Světlo vyzařované z meshe, hodí se např. pro vytvoření monitoru nebo kina ve scéně.

Pokud chceš vědět více přečti si něco o Phongově osvětlovacím modelu .

Každou z těhto 4 složek můžeme naplnit barvou nebo texturou. Existují i velmi pokročilé textury, pomocí kterých můžeme vytvořit efekt zrcadla, vodní kapku a místo statického obrázku zobrazovat video či na texturu kreslit, jako na canvas.

V této ukázce však budeme používat pouze jednobarevné materiály.

Ve funkci createScene() (před místo, kde vytvářím první krychli) vytvoříme dva materiály - jeden pro normální krychli a jeden pro krychli na které bude :hover efekt.

const materialNormal = new BABYLON.StandardMaterial("material-normal", scene);
materialNormal.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4);// Také bych mohl vyrobit barvu z hexadecimálního zápisu BABYLON.Color3.FromHexString("#666666");

const materialHover = new BABYLON.StandardMaterial("material-hover", scene);
materialHover.diffuseColor = new BABYLON.Color3(0.4, 1, 0.4);

A rovnou nastavíme materialNormal první krychli:

const box = BABYLON.Mesh.CreateBox("box", 1, scene);
box.material = materialNormal;

Poznámka: Typická věc pro BabylonJS je, že každá věc, která se váže s konkrétní instancí scény Camera, Mesh, Light, Material a mnoho dalších má název jako první parametr v konstruktoru a jako poslední parametr má scénu.

Hover efekt

Tam, kde se nachází posluchač události pointerup, přidám navíc posluchač události pointermove.

let lastMesh = null;
function onPointerMove(event) {
    if (lastMesh) {
        lastMesh.material = materialNormal;
    }
    const pickInfo = scene.pick(scene.pointerX, scene.pointerY);
    if (pickInfo.hit) {
        const currentMesh = pickInfo.pickedMesh;
        currentMesh.material = materialHover;
        lastMesh = currentMesh;
    } else {
        lastMesh = null;
    }

}
canvas.addEventListener("pointermove", onPointerMove, false);

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.

V dalším díle, Stav hry, ukáži, jak můžu držet stav celé aplikace.


 

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 82x (4.07 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Předchozí článek
Vytvoř si vlastní webovou hru
Všechny články v sekci
WebGL a BabylonJS - 3D webová hra
Přeskočit článek
(nedoporučujeme)
Stav hry
Článek pro vás napsal Pavol Hejný
Avatar
Uživatelské hodnocení:
3 hlasů
/^(web )?(app )?developer$/
Aktivity