Byg dit eget WebGL-fysikspil

Dette projekt opdeles i forskellige dele. Vi vil give en kort introduktion til Heroku, vise, hvordan man bruger Physijs med three.js, forklare, hvordan man håndterer sockethændelser over Node.js, og også hvordan vi håndterer de sendte data.

01. Heroku

Heroku er en nem at bruge og gratis at prøve node.js webserver

Heroku er en nem at bruge og gratis at prøve node.js webserver

Dette projekt vil være vært den Heroku , som er en cloudplatform til at være vært for dine apps. Det har en bred vifte af understøttede sprog som Ruby, Java, PHP og Python. Vi skal bruge Node.js.



Tilmeld dig en konto, og vælg Node.js. Til dette projekt kan vi bruge basisserveren, som er gratis. Efter registrering kommer du til dit dashboard, hvor du kan oprette din app. Dette opretter et underdomæne på herokuapp.com.

Som en implementeringsmetode kan du vælge enten at bruge Heroku Command Line Interface (CLI) til at implementere ved hjælp af sit git-arkiv eller have en forbindelse oprettet til GitHub eller Dropbox. Jeg har valgt at gå med dens CLI; dette kræver en installation. Men til gengæld får du en række nye nyttige værktøjer, en af ​​disse er live debugging gennem din terminal.

hvordan man laver vektorformer i Photoshop

For at konfigurere din server anbefaler jeg at følge trinene som beskrevet her .

For at implementere bruger du standard git-kommandoer. Hver, du bruger, udløser build-serveren, og din app vil blive implementeret på Heroku-serveren og kan derefter ses på dit underdomæne.

Når koden er implementeret, kan du se dit projekt på [yourproject] .herokuapp.com. For at se logfilerne skal du bruge kommandoen 'heroku logs - tail' i din terminal. Nogle af de ting, der vises, er, hvad der serveres til klienten - det viser sokkelforbindelserne, og hvis du vil fejle din kode, kan du også bruge console.log for at sende til terminalen.

02. Byg fysikscenen

Tryk på din skærm eller tryk på mellemrumstasten for at hoppe tabellen op

Tryk på din skærm eller tryk på mellemrumstasten for at hoppe tabellen op

Vi bruger den mest populære WebGL-ramme, three.js , for at opbygge en 3D-scene, der indeholder et objekt, som vi vedhæfter fysik på. Det valgte fysikbibliotek er Physijs , et plug-in til three.js. Som en udvidelse til three.js bruger Physijs den samme kodningskonvention, hvilket gør det lettere at bruge, hvis du allerede er bekendt med three.js.

Den første ting er poolbordet. Vi bruger Physijs HeightfieldMesh , fordi dette maske læser højden fra PlaneGeometry. Så det vil dybest set vikle sig rundt om three.js-objektet.

var tableGeometry = new THREE.PlaneGeometry(650, 500, 10, 10); var tableMaterial = Physijs.createMaterial( new THREE.MeshPhongMaterial({ shininess: 1, color: 0xb00000, emissive: 0x111111, side: THREE.DoubleSide }), .8, // friction .4 // restitution ); table = new Physijs.HeightfieldMesh(tableGeometry, tableMaterial, 0);

HeightfieldMesh kræver en geometri, men også et Physijs-materiale. Vi tilføjer to nye funktioner til three.js-materialet. Det er de friktion og restitution variabler. Friktion er den modstand, objektet gør, og restitution henviser til 'bounciness'. Disse to variabler vil definere, hvor ægte fysikken vil føles i din scene.

For de oprettede poolkugler ønsker vi ikke at gøre dem for hoppende, så hold antallet lavt. Ligesom three.js har Physijs også en række grundlæggende former til at gå rundt om det originale mesh. SphereMesh indpakning af SphereGeometry vil give bolden fysik. Når vi initialiserer scenen, ringer vi buildBall (8) , som udløser følgende funktion ...

var buildBall = function(numberBall) { var ballTexture = new THREE.Texture(); var ballIndex = ball.length;

Tilføj tekstur:

ballTexture = THREE.ImageUtils.loadTexture('textures/' + numberBall + '_Ball.jpg', function(image) { ballTexture.image = image; });

Opret det fysijs-aktiverede materiale med nogle anstændige friktions- og bounceegenskaber:

var ballMaterial = Physijs.createMaterial( new THREE.MeshLambertMaterial({ map: ballTexture, shininess: 10, color: 0xdddddd, emissive: 0x111111, side: THREE.FrontSide }), .6, // friction .5 // restitution );

Kortlægning af tekstur:

ballMaterial.map.wrapS = ballMaterial.map.wrapT = THREE.RepeatWrapping; ballMaterial.map.repeat.set(1, 1); Create the physics-enabled SphereMesh, and start it up in the air: ball[ballIndex] = new Physijs.SphereMesh( new THREE.SphereGeometry(25, 25, 25), ballMaterial, 100 ); // y offset to the top of the canvas ball[ballIndex].position.y = 500; // shadows ball[ballIndex].receiveShadow = true; ball[ballIndex].castShadow = true; // add the ball to your canvas scene.add(ball[ballIndex]); };

Vi tilføjer tekstur fra en .jpg-fil. Opret materialet og brug det til SphereMesh for at oprette objektet, som vi placerer lodret til toppen, så det falder ind på skærmen.

03. Stikforbindelse

Hovedmålet med vores spil er at efterligne de fysiske bevægelser til skærmen

Hovedmålet med vores spil er at efterligne de fysiske bevægelser til skærmen

Til kommunikation mellem serveren og klienten bruger vi stikkontakt.io . Dette er et af de mest pålidelige biblioteker, der er tilgængelige for Node.js. Det er bygget oven på WebSockets API.

Nu er fysik aktiveret for de masker, vi har brug for brugerinput for at gøre spillet interaktivt. Den inputenhed, vi bruger, er den mobile enhed. Mobilbrowseren er den controller, der leverer data fra accelerometer og gyroskop til skrivebordet, hvor du vil se spillet.

For det første skal der oprettes en forbindelse mellem mobilbrowseren og desktopbrowseren. Hver gang en browser opretter forbindelse til vores Node.js-app, skal vi oprette en ny forbindelse. En klientsideforbindelse oprettes ved hjælp af følgende:

var socket = io.connect();

For at sende beskeder bruger du udsender fungere:

socket.emit('event name', data);

Og til modtagelse skal du bruge .på() fungere:

socket.on('event name', function() {});

03.1. Opsætning af desktop-spillet

Hvis vi er på et skrivebord, sender vi vores stikkontakter, som en enhed udsender, der fortæller vores server, at skrivebordet er spillet ved hjælp af følgende linje kode:

var socket = io.connect(); // when initial welcome message, reply with 'game' device type socket.on('welcome', function(data) { socket.emit('device', { 'type': 'game' }); });

Serveren returnerer os en unik nøgle / spilkode genereret af krypto . Dette vises på skrivebordet.

// generate a code var gameCode = crypto.randomBytes(3).toString('hex').substring(0, 4).toLowerCase(); // ensure uniqueness while (gameCode in socketCodes) { gameCode = crypto.randomBytes(3).toString('hex').substring(0, 4).toLowerCase(); } // store game code -> socket association socketCodes[gameCode] = io.sockets.sockets[socket.id]; socket.gameCode = gameCode

Bed spilklienten om at initialisere og vise spilkoden til brugeren ...

socket.emit('initialize', gameCode);

03.2. Tilslut controlleren til spillet

For at forbinde den mobile enhed til spillet bruger vi en formular til at indsende spilkoden fra skrivebordsskærmen. På formularen indsender vi spilkoden til serveren til godkendelse.

socket.emit('device', { 'type': 'controller', 'gameCode': gameCode });

Serveren kontrollerer, om spilkoden er gyldig, og vil oprette forbindelsen til desktop-spillet

if (device.gameCode in socketCodes) { // save the game code for controller commands socket.gameCode = device.gameCode // initialize the controller socket.emit('connected', {}); // start the game socketCodes[device.gameCode].emit('connected', {}); }

Når forbindelsen er klar, giver vi 8-kuglen et lille skub fra x og z med følgende kommando ...

ball[0].setLinearVelocity(new THREE.Vector3(30, 0, 30));

04. Afsendelse af data

Nu hvor forbindelsen er oprettet, vil vi sende gyro- og accelerometervariablerne til spillet. Ved at bruge window.ondevicemotion og vindue.indretningsorientering hændelser, har vi de data, vi har brug for, for at efterligne de samme vippebevægelser på vores telefon til poolbordet. Jeg har valgt at bruge et interval på 100 ms til at udsende disse værdier.

setInterval(function() { socket.emit('send gyro', [Math.round(rotY), Math.round(rotX), ay, ax]); }, intervalTime);

På klientsiden løser vi latenstiden ved at afveje de indgående værdier fra serveren til vipningen af ​​poolbordet. Til interpolering bruger vi TweenMax .

// handle incoming gyro data socket.on('new gyro', function(data) { var degY = data[1] < 0 ? Math.abs(data[1]) : -data[1]; TweenMax.to(table.rotation, 0.3, { x: degToRad(degY - 90), y: degToRad(data[0]), ease: Linear.easeNone, onUpdate: function() { table.__dirtyRotation = true; } }); });

05. Ekstra begivenheder

Flere bolde er lig med mere sjov. Prøv at ramme mellemrumstasten eller trykke på skærmen på din mobil

Flere bolde er lig med mere sjov. Prøv at ramme mellemrumstasten eller trykke på skærmen på din mobil

For at give det lidt mere interaktivitet har jeg tilføjet et par ekstra begivenheder, som brugeren kan lege med. Vi giver brugeren mulighed for at tilføje ekstra bolde ved siden af ​​8-kuglen ved hjælp af numrene på tastaturet.

En anden er at hoppe bordet opad. For dette kan du ramme mellemrumstasten. Men vi tilføjer også en trykhændelse på controller-enheden. Dette sender en begivenhed til poolbordet, som hæver bordet og sender kuglerne op.

Først skal vi fange tastaturbegivenhederne ...

// create balls / slam table on spacebar document.addEventListener('keydown', function(e) { if (e.keyCode == 49) { // key: 1 buildBall(1); } else if (e.keyCode == 50) { // key: 1 buildBall(2); } else if (e.keyCode == 51) { // key: 1 buildBall(3); } else if (e.keyCode == 32) { // key: spacebar bounceTable(); } });

Det buildBall funktion er den samme funktion, som vi brugte til at skabe kuglen 8-kugle. Vi bruger bare forskellige strukturer, der omslutter sfæren. For at skubbe bordet op, giver vi bordet en opadgående bevægelse langs y-aksen med denne kode ...

table.setLinearVelocity(new THREE.Vector3(0, 500, 0));

Konklusion

Tilføj flere bolde og se, hvor meget din browser kan klare

Tilføj flere bolde og se, hvor meget din browser kan klare

Når du har et koncept til et spil eller noget andet, er det meget sandsynligt, at der er biblioteker derude, der kan gøre dit liv lettere. Dette er en demo, der viser, hvordan dette kan fungere. Vi håber, at dette vil hjælpe med at udløse nogle kreative ideer eller hjælpe dig med dit nuværende projekt. Se et live eksempel på spillet her eller find den på GitHub .

Denne artikel blev oprindeligt offentliggjort i nummer 300 af net , verdens topmagasin for professionelle webdesignere og udviklere. Køb nummer 300 eller abonner her .

Relaterede artikler: