Upgrade to Pro — share decks privately, control downloads, hide ads and more …

NOVIE - Workshop

Vlad Goran
November 20, 2014

NOVIE - Workshop

Demoing building a simple 3d multiplayer game for a workshop for ITFest Bucharest 2014

Vlad Goran

November 20, 2014
Tweet

More Decks by Vlad Goran

Other Decks in Programming

Transcript

  1. Myself - ten years XP as a Web Developer -

    ActionScript fanatic back in the day - Javascript, HTML5 enthusiast - in a complicated relationship with 3D - doing my first workshop - vladgoran.ro
  2. OKAPI Studio - proud sponsors of IT Fest - a

    fun bunch of really talented people - a great place to work - internationally renown clients - challenging projects
  3. Tools - git - bower - WebGL (trough canvas) -

    Three.js / ThreeX.js - Cannon.js - Sound API (through Howler) - sockets if there’s time :)
  4. CSS <style> body { margin: 0; padding: 0; overflow: hidden;

    } canvas { width: 100%; height: 100% } </style>
  5. Get the javascript via bower > bower install threex.cannonjs >

    bower install threex.keyboardstate > bower install howler.js
  6. Add them to your page <script src="bower_components/threex.cannonjs/examples/vendor/three.js/build/three.min.js"></script> <script src="bower_components/threex.cannonjs/vendor/cannon.js/build/cannon.js"></script> <script

    src="bower_components/threex.cannonjs/threex.cannonbody.js"></script> <script src="bower_components/threex.cannonjs/threex.cannonworld.js"></script> <script src="bower_components/threex.keyboardstate/threex.keyboardstate.js"></script> <script src="bower_components/howler.js/howler.js"></script>
  7. SETUP: Camera var camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1,

    1000 ); camera.position.x = 60; camera.position.y = 80; camera.position.z = 0; camera.lookAt(scene.position);
  8. Objects: Plane var plane = function generatePlane () { var

    planeSize = 50; var geometry = new THREE.CubeGeometry(planeSize, 1, planeSize, 1, 1, 1); var material = new THREE.MeshBasicMaterial({color: 0xffffff}); var mesh = new THREE.Mesh(geometry, material); mesh.position.y = -.5; scene.add(mesh); return mesh; } ();
  9. Objects: Spheres var generateSphere = function (color, y, name) {

    var geometry = new THREE.SphereGeometry(1, 10, 10); var material = new THREE.MeshBasicMaterial({color: color || 0x00000, wireframe: true}); var mesh = new THREE.Mesh(geometry, material); mesh.position.y = y; mesh.isSphere = true; scene.add(mesh); mesh.name = name; return mesh; };
  10. Still boring: Add physics - create a physical world -

    create a contact material - var updateFcts = []; - wrap objects in physics Bodies - update the render loop - place them high up and let them fall
  11. Add physics: Contact Material var stoneMaterial = new CANNON.Material('stone'); worldX.world.addContactMaterial(new

    CANNON.ContactMaterial( stoneMaterial, stoneMaterial, 0.1, // Friction 0.1 // Restitution ));
  12. Add physics: Physics Bodies var physicsBody = new THREEx.CannonBody({ mesh:

    mesh, material: stoneMaterial, mass: 100 }).addTo(worldX);
  13. Add physics: New render loop var animate = function animate(nowMs)

    { requestAnimationFrame(animate); // measure time lastTimeMs = lastTimeMs || nowMs - 1000 / 60; var deltaMs = Math.min(200, nowMs - lastTimeMs); lastTimeMs = nowMs; // call each update function updateFcts.forEach( function (updateFn) { updateFn(deltaMs / 1000, nowMs / 1000); } ); }; var lastTimeMs = null; requestAnimationFrame(animate);
  14. Controls: angularVelocity var speed = 20; if (keyboard.pressed(keys.left)) { target.body.angularVelocity.x

    = speed; } else if (keyboard.pressed(keys.right)) { target.body.angularVelocity.x = -speed; } else { target.body.angularVelocity.x = 0; } if (keyboard.pressed(keys.up)) { target.body.angularVelocity.z = speed; } else if (keyboard.pressed(keys.down)) { target.body.angularVelocity.z = -speed; } else { target.body.angularVelocity.z = 0; }
  15. Controls: angularVelocity var generateControls = function (target, keys) { return

    function () { var speed = 20; if (keyboard.pressed(keys.left)) { … } ... }; updateFcts.push(generateControls(redSphere, {left: 'left', right: 'right', up: 'up', down: 'down'})); updateFcts.push(generateControls(blueSphere, {left: 'a', right: 'd', up: 'w', down: 's'}));
  16. Add events: Death var deathY = -30; updateFcts.push(function () {

    if (blueSphere.body.position.y < deathY && !blueSphere.isDead) { sphereDied(blueSphere); } if (redSphere.body.position.y < deathY && !redSphere.isDead) { sphereDied(redSphere); } });
  17. Add events: Death (2) var sphereDied = function (target) {

    target.isDead = true; console.log(target.name, 'died'); //sound.play('death'); //resetScene(); };
  18. Add events: Collision physicsBody.body.addEventListener("collide", function (e) { if (e.with.userData.object3d.isSphere) {

    console.log(e.with.userData.object3d.name, 'collided with', name); //sound.play('impact'); } });
  19. Add Sound var sound = function () { var base

    = 'http://vladgoran. ro/games/novie/'; var sounds = { impact: new Howl({ urls: [base + 'sounds/impact.mp3'], volume: 0.5 }), death: new Howl({ urls: [base + 'sounds/death.mp3'], volume: 0.5 }) ... ... return { play: function (id) { if (sounds[id]) { return sounds[id].play(); } return false; } }; }();
  20. Play the sound physicsBody.body.addEventListener("collide", function (e) { if (e.with.userData.object3d.isSphere) {

    console.log(e.with.userData.object3d.name, 'collided with', name); sound.play('impact'); } });
  21. Refactoring: initScene var initScene = function () { redSphere =

    generateSphere(0xff0000, 5, 'red'); blueSphere = generateSphere(0x0000ff, 2, 'blue'); updateFcts.push(generateControls(redSphere, {left: 'left', right: 'right', up: 'up', down: 'down'})); updateFcts.push(generateControls(blueSphere, {left: 'a', right: 'd', up: 'w', down: 's'})); worldX.start(); }; initScene(); remove worldX.start
  22. Refactoring: resetSphere var resetSphere = function (target) { target.body.position.x =

    target.body.initPosition.x; target.body.position.y = target.body.initPosition.y; target.body.position.z = target.body.initPosition.z; target.body.velocity.x = 0; target.body.velocity.y = 0; target.body.velocity.z = 0; };