/** * Game Runtime * @param graphics GameLib.D3.Graphics * @param apiGame GameLib.D3.API.Game * @param imageFactory * @constructor */ GameLib.D3.Game = function ( graphics, apiGame, imageFactory ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); if (GameLib.Utils.UndefinedOrNull(apiGame)) { apiGame = {}; } GameLib.D3.API.Game.call( this, apiGame.id, apiGame.name, apiGame.baseUrl, apiGame.path, apiGame.gameType, apiGame.width, apiGame.height, apiGame.scenes, apiGame.cameras, apiGame.renderers, apiGame.composers, apiGame.systems, apiGame.viewports, apiGame.entityManager, apiGame.mouse, apiGame.parentEntity ); if (GameLib.Utils.UndefinedOrNull(imageFactory)) { imageFactory = GameLib.D3.ImageFactory( this.graphics, this.baseUrl ); } this.imageFactory = imageFactory; this.scenes = this.scenes.map( function(apiScene) { if (apiScene instanceof GameLib.D3.API.Scene) { return new GameLib.D3.Scene( this.graphics, apiScene, this.imageFactory, true ) } else { console.warn('Scene not of type API.Scene'); throw new Error('Scene not of type API.Scene'); } }.bind(this) ); this.cameras = this.cameras.map( function(apiCamera) { if (apiCamera instanceof GameLib.D3.API.Camera) { return new GameLib.D3.Camera( this.graphics, apiCamera ) } else { console.warn('Camera not of type API.Camera'); throw new Error('Camera not of type API.Camera'); } }.bind(this) ); this.renderers = this.renderers.map( function(apiRenderer) { if (apiRenderer instanceof GameLib.D3.API.Renderer) { return new GameLib.D3.Renderer( this.graphics, apiRenderer ) } else { console.warn('Renderer not of type API.Renderer'); throw new Error('Renderer not of type API.Renderer'); } }.bind(this) ); this.composers = this.composers.map( function(apiComposer) { if (apiComposer instanceof GameLib.D3.API.Composer) { return new GameLib.D3.Composer( this.graphics, apiComposer ) } else { console.warn('Composer not of type API.Composer'); throw new Error('Composer not of type API.Composer'); } }.bind(this) ); this.systems = this.systems.map( function(apiSystem) { if (apiSystem instanceof GameLib.D3.API.System) { return new GameLib.D3.System( this.graphics, apiSystem ) } else { console.warn('System not of type API.System'); throw new Error('System not of type API.System'); } }.bind(this) ); this.viewports = this.viewports.map( function(apiViewport) { if (apiViewport instanceof GameLib.D3.API.Viewport) { return new GameLib.D3.Viewport( this.graphics, apiViewport ) } else { console.warn('Viewport not of type API.Viewport'); throw new Error('Viewport not of type API.Viewport'); } }.bind(this) ); this.buildIdToObject(); }; GameLib.D3.Game.prototype = Object.create(GameLib.D3.API.Game.prototype); GameLib.D3.Game.prototype.constructor = GameLib.D3.Game; GameLib.D3.Game.GAME_TYPE_VR_PONG = 0x1; GameLib.D3.Game.GAME_TYPE_VR_RACER = 0x2; /** * Creates a camera instance of 'graphics' type (only THREE for now) * @returns {THREE.Game} */ GameLib.D3.Game.prototype.createInstance = function(update) { var instance = null; if (update) { instance = this.instance; } return instance; }; // GameLib.D3.Game.prototype.setSize = function(width, height) { // // // var w = 0; // // var h = 0; // // this.viewports.map( // function(viewport) { // // w = viewport.width; // // h = viewport.height; // // // // //TODO : calculate width and height decrease or increase ratio and adjust viewport x and y offset according // // var wx = width / w; // // var hx = height / h; // // viewport.width = width; // viewport.height = height; // // viewport.updateInstance(); // } // ) // // }; /** * Updates the instance with the current state */ GameLib.D3.Game.prototype.updateInstance = function() { this.instance = this.createInstance(true); }; GameLib.D3.Game.prototype.buildIdToObject = function() { this.idToObject = {}; if (this.entityManager instanceof GameLib.API.EntityManager) { this.entityManager = new GameLib.EntityManager( this.graphics, this.entityManager ); this.entityManager.entities.map( function (entity) { this.idToObject[entity.id] = entity; entity.components.map( function(component) { if (component instanceof GameLib.Component) { this.idToObject[component.id] = component; } else { console.warn('Component not of type Component'); throw new Error('Component not of type Component'); } }.bind(this) ) }.bind(this) ); this.entityManager.linkObjects(this.idToObject); } else { console.warn('EntityManager not of type API.EntityManager'); throw new Error('EntityManager not of type API.EntityManager'); } this.scenes.map( function(scene) { var idToObject = scene.idToObject; for (var property in idToObject) { if (idToObject.hasOwnProperty(property)) { this.idToObject[property] = idToObject[property]; } } }.bind(this) ) }; /** * Converts a GameLib.D3.Game to a new GameLib.D3.API.Game * @returns {GameLib.D3.API.Game} */ GameLib.D3.Game.prototype.toApiGame = function() { var apiScenes = []; if (this.scenes) { apiScenes = this.scenes.map( function(scene) { if (scene instanceof GameLib.D3.Scene) { return scene.toApiScene(); } else { console.warn('Scene not an instance of Scene'); throw new Error('Scene not an instance of Scene'); } } ); } var apiCameras = []; if (this.cameras) { apiCameras = this.cameras.map( function(camera) { if (camera instanceof GameLib.D3.Camera) { return camera.toApiCamera(); } else { console.warn('Camera not an instance of Camera'); throw new Error('Camera not an instance of Camera'); } } ); } var apiRenderers = []; if (this.renderers) { apiRenderers = this.renderers.map( function(renderer) { if (renderer instanceof GameLib.D3.Renderer) { return renderer.toApiRenderer(); } else { console.warn('Renderer not an instance of Renderer'); throw new Error('Renderer not an instance of Renderer'); } } ); } var apiComposers = []; if (this.composers) { apiComposers = this.composers.map( function(composer) { if (composer instanceof GameLib.D3.Composer) { return composer.toApiComposer(); } else { console.warn('Composer not an instance of Composer'); throw new Error('Composer not an instance of Composer'); } } ); } var apiSystems = []; if (this.systems) { apiSystems = this.systems.map( function(system) { if (system instanceof GameLib.System) { return system.toApiSystem(); } else { console.warn('System not an instance of System'); throw new Error('System not an instance of System'); } } ); } var apiViewports = []; if (this.viewports) { apiViewports = this.viewports.map( function(viewport) { if (viewport instanceof GameLib.D3.Viewport) { return viewport.toApiViewport(); } else { console.warn('Viewport not an instance of Viewport'); throw new Error('Viewport not an instance of Viewport'); } } ); } var apiEntityManager = null; if (this.entityManager) { if (this.entityManager instanceof GameLib.EntityManager) { apiEntityManager = this.entityManager.toApiEntityManager(); } else { console.warn('EntityManager not an instance of EntityManager'); throw new Error('EntityManager not an instance of EntityManager'); } } var apiMouse = null; if (this.mouse) { if (this.mouse instanceof GameLib.Mouse) { apiMouse = this.mouse.toApiMouse(); } else { console.warn('Mouse not an instance of Mouse'); throw new Error('Mouse not an instance of Mouse'); } } return new GameLib.D3.API.Game( this.id, this.name, this.baseUrl, this.path, this.gameType, this.width, this.height, apiScenes, apiCameras, apiRenderers, apiComposers, apiSystems, apiViewports, apiEntityManager, apiMouse, GameLib.Utils.IdOrNull(this.parentEntity) ); }; /** * Converts from an Object Game to a GameLib.D3.Game * @param graphics GameLib.D3.Graphics * @param objectGame Object * @returns {GameLib.D3.Game} * @constructor */ GameLib.D3.Game.FromObjectGame = function(graphics, objectGame) { var apiGame = GameLib.D3.API.Game.FromObjectGame(objectGame); return new GameLib.D3.Game( graphics, apiGame ); }; /** * Loads a Game * @param graphics * @param objectGame * @param onLoaded * @constructor */ GameLib.D3.Game.LoadGame = function( graphics, objectGame, onLoaded ) { var game = GameLib.D3.Game.FromObjectGame( graphics, objectGame ); onLoaded(game); }; /** * Loads a Game from the API * @param graphics GameLib.D3.Graphics * @param partialGameObject Object * @param onLoaded callback * @param apiUrl * @returns {*} * @constructor */ GameLib.D3.Game.LoadGameFromApi = function( graphics, partialGameObject, onLoaded, apiUrl ) { /** * First check if this is a client or server side request */ if (typeof XMLHttpRequest == 'undefined') { console.warn('Implement server side loading from API here'); return onLoaded( null, new Error('Not Implemented') ); } var xhr = new XMLHttpRequest(); xhr.open( 'GET', apiUrl + '/game/load' + partialGameObject.path + '/' + partialGameObject.name ); xhr.onreadystatechange = function(xhr) { return function() { if (xhr.readyState == 4) { try { var response = JSON.parse(xhr.responseText); } catch (e) { return onLoaded(null, new Error('Could not load game : ' + e.message)); } if (!response.game || response.game.length == 0) { return onLoaded(null, new Error('Could not load game')); } var objectGame = response.game[0]; GameLib.D3.Game.LoadGame( graphics, objectGame, onLoaded ); } } }(xhr); xhr.send(); };