Erstellen Sie Ihr eigenes WebGL-Physikspiel

Dieses Projekt wird in verschiedene Teile aufgeteilt. Wir werden eine kurze Einführung in Heroku geben, zeigen, wie Physijs mit three.js verwendet wird, wie Socket-Ereignisse über Node.js behandelt werden und wie wir mit den gesendeten Daten umgehen.
01. Heroku
Dieses Projekt wird am gehostet Heroku Dies ist eine Cloud-Plattform zum Hosten Ihrer Apps. Es verfügt über eine Vielzahl unterstützter Sprachen wie Ruby, Java, PHP und Python. Wir werden Node.js verwenden.
Eröffnen Sie ein Konto und wählen Sie Node.js. Für dieses Projekt können wir den Basisserver verwenden, der kostenlos ist. Nach der Registrierung gelangen Sie zu Ihrem Dashboard, in dem Sie Ihre App erstellen können. Dadurch wird eine Subdomain bei herokuapp.com erstellt.
Als Bereitstellungsmethode können Sie entweder die Heroku-Befehlszeilenschnittstelle (CLI) für die Bereitstellung über das Git-Repository verwenden oder eine Verbindung zu GitHub oder Dropbox einrichten. Ich habe mich für die CLI entschieden. Dies erfordert eine Installation. Im Gegenzug erhalten Sie eine Vielzahl neuer hilfreicher Tools. Eines davon ist das Live-Debugging über Ihr Terminal.
Zum Einrichten Ihres Servers empfehle ich die folgenden Schritte wie hier beschrieben .
Zum Bereitstellen verwenden Sie Standard-Git-Befehle. Jeder von Ihnen verwendete wird den Build-Server auslösen und Ihre App wird auf dem Heroku-Server bereitgestellt und kann dann in Ihrer Subdomain angezeigt werden.
Sobald der Code bereitgestellt ist, können Sie Ihr Projekt unter [yourproject] .herokuapp.com anzeigen. Verwenden Sie zum Anzeigen der Protokolle den Befehl 'heroku logs - tail' in Ihrem Terminal. Einige der angezeigten Dinge werden dem Client bereitgestellt - sie zeigen die Socket-Verbindungen an. Wenn Sie Ihren Code debuggen möchten, können Sie auch die Datei console.log verwenden, um sie an das Terminal auszugeben.
02. Baue die Physikszene auf
Wir werden das beliebteste WebGL-Framework verwenden. three.js , um eine 3D-Szene mit einem Objekt zu erstellen, an das wir Physik anhängen. Die Physikbibliothek der Wahl ist Physijs , ein Plug-In für three.js. Als Erweiterung von three.js verwendet Physijs dieselbe Codierungskonvention, was die Verwendung erleichtert, wenn Sie bereits mit three.js vertraut sind.
Das erste ist der Billardtisch. Wir benutzen die Physijs HeightfieldMesh , weil dieses Netz die Höhe aus der PlaneGeometry liest. Es wird sich also im Grunde genommen um das three.js-Objekt wickeln.
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);
So HeightfieldMesh erfordert eine Geometrie, aber auch ein Physijs-Material. Wir fügen dem Material von three.js zwei neue Funktionen hinzu. Das sind die Reibung und Restitution Variablen. Reibung ist der Widerstand, den das Objekt leistet, und Restitution bezieht sich auf die „Hüpfburg“. Diese beiden Variablen definieren, wie real sich die Physik in Ihrer Szene anfühlt.
Für die erstellten Poolbälle möchten wir sie nicht zu federnd machen, also halten Sie die Anzahl niedrig. Wie bei three.js gibt es auch bei Physijs eine Reihe von Grundformen, die um das ursprüngliche Netz herumgehen. SphereMesh wickeln die SphereGeometry wird den Ball Physik geben. Bei der Initialisierung der Szene rufen wir an buildBall (8) , was die folgende Funktion auslöst ...
var buildBall = function(numberBall) { var ballTexture = new THREE.Texture(); var ballIndex = ball.length;
Fügen Sie die Textur hinzu:
ballTexture = THREE.ImageUtils.loadTexture('textures/' + numberBall + '_Ball.jpg', function(image) { ballTexture.image = image; });
Erstellen Sie das physijs-fähige Material mit einigen anständigen Reibungs- und Bounce-Eigenschaften:
var ballMaterial = Physijs.createMaterial( new THREE.MeshLambertMaterial({ map: ballTexture, shininess: 10, color: 0xdddddd, emissive: 0x111111, side: THREE.FrontSide }), .6, // friction .5 // restitution );
Textur-Mapping:
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]); };
Wir fügen Textur aus einer .jpg-Datei hinzu. Erstellen Sie das Material und verwenden Sie es für die SphereMesh um das Objekt zu erstellen, das wir vertikal nach oben platzieren, damit es auf den Bildschirm fällt.
03. Steckdosenverbindung
Für die Kommunikation zwischen dem Server und dem Client werden wir verwenden socket.io . Dies ist eine der zuverlässigsten Bibliotheken für Node.js. Es basiert auf der WebSockets-API.
Jetzt ist die Physik für die Netze aktiviert, für die wir Benutzereingaben benötigen, um das Spiel interaktiv zu gestalten. Das von uns verwendete Eingabegerät ist das mobile Gerät. Der mobile Browser ist der Controller, der Daten bereitstellt vom Beschleunigungsmesser und Gyroskop auf den Desktop, auf dem Sie das Spiel sehen.
Zunächst muss eine Verbindung zwischen dem mobilen Browser und dem Desktop-Browser hergestellt werden. Jedes Mal, wenn sich ein Browser mit unserer Node.js-App verbindet, müssen wir eine neue Verbindung herstellen. Eine clientseitige Verbindung wird wie folgt eingerichtet:
var socket = io.connect();
Zum Senden von Nachrichten verwenden Sie die emittieren Funktion:
socket.emit('event name', data);
Und für den Empfang verwenden Sie die .auf() Funktion:
socket.on('event name', function() {});
03.1. Einrichten des Desktop-Spiels
Wenn wir uns auf einem Desktop befinden, senden wir unseren Sockets ein Gerät, das unserem Server mit der folgenden Codezeile mitteilt, dass der Desktop das Spiel ist:
var socket = io.connect(); // when initial welcome message, reply with 'game' device type socket.on('welcome', function(data) { socket.emit('device', { 'type': 'game' }); });
Der Server gibt uns einen eindeutigen Schlüssel- / Spielcode zurück durch Krypto generiert . Dies wird auf dem Desktop angezeigt.
// 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
Weisen Sie den Spielclient an, den Spielcode zu initialisieren und dem Benutzer anzuzeigen.
socket.emit('initialize', gameCode);
03.2. Verbinde den Controller mit dem Spiel
Um das mobile Gerät mit dem Spiel zu verbinden, verwenden wir ein Formular, um den Spielcode vom Desktop-Bildschirm aus zu senden. Auf dem Formular senden wir den Spielcode zur Authentifizierung an den Server.
socket.emit('device', { 'type': 'controller', 'gameCode': gameCode });
Der Server prüft, ob der Spielcode gültig ist, und stellt die Verbindung zum Desktop-Spiel her
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', {}); }
Sobald die Verbindung hergestellt ist, geben wir dem 8-Ball mit dem folgenden Befehl einen kleinen Druck von x und z…
ball[0].setLinearVelocity(new THREE.Vector3(30, 0, 30));
04. Daten senden
Nachdem die Verbindung hergestellt ist, möchten wir die Kreisel- und Beschleunigungsmesservariablen an das Spiel senden. Mit dem window.ondevicemotion und das window.ondeviceorientation Bei Ereignissen verfügen wir über die Daten, die wir benötigen, um die gleichen Neigungsbewegungen unseres Telefons zum Billardtisch zu emulieren. Ich habe mich für ein Intervall von 100 ms entschieden, um diese Werte auszugeben.
setInterval(function() { socket.emit('send gyro', [Math.round(rotY), Math.round(rotX), ay, ax]); }, intervalTime);
Auf der Clientseite lösen wir die Latenz, indem wir die vom Server eingehenden Werte mit der Neigung der Billardtabelle in Verbindung bringen. Für das Tweening verwenden wir 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. Zusätzliche Ereignisse
Um die Interaktivität zu erhöhen, habe ich einige zusätzliche Ereignisse hinzugefügt, mit denen der Benutzer spielen kann. Wir geben dem Benutzer die Möglichkeit, zusätzliche Bälle neben dem 8-Ball hinzuzufügen, indem wir die Zahlen auf der Tastatur verwenden.
Eine andere Möglichkeit besteht darin, den Tisch nach oben zu hüpfen. Dazu können Sie die Leertaste drücken. Wir fügen aber auch ein Tap-Ereignis auf dem Controller-Gerät hinzu. Dadurch wird ein Ereignis an den Billardtisch gesendet, wodurch der Tisch angehoben und die Bälle hochgeschickt werden.
Zuerst müssen wir die Tastaturereignisse erfassen…
// 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(); } });
Das buildBall Funktion ist die gleiche Funktion, die wir verwendet haben, um die Kugel 8-Kugel zu erstellen. Wir verwenden nur verschiedene Texturen, die die Kugel umhüllen. Um den Tisch nach oben zu schieben, geben wir dem Tisch mit diesem Code eine Aufwärtsbewegung entlang der y-Achse…
table.setLinearVelocity(new THREE.Vector3(0, 500, 0));
Fazit
Wenn Sie ein Konzept für ein Spiel oder etwas anderes haben, ist es sehr wahrscheinlich, dass es Bibliotheken gibt, die Ihnen das Leben erleichtern könnten. Dies ist eine Demo, die zeigt, wie dies funktionieren kann. Wir hoffen, dass dies einige kreative Ideen hervorruft oder Ihnen bei Ihrem aktuellen Projekt hilft. Sehen Sie sich ein Live-Beispiel des Spiels an Hier oder finde es auf GitHub .
Dieser Artikel wurde ursprünglich in Ausgabe 300 von veröffentlicht Netz , das weltweit führende Magazin für professionelle Webdesigner und Entwickler. Ausgabe 300 kaufen oder Abonnieren Sie hier .
Zum Thema passende Artikel:
- Beginnen Sie mit webGL mit three.js
- 20 JavaScript-Tools, die Sie umhauen werden
- Erstellen Sie interaktive 3D-Grafiken mit three.js