Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Multiplayer böngészőben

Hasonló előadás


Az előadások a következő témára: "Multiplayer böngészőben"— Előadás másolata:

1 Multiplayer böngészőben
Szoftverfejlesztés laboratórium 2. IIT1 mérés

2 Technológiák szerver kliens kommunikáció Node.js
HTML5, JavaScript, WebGL kommunikáció sockets.io

3 Kiindulási állapot node.js szerver csak fileokat szolgáltat
minden lokálisan zajlik

4 Vezérlés App.prototype.registerEventHandlers = function() {
let theApp = this; document.onkeydown = function(event) { if(keyboardMap[event.keyCode] === 'W') { // LABTODO: üzenet a szervernek theApp.scene.setThrust(1);

5 Kilépésre eseményfigyelés
window.addEventListener('beforeunload', function() { // LABTODO: üzenet a szervernek });

6 Mesh betöltés let addMesh = function(textureFileName, animTileSize) {
let material = new Material(gl, theScene.texturedProgram); material.colorTexture.set( new Texture2D(gl, 'media/' + textureFileName + '.png') ); material.texScale.set(animTileSize); theScene[textureFileName + 'Mesh'] = new Mesh(theScene.quadGeometry, material); };

7 GameState - Fizikai állapotváltozók
this.positionPool = new Vec2Array(1024); this.orientationPool = new Vec1Array(1024); this.velocityPool = new Vec2Array(1024); this.angVelocityPool = new Vec1Array(1024); this.invMassPool = new Vec1Array(1024); this.invAngMassPool = new Vec1Array(1024); this.backDragPool = new Vec1Array(1024); this.sideDragPool = new Vec1Array(1024); this.angDragPool = new Vec1Array(1024); this.thrustPool = new Vec1Array(1024); this.torquePool = new Vec1Array(1024);

8 GameState - Fizikai számításokhoz memória
this.forcePool = new Vec2Array(1024); this.aheadPool = new Vec2Array(1024); this.aheadSpeedPool = new Vec1Array(1024); this.aheadVelocityPool = new Vec2Array(1024); this.sideVelocityPool = new Vec2Array(1024); this.backDragFactorPool = new Vec1Array(1024); this.sideDragFactorPool = new Vec1Array(1024); this.angDragFactorPool = new Vec1Array(1024);

9 GameState – objektumok, avatarok
this.dynamicObjects = []; this.avatars = {}; this.resizeArrays();

10 GameState – resizeArrays
GameState.prototype.resizeArrays = function() { this.positions = this.positionPool.subarray(0, this.dynamicObjects.length); ...

11 GameState – addPlayer GameState.prototype.addPlayer = function(playerId){ this.avatars[playerId] = {}; };

12 GameState – addObject GameState.prototype.addObject = function(playerId, isAvatar, meshName){ let i = this.dynamicObjects.length; this.dynamicObjects.push({ playerId:playerId, isAvatar:isAvatar, meshName:meshName, role:role}); if(isAvatar){ this.avatars[playerId].objectIndex = i; } this.positionPool.at(i).setRandom(0, 5); ...

13 GameState – dropPlayer
GameState.prototype.dropPlayer = function(playerId){ // remove objects with a certain player id this.dynamicObjects = this.dynamicObjects.filter(function(obj){ return obj.playerId !== playerId; });

14 GameState – dropPlayer
// refresh avatar indices delete this.avatars[playerId]; for(var i=0; i<this.dynamicObjects.length; i++){ let obj = this.dynamicObjects[i]; if(obj.isAvatar){ this.avatars[obj.playerId].objectIndex = i; } this.resizeArrays();

15 GameState update – Euler integrálás Newton egyenletekre
this.aheads.cossin(this.orientations); this.forces.mulWithVec1s(this.aheads, this.thrusts); this.velocities.addScaled(this.velocities, this.forces, dt); this.angVelocities.addScaled(this.angVelocities, this.torques, dt); this.positions.addScaled(this.positions, this.velocities, dt); this.orientations.addScaled(this.orientations, this.angVelocities, dt); this.aheadSpeeds.dotVec2s(this.velocities, this.aheads); this.aheadVelocities.mulWithVec1s(this.aheads, this.aheadSpeeds); this.sideVelocities.sub(this.velocities, this.aheadVelocities); this.backDragFactors.exp(this.backDrags, dt); this.aheadVelocities.mulWithVec1s(this.aheadVelocities, this.backDragFactors); this.sideDragFactors.exp(this.sideDrags, dt); this.sideVelocities.mulWithVec1s(this.sideVelocities, this.sideDragFactors); this.velocities.add(this.aheadVelocities, this.sideVelocities); this.angDragFactors.exp(this.angDrags, dt); this.angVelocities.mul(this.angVelocities, this.angDragFactors);

16 Ütközésdetektálás és válasz
let relativeVelocity = new Vec2(); let diff = new Vec2(); for(let i=0; i<this.dynamicObjects.length; i++) { for(let j=i+1; j<this.dynamicObjects.length; j++) { diff.set(this.positions.at(i)).sub(this.positions.at(j)); let dist2 = diff.dot(diff); if(dist2 < 4) { diff.mul( 1.0 / Math.sqrt(dist2) ); this.positions.at(i).addScaled(0.05, diff); this.positions.at(j).addScaled(-0.05, diff); var tangent = new Vec2(-diff.y, diff.x); var vi = this.velocities.at(i); var bi = this.angVelocities.at(i); var vj = this.velocities.at(j); var bj = this.angVelocities.at(j); relativeVelocity.set(vi).sub(vj).addScaled(bi.x - bj.x, tangent); let impulseLength = diff.dot(relativeVelocity); diff.mul( impulseLength * 1.5 /*restitution*/ ); let frictionLength = tangent.dot(relativeVelocity); tangent.mul(frictionLength * 0.5 /*friction*/); vi.sub(diff).sub(tangent); vj.add(diff).add(tangent); bi.add(frictionLength /* *radius*/ ); bj.add(frictionLength /* *radius*/ ); }

17 Kameramozgatás this.camera.position.set(
this.gameState.positions.at(this.avatarIndex)); this.camera.updateViewProjMatrix();

18 Feladat ütközésválasz a statikus objektumokra
minden ugyanaz, kivéve, hogy a statikusnak nulla a sebessége és a szögsebessége, valamint nem mozdul el

19 Feladat fizikai szimuláció a szerveren (is)
szinkronizáció a kliensekke multiplayer játék az egyes lépésekhez segítenek a következő diák

20 Indítás most nem az index.html játszik már hanem az index.js
package.json-ban van minden node shell / linux shell npm start csatlakozás: böngészőbe: localhost:8082

21 Szerver lehetőségek localhost cg.iit.bme.hu windows standalone node.js
nodejs-portable.exe 2-es menüopció cd arena npm start cg.iit.bme.hu user/pass: sw2/node.js a home-ba mindenki gyárthat NEPTUN kód könyvtárat npm a pathban van, npm start működik

22 Debuggolás kliens: szerver (localhoston) chrome, jobb klikk, inspect
chrome: about:inspect ha fut a szerver, kell itt lennie egy linknek a debuggolásához

23 Kapcsolódás a kliensből (App.js)
//this.socket = io.connect('localhost'); // VAGY //this.socket = io.connect('

24 Socket.io szerveren (index.js)
let io = require('socket.io')(server);

25 fogadás a szerveren io.on('connection', function(client) {
let clientId = lastClientId++; console.log('User connected, id: ' + clientId); });

26 Próbáljuk ki

27 Kilépés client.on('leave', function(){
console.log('Client left. Id: ' + clientId); });

28 Page unloadkor a kliens
theApp.socket.emit('leave', {});

29 Próbáljuk ki

30 Feladat néhány frameenként 'reqState' üzenet küldése a kliensről
App update-ből üres objektumot elég átküldni írjuk ki, hogy az üzenet megjött próbáljuk ki

31 GameState objektum szerveroldalon
let game = new GameState();

32 Szerveren: új játékos belépésekor objektumok létrehozása
új játékos hozzáadása (gameState) új avatar objektum hozzáadása (gameState) syncObject küldése mindenkinek üzenet része a kliensId (tudja meg a kliens, hogy hányas) ha broadcastolunk, ne legyen benne kliensId (legyen null) plusz küldjük át a gameState objektumot client.broadcast.emit('syncObjects', { clientId:null, state:game });

33 App.js: üzenetfogadás a kliensen példa
this.socket.on('syncObjects', function(data){ theScene.syncObjects(data.clientId, data.state); });

34 syncObjects példa Scene.prototype.syncObjects = function(clientId, serverState) { let theScene = this; var i = 0; this.dynamicObjects = serverState.dynamicObjects.map( function(obj){ return new GameObject( theScene[obj.meshName + 'Mesh'] ); }); this.gameState.dynamicObjects = serverState.dynamicObjects; this.gameState.resizeArrays(); this.syncState(clientId, serverState); };

35 syncState példa Scene.prototype.syncState = function(clientId, serverState) { if(clientId !== null) { this.playerId = clientId; } this.gameState.set(serverState); };

36 Próbáljuk ki új belépő esetén az új objektum és a játékállapot mindenkinek el lesz küldve

37 Szerveren: játékos kilépésekor
játékos kidobása a gameStateből syncObjects küldése mindenkinek

38 Próbáljuk ki kilépés esetén sync

39 Game loop a szerveren var timeAtStart = new Date().getTime();
var timeAtLastFrame = 0.0; setInterval(function(){ let time = (new Date().getTime() - timeAtStart) / ; let dt = time - timeAtLastFrame; timeAtLastFrame = time; game.update(dt); }, 16);

40 Feladat legyen az avataroknak valamilyen kezdősebessége
néhány frameenként 'reqState' üzenet küldése a kliensről válasz a szerverről: 'syncState' üzenetek

41 Próbáljuk ki sodródó, de szinkronizált hajók

42 Feladat setThrust és setTorque üzenetek küldése a kliensről, feldolgozása a szerveren game.avatars[clientId].objectIndex-et ne felejtsük

43 Próbáljuk ki multiplayer lökdösődés

44 További lehetőségek más objektumok ütközéskor típusfüggő reakció
pickupok, lövedékek célszerű őket előre, kapcsolódáskor létrehozni a GameState dynamicObjectsben lehet tárolni, hogy az objektum miféle (role) ütközéskor típusfüggő reakció ha az egyik avatar, a másik meg pickup: avatar tulajdonságok változtatása ehhez lehet avatarleíróba új property-t felvenni az objectIndex mellé pl. tolóerő függjön attól, hány pickupot szedtük fel pickup respawn (random helyre ugrik) lövedék: ha talál, frag++, eltalált respawn


Letölteni ppt "Multiplayer böngészőben"

Hasonló előadás


Google Hirdetések