ShadowSpace un MMORPG en WebGL

Rédigé par BeHuman 4 commentaires
Classé dans : HTML/CSS/JavaScript, Php, XML, Ajax Mots clés : rpg, mmorpg, jeu, game, webgl, opengl, 3d

ShadowSpace est un projet perso que je développe quand j'ai un peu de temps libre devant moi. Le but de ce projet est de créer un jeu spacial du type MMORPG/FPS

j'ai débuté ce projet avec un example disponible dans la librairie http://threejs.org/ , ensuite j'ai ajouté quelques éléments pour comprendre le mechanisme de la librairie et pour finir ma base, j'ai dev une librairie ajax en javascript , une librairie xml en php et créé un système de session multijoueur avec le tout.

Pour commencer je vous balance quelques captures d'écran:

 

J'ai inclus à la scène une sélection des objets avec la souris avec une aura jaune. Le point rouge est un autre joueur (en l'occurence c'est moi avec le navigateur Firefox). En cliquant dessus il affiche les informations relative au joueur en bas, il en va de même pour les autres objet (comme les planètes par exemple) de la scène.

page index.php:

<!DOCTYPE html>
<html lang="fr">
    <head>
        <title>Space Shadow</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                background:#000;
                color: #eee;
                padding:0;
                margin:0;
                font-weight:bold;
                overflow:hidden;

                font-family:Monospace;
                font-size:13px;
                text-align:center;
            }

            #msg {
                position: absolute;
                bottom: 0px; width: 100%;
                padding: 5px;
                z-index:10000;
            }
            #result {
                position: absolute;
                top: 10px;
                left: 10px;
                width: 100%;
                padding: 5px;
                font-size:9px;
                z-index:10000;
            }
            #cockpit {
                position:absolute;
                top:0px;left:0px;
                width: 100%;
                height:100%;
                z-index:1000;
                /*background-image:url(textures/cockpits/view.png);
                background-repeat: no-repeat; 
                background-attachment: fixed; */
                background-size: 100% 100%; 
            }
            a {

                color: #0080ff;
            }

            b { color:orange }
        </style>

        <script src="build/three.min.js"></script>

        <script src="js/controls/FlyControls.js"></script>

        <script src="js/shaders/CopyShader.js"></script>
        <script src="js/shaders/FilmShader.js"></script>

        <script src="js/postprocessing/EffectComposer.js"></script>
        <script src="js/postprocessing/ShaderPass.js"></script>
        <script src="js/postprocessing/MaskPass.js"></script>
        <script src="js/postprocessing/RenderPass.js"></script>
        <script src="js/postprocessing/FilmPass.js"></script>
        <script src="libajax.js"></script>
        <script src="js/Detector.js"></script>
<!--        <script src="js/libs/stats.min.js"></script>-->

    </head>

    <body>
        <div id="msg"></div>
        <div id="result"></div>
        <div id="cockpit"></div>
        <!--<b>WASD</b> move, <b>R|F</b> up | down, <b>Q|E</b> roll, <b>up|down</b> pitch, <b>left|right</b> yaw<br/>-->
        
        <script>
            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
            
            
            var projector, lightsolar, particule1,l1;
            var objects = [];
            var mouse = { x: 0, y: 0 }, INTERSECTED;
            
            var radius = 6371;
            var tilt = 0.41;
            var rotationSpeed = 0.02;

            var cloudsScale = 1.005;
            var moonScale = 0.23;
            var playerScale = 0.23;
            var marsScale = 10.00;
            var plutonScale = 100.00;
            var solarScale = 150.00;
            var targeting=false;
            var MARGIN = 0;
            var SCREEN_HEIGHT = window.innerHeight - MARGIN * 2;
            var SCREEN_WIDTH  = window.innerWidth;

            var container, stats;
            var camera, controls, scene, sceneCube, renderer;
            var geometry, meshPlanet, meshClouds, meshMoon, meshMars, meshPluton,meshPlayer, meshSolar;
            var materialPlayer = new THREE.ParticleBasicMaterial( { color: 0xff0000, opacity:0.3, transparent: true } );
            var materialPlayer_head = new THREE.ParticleBasicMaterial( { color: 0x00ff00, opacity:0.3, transparent: true } );
            var meshPlayers = new Array();
            var dirLight, pointLight, ambientLight;

            var d, dPlanet, dMoon, dMoonVec = new THREE.Vector3();
            var dMars, dMarsVec = new THREE.Vector3();
            var dPluton, dPlutonVec = new THREE.Vector3();
            var dSolar, dSolarVec = new THREE.Vector3();
            var clock = new THREE.Clock();

            init();
            animate();

            function init() {
                
                container = document.createElement( 'div' );
                document.body.appendChild( container );

                camera = new THREE.PerspectiveCamera( 50, SCREEN_WIDTH / SCREEN_HEIGHT, 50, 1e7 );
                camera.position.z = radius * 3;

                scene = new THREE.Scene();
                scene.fog = new THREE.FogExp2( 0x000000, 0.00000025 );

                controls = new THREE.FlyControls( camera );

                controls.movementSpeed = 1;
                controls.domElement = container;
                controls.rollSpeed = Math.PI / 14;
                controls.autoForward = false;
                controls.dragToLook = true;
                
                zoneSelected = new THREE.Mesh( new THREE.SphereGeometry( 7000, 200, 200 ), new THREE.ParticleBasicMaterial( { color: 0xffff00, opacity:0.1, transparent:true } ) );
                zoneSelected.name="select";
                
                scene.add( zoneSelected );
                
                ambientLight = new THREE.AmbientLight( 0x000000 );
                scene.add( ambientLight );
                
                var planetTexture   = THREE.ImageUtils.loadTexture( "textures/planets/earth_atmos_2048.jpg" );
                var cloudsTexture   = THREE.ImageUtils.loadTexture( "textures/planets/earth_clouds_1024.png" );
                var normalTexture   = THREE.ImageUtils.loadTexture( "textures/planets/earth_normal_2048.jpg" );
                var specularTexture = THREE.ImageUtils.loadTexture( "textures/planets/earth_specular_2048.jpg" );
                var solarTexture = THREE.ImageUtils.loadTexture( "textures/planets/solar.jpg" );
                var moonTexture = THREE.ImageUtils.loadTexture( "textures/planets/moon_1024.jpg" );
                var marsTexture = THREE.ImageUtils.loadTexture( "textures/planets/mars.jpg" );
                var plutonTexture = THREE.ImageUtils.loadTexture( "textures/planets/firya.jpg" );

                var shader = THREE.ShaderLib[ "normalmap" ];
                var uniforms = THREE.UniformsUtils.clone( shader.uniforms );

                uniforms[ "tNormal" ].value = normalTexture;
                uniforms[ "uNormalScale" ].value.set( 0.85, 0.85 );

                uniforms[ "tDiffuse" ].value = planetTexture;
                uniforms[ "tSpecular" ].value = specularTexture;

                uniforms[ "enableAO" ].value = false;
                uniforms[ "enableDiffuse" ].value = true;
                uniforms[ "enableSpecular" ].value = true;

                uniforms[ "uDiffuseColor" ].value.setHex( 0xffffff );
                uniforms[ "uSpecularColor" ].value.setHex( 0x999999 );
                uniforms[ "uAmbientColor" ].value.setHex( 0x999999 );

                uniforms[ "uShininess" ].value = 10;

                var parameters = {

                    fragmentShader: shader.fragmentShader,
                    vertexShader: shader.vertexShader,
                    uniforms: uniforms,
                    lights: true,
                    fog: true

                };

                // planet
                var materialNormalMap = new THREE.ShaderMaterial( parameters );
                geometry = new THREE.SphereGeometry( radius, 100, 50 );
                geometry.computeTangents();

                meshPlanet = new THREE.Mesh( geometry, materialNormalMap );
                meshPlanet.rotation.y = 0;
                meshPlanet.rotation.z = tilt;
                meshPlanet.name="lifewater";
                scene.add( meshPlanet );
                
                // clouds

                var materialClouds = new THREE.MeshLambertMaterial( { color: 0xffffff, map: cloudsTexture, transparent: true } );

                meshClouds = new THREE.Mesh( geometry, materialClouds );
                meshClouds.scale.set( cloudsScale, cloudsScale, cloudsScale );
                meshClouds.rotation.z = tilt;
                meshClouds.name="lifewater";
                scene.add( meshClouds );

                // moon

                var materialMoon = new THREE.MeshPhongMaterial( { color: 0xffffff, map: moonTexture } );

                meshMoon = new THREE.Mesh( geometry, materialMoon );
                meshMoon.position.set( radius * 5, 0, 0 );
                meshMoon.scale.set( moonScale, moonScale, moonScale );
                meshMoon.name="sat1";
                scene.add( meshMoon );
                
                
                //soleil
                lightsolar = new THREE.PointLight( 0xffffff);
                lightsolar.position.set( -6000000 , -50000, 500000 );
                lightsolar.intensity = 1;
                scene.add( lightsolar );
                
                
                var materialSolar = new THREE.ParticleBasicMaterial( { color: 0xffff00, opacity:0.7,  transparent:true } );

                meshSolar = new THREE.Mesh( geometry, materialSolar );
                meshSolar.position.x = lightsolar.position.x;
                meshSolar.position.y = lightsolar.position.y;
                meshSolar.position.z = lightsolar.position.z;

                meshSolar.scale.set( solarScale, solarScale, solarScale );
                meshSolar.name="solar9554";
                scene.add( meshSolar );
                
                // mars

                var materialMars = new THREE.MeshPhongMaterial( { color: 0xffffff, map: marsTexture } );

                meshMars = new THREE.Mesh( geometry, materialMars );
                meshMars.position.set( radius * 100, 50, 45 );
                meshMars.scale.set( marsScale, marsScale, marsScale );
                meshMars.name="m44";
                scene.add( meshMars );
                
                // pluton

                var materialPluton = new THREE.MeshPhongMaterial( { color: 0xffffff, map: plutonTexture } );

                meshPluton = new THREE.Mesh( geometry, materialPluton );
                meshPluton.position.set( radius * 300, -100, 90 );
                meshPluton.scale.set( plutonScale, plutonScale, plutonScale );
                meshPluton.name="firya";
                scene.add( meshPluton );
                
                //player
                
                /*
                meshPlayer = new THREE.Mesh( geometry, materialPlayer );
                meshPlayer.position.x = camera.position.x;
                meshPlayer.position.y = camera.position.y;
                meshPlayer.position.z = camera.position.z;
                meshPlayer.scale.set( 0.10, 0.10, 0.10 );
                meshPlayer.name="";
                scene.add( meshPlayer );
                */
                
                // stars

                var i, r = radius, starsGeometry = [ new THREE.Geometry(), new THREE.Geometry() ];

                for ( i = 0; i < 250; i ++ ) {

                    var vertex = new THREE.Vector3();
                    vertex.x = Math.random() * 2 - 1;
                    vertex.y = Math.random() * 2 - 1;
                    vertex.z = Math.random() * 2 - 1;
                    vertex.multiplyScalar( r );

                    starsGeometry[ 0 ].vertices.push( vertex );

                }

                for ( i = 0; i < 1500; i ++ ) {

                    var vertex = new THREE.Vector3();
                    vertex.x = Math.random() * 2 - 1;
                    vertex.y = Math.random() * 2 - 1;
                    vertex.z = Math.random() * 2 - 1;
                    vertex.multiplyScalar( r );

                    starsGeometry[ 1 ].vertices.push( vertex );

                }

                var stars;
                var starsMaterials = [
                    new THREE.ParticleBasicMaterial( { color: 0x555555, size: 2, sizeAttenuation: false } ),
                    new THREE.ParticleBasicMaterial( { color: 0x555555, size: 1, sizeAttenuation: false } ),
                    new THREE.ParticleBasicMaterial( { color: 0x333333, size: 2, sizeAttenuation: false } ),
                    new THREE.ParticleBasicMaterial( { color: 0x3a3a3a, size: 1, sizeAttenuation: false } ),
                    new THREE.ParticleBasicMaterial( { color: 0x1a1a1a, size: 2, sizeAttenuation: false } ),
                    new THREE.ParticleBasicMaterial( { color: 0x1a1a1a, size: 1, sizeAttenuation: false } )
                ];

                for ( i = 10; i < 40; i ++ ) {

                    stars = new THREE.ParticleSystem( starsGeometry[ i % 2 ], starsMaterials[ i % 6 ] );

                    stars.rotation.x = Math.random() * 12;
                    stars.rotation.y = Math.random() * 12;
                    stars.rotation.z = Math.random() * 12;

                    s = i * 7;
                    stars.scale.set( s, s, s );

                    stars.matrixAutoUpdate = false;
                    stars.updateMatrix();

                    scene.add( stars );

                }
                projector = new THREE.Projector();
                renderer = new THREE.WebGLRenderer( { clearColor: 0x000000, clearAlpha: 1 } );
                renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
                renderer.sortObjects = false;

                renderer.autoClear = false;

                container.appendChild( renderer.domElement );

                /*stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                stats.domElement.style.zIndex = 100;
                container.appendChild( stats.domElement );*/
                
                
                document.addEventListener( 'mouseup', onDocumentMouseLeftClick, false );
                //document.addEventListener( 'dblclick', onDocumentMouseDoubleClick, false );
                window.addEventListener( 'resize', onWindowResize, false );
                
                // postprocessing

                var renderModel = new THREE.RenderPass( scene, camera );
                var effectFilm = new THREE.FilmPass( 0.0, 0.0, 2048, false );

                effectFilm.renderToScreen = true;

                composer = new THREE.EffectComposer( renderer );

                composer.addPass( renderModel );
                composer.addPass( effectFilm );

            };
            
            
            function onDocumentMouseLeftClick( event ) {

                event.preventDefault();

                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

            }
            var DBLC=false;
            function onDocumentMouseDoubleClick( event ) {
                DBLC=true;

            }
            
            function onWindowResize( event ) {

                SCREEN_HEIGHT = window.innerHeight;
                SCREEN_WIDTH  = window.innerWidth;

                renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );

                camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
                camera.updateProjectionMatrix();

                composer.reset();

            };

            function animate() {

                requestAnimationFrame( animate );

                render();
                //stats.update();

            };
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

function _SESSION() {
    sendWithAjaxE4(
            'get_session_xml.php',
            'POST',
            'eval(xh.responseText);',
            null,
            'posx='+camera.position.x+'&posy='+camera.position.y+'&posz='+camera.position.z+'&pseudo='+pseudo
    );
}
//_SESSION();
var pseudo=prompt('Tapez votre pseudo','null');
setInterval(_SESSION,1000);
            function render() {

                // rotate the planet and clouds
                var time = Date.now() * 0.0005;
                var delta = clock.getDelta();

                meshPlanet.rotation.y += rotationSpeed * delta;
                meshClouds.rotation.y += 1.25 * rotationSpeed * delta;


                // slow down as we approach the surface

                dPlanet = camera.position.length();

                dMoonVec.subVectors( camera.position, meshMoon.position );
                dMoon = dMoonVec.length();
                
                dMarsVec.subVectors( camera.position, meshMars.position );
                dMars = dMarsVec.length();
                
                dPlutonVec.subVectors( camera.position, meshPluton.position );
                dPluton = dPlutonVec.length();
                

                if ( dMoon < dPlanet ) {

                    d = ( dMoon - radius * moonScale * 1.01 );
                    
                } 
                
                 
                if ( dMars < dPlanet ) {
                    d = ( dMars - radius * marsScale * 1.01 );
                    

                }
                
                if ( dPluton < dPlanet ) {
                    d = ( dPluton - radius * plutonScale * 1.01 );
                    

                }
                
                if (( dPluton > dPlanet ) &&( dMars > dPlanet ) && ( dMoon > dPlanet ) ) {

                    d = ( dPlanet - radius * 1.01 );
                    
                }
                

                // find intersections

                var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
                projector.unprojectVector( vector, camera );

                var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

                var intersects = raycaster.intersectObjects( scene.children );
                
                if ( intersects.length > 0 ) {
                    
                    if ( INTERSECTED != intersects[ 0 ].object ) {
                        INTERSECTED = intersects[ 0 ].object;

                        if (INTERSECTED.name!='select') {
                            if (INTERSECTED.name!='solar9554') {
                                zoneSelected.position.set(INTERSECTED.position.x,INTERSECTED.position.y,INTERSECTED.position.z);
                                zoneSelected.scale.x = INTERSECTED.scale.x;
                                zoneSelected.scale.y = INTERSECTED.scale.y;
                                zoneSelected.scale.z = INTERSECTED.scale.z;
                            }
				            document.getElementById('msg').innerHTML=INTERSECTED.name+'<br> position x:'+INTERSECTED.position.x+' y:'+INTERSECTED.position.y+' z:'+INTERSECTED.position.z+'<br>dimension x:'+INTERSECTED.scale.x+' y:'+INTERSECTED.scale.y;
				    }
                    }
                } else {
                    INTERSECTED = null;
                    zoneSelected.position.set(0,0,0);
                    zoneSelected.scale.x =0;
                    zoneSelected.scale.y = 0;
                    zoneSelected.scale.z = 0;
                }
                
                
                controls.movementSpeed = 0.33 * d;
                controls.update( delta );
                
                //renderer.render( scene, camera );
                renderer.clear();
                composer.render( delta );
                

            };
            
        </script>
    </body>
</html>

le script envoie une requête en Ajax au script get_session_xml.php:

<?php
ini_set('display_errors', 1); 
error_reporting(E_ALL);
require("libxml.php");
$fp = fopen("session.xml", "rw+");
while (!flock($fp, LOCK_EX)) {
    //echo "Impossible de verrouiller le fichier!";
}

$dom=loadFileXML("session.xml");
$out=getAttribute($dom,"connect", "id");

$record=false;
for ($i=0; $i<count($out); $i++) {
    if ($out[$i]==sessionXML()) {
        $record=true;
       break;
    }
}
if ($record) {
    //mise à jour des connections
    updateTagWithAttribute($dom, "connect", $_SERVER['REQUEST_TIME'], "id", $out[$i]);
    updateTagWithAttribute($dom, "posx", $_POST['posx'], "id", $out[$i]);
    updateTagWithAttribute($dom, "posy", $_POST['posy'], "id", $out[$i]);
    updateTagWithAttribute($dom, "posz", $_POST['posz'], "id", $out[$i]);
    $tim=getTagWithoutAttribute($dom,"connect", "id", $out[$i]);
    $attr=getAttributeWithout($dom,"connect", "id", $out[$i]);
    $posx=getTagWithoutAttribute($dom,"posx", "id", $out[$i]);
    $posy=getTagWithoutAttribute($dom,"posy", "id", $out[$i]);
    $posz=getTagWithoutAttribute($dom,"posz", "id", $out[$i]);
    $pseudo=getTagWithoutAttribute($dom,"pseudo", "id", $out[$i]);
    for($e=0; $e<count($tim); $e++) {
        if ($tim[$e]+10 < $_SERVER['REQUEST_TIME']) { 
            echo "scene.remove(meshPlayers[\"".$attr[$e]."\"]);";
            delTagWithAttribute($dom, "connect", "id", $attr[$e]);
            delTagWithAttribute($dom, "ua", "id", $attr[$e]);
            delTagWithAttribute($dom, "ip", "id", $attr[$e]);
            delTagWithAttribute($dom, "posx", "id", $attr[$e]);
            delTagWithAttribute($dom, "posy", "id", $attr[$e]);
            delTagWithAttribute($dom, "posz", "id", $attr[$e]);
            delTagWithAttribute($dom, "pseudo", "id", $attr[$e]);
        } else {
            echo "scene.remove(meshPlayers[\"".$attr[$e]."\"]);";
            echo "meshPlayers[\"".$attr[$e]."\"]=new THREE.Mesh( geometry, materialPlayer );";
            echo "meshPlayers[\"".$attr[$e]."\"].name=\"".$pseudo[$e]."\";";
            echo "meshPlayers[\"".$attr[$e]."\"].position.x = ".$posx[$e].";";
            echo "meshPlayers[\"".$attr[$e]."\"].position.y = ".$posy[$e].";";
            echo "meshPlayers[\"".$attr[$e]."\"].position.z = ".$posz[$e].";";
            echo "meshPlayers[\"".$attr[$e]."\"].scale.set( 0.1, 0.1, 0.1 );";
            echo "scene.add( meshPlayers[\"".$attr[$e]."\"] );";
            
            echo "scene.remove(meshPlayers[\"".$attr[$e]."_head\"]);";
            echo "meshPlayers[\"".$attr[$e]."_head\"]=new THREE.Mesh( geometry, materialPlayer_head );";
            echo "meshPlayers[\"".$attr[$e]."_head\"].name=\"".$pseudo[$e]."\";";
            echo "meshPlayers[\"".$attr[$e]."_head\"].position.x = ".($posx[$e]).";";
            echo "meshPlayers[\"".$attr[$e]."_head\"].position.y = ".($posy[$e]).";";
            echo "meshPlayers[\"".$attr[$e]."_head\"].position.z = ".($posz[$e]).";";
           echo "meshPlayers[\"".$attr[$e]."_head\"].scale.set( 0.025, 0.025, 0.025 );";
            echo "scene.add( meshPlayers[\"".$attr[$e]."_head\"] );";
        }
    }
} else {
    updateTagWithAttribute($dom, "connect", $_SERVER['REQUEST_TIME'], "id", sessionXML());
    updateTagWithAttribute($dom, "ua", $_SERVER['HTTP_USER_AGENT'], "id", sessionXML());
    updateTagWithAttribute($dom, "ip", $_SERVER['SERVER_ADDR'], "id", sessionXML());
    updateTagWithAttribute($dom, "posx", $_POST['posx'], "id", sessionXML());
    updateTagWithAttribute($dom, "posy", $_POST['posy'], "id", sessionXML());
    updateTagWithAttribute($dom, "posz", $_POST['posz'], "id", sessionXML());
    $pseudo=$_POST['pseudo'];
    if ($pseudo == 'null') { $pseudo=sessionXML();}
    updateTagWithAttribute($dom, "pseudo", $pseudo, "id", sessionXML());
    //mise à jour des connections
    $tim=getTagWithoutAttribute($dom,"connect", "id", sessionXML());
    $attr=getAttributeWithout($dom,"connect", "id", sessionXML());
    for($e=0; $e<count($tim); $e++) {
        if ($tim[$e]+10 < $_SERVER['REQUEST_TIME']) { 
            echo "scene.remove(meshPlayers[\"".$attr[$e]."\"]);";
            delTagWithAttribute($dom, "connect", "id", $attr[$e]);
            delTagWithAttribute($dom, "ua", "id", $attr[$e]);
            delTagWithAttribute($dom, "ip", "id", $attr[$e]);
            delTagWithAttribute($dom, "posx", "id", $attr[$e]);
            delTagWithAttribute($dom, "posy", "id", $attr[$e]);
            delTagWithAttribute($dom, "posz", "id", $attr[$e]);
            delTagWithAttribute($dom, "pseudo", "id", $attr[$e]);
        }
    }
}



    saveFileXML($dom, "session.xml");
    flock($fp, LOCK_UN);
    fclose($fp);
?>

Dans cette requête on stock les informations du joueur dans le fichiers session.xml et on récupère la liste des informations des autres joueurs. Le fichier session.xml se précente sous cette forme:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<references>
<ua id="5c7e0562b63498e271beab81c4d8537e6d66c10b">Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22</ua>
<ip id="5c7e0562b63498e271beab81c4d8537e6d66c10b">192.168.1.53</ip>
<pseudo id="5c7e0562b63498e271beab81c4d8537e6d66c10b">Craft</pseudo>
<connect id="5c7e0562b63498e271beab81c4d8537e6d66c10b">1370780315</connect>
<posx id="5c7e0562b63498e271beab81c4d8537e6d66c10b">-22631.185738533248</posx>
<posy id="5c7e0562b63498e271beab81c4d8537e6d66c10b">471.5070339740008</posy>
<posz id="5c7e0562b63498e271beab81c4d8537e6d66c10b">54024.373695524286</posz>
</references>

Grace à ces informations on peu rafraichir la position des joueurs dans la scène.

Vous pouvez télécharger la totalité du projet ici même

Dans le pack, j'ai ajouté un autre exemple qui va me servir de base pour la suite dans le dossiers fps....la partie FPS pure. Une fois cela en place je bosserai un scénario que j'agrémenterai petit à petit, à moins que quelqu'un se joigne à ce petit projet en cours de route.

 

4 commentaires

#1  - OutIn a dit :

Salut BeHuman,

Super projet que celui là...La parti intéressante est la gestion de session multi-joueur. Du JSon ne serait il pas plus adapté et plus rapide? j'attend avec impatience la suite

Répondre
#2  - Beni a dit :

Je dirai JSon est plus rapide, mais XML est plus flexible...Personnellement je me redirigerai vers du JSON pour ma part

Répondre
#3  - BeHuman a dit :

@OutIn :
Merci ;) Je t'avouerai ne mettre pas posé la question concernant JSon, c'est un tech que je ne maîtrise pas des masse, et j'aime la format XML. Cependant je dois absolument y réfléchir, car à quelques joueurs, le XML gère correctement le truc, mais à plus grosse échelle j'ai un sérieux doute.

Répondre
#4  - weboref a dit :

Très bien codé c'est impressionnant!

Répondre

Écrire un commentaire

Quelle est la sixième lettre du mot 0ja6s2pb ?

Fil RSS des commentaires de cet article