432 lines
11 KiB
JavaScript
432 lines
11 KiB
JavaScript
|
/**
|
||
|
* Game Runtime
|
||
|
* @param graphics R3.D3.Graphics
|
||
|
* @param apiGame R3.D3.API.Game
|
||
|
* @constructor
|
||
|
*/
|
||
|
R3.D3.Game = function (
|
||
|
graphics,
|
||
|
apiGame
|
||
|
) {
|
||
|
|
||
|
this.graphics = graphics;
|
||
|
this.graphics.isNotThreeThrow();
|
||
|
|
||
|
if (R3.Utils.UndefinedOrNull(apiGame)) {
|
||
|
apiGame = {};
|
||
|
}
|
||
|
|
||
|
if (apiGame instanceof R3.D3.Game) {
|
||
|
return apiGame;
|
||
|
}
|
||
|
|
||
|
R3.D3.API.Game.call(
|
||
|
this,
|
||
|
apiGame.id,
|
||
|
apiGame.name,
|
||
|
apiGame.baseUrl,
|
||
|
apiGame.path,
|
||
|
apiGame.imageFactory,
|
||
|
apiGame.gameType,
|
||
|
apiGame.cameras,
|
||
|
apiGame.composers,
|
||
|
apiGame.viewports,
|
||
|
apiGame.renderers,
|
||
|
apiGame.renderTargets,
|
||
|
apiGame.systems,
|
||
|
apiGame.entityManager,
|
||
|
apiGame.parentEntity
|
||
|
);
|
||
|
|
||
|
if (this.imageFactory instanceof R3.D3.API.ImageFactory) {
|
||
|
this.imageFactory = new R3.D3.ImageFactory(
|
||
|
this.graphics,
|
||
|
this.imageFactory
|
||
|
);
|
||
|
}
|
||
|
|
||
|
this.cameras = this.cameras.map(
|
||
|
function (apiCamera) {
|
||
|
if (apiCamera instanceof R3.D3.API.Camera) {
|
||
|
return new R3.D3.Camera(
|
||
|
this.graphics,
|
||
|
apiCamera
|
||
|
)
|
||
|
} else {
|
||
|
console.warn('apiCamera not of type API.Camera');
|
||
|
throw new Error('apiCamera not of type API.Camera');
|
||
|
}
|
||
|
}.bind(this)
|
||
|
);
|
||
|
|
||
|
this.composers = this.composers.map(
|
||
|
function (apiComposer) {
|
||
|
if (apiComposer instanceof R3.D3.API.Composer) {
|
||
|
return new R3.D3.Composer(
|
||
|
this.graphics,
|
||
|
apiComposer
|
||
|
)
|
||
|
} else {
|
||
|
console.warn('apiComposer not of type API.Composer');
|
||
|
throw new Error('apiComposer not of type API.Composer');
|
||
|
}
|
||
|
}.bind(this)
|
||
|
);
|
||
|
|
||
|
this.viewports = this.viewports.map(
|
||
|
function (apiViewport) {
|
||
|
if (apiViewport instanceof R3.D3.API.Viewport) {
|
||
|
return new R3.D3.Viewport(
|
||
|
this.graphics,
|
||
|
apiViewport
|
||
|
)
|
||
|
} else {
|
||
|
console.warn('apiViewport not of type API.Viewport');
|
||
|
throw new Error('apiViewport not of type API.Viewport');
|
||
|
}
|
||
|
}.bind(this)
|
||
|
);
|
||
|
|
||
|
this.renderers = this.renderers.map(
|
||
|
function (apiRenderer) {
|
||
|
if (apiRenderer instanceof R3.D3.API.Renderer) {
|
||
|
return new R3.D3.Renderer(
|
||
|
this.graphics,
|
||
|
apiRenderer
|
||
|
)
|
||
|
} else {
|
||
|
console.warn('apiRenderer not of type API.Renderer');
|
||
|
throw new Error('apiRenderer not of type API.Renderer');
|
||
|
}
|
||
|
}.bind(this)
|
||
|
);
|
||
|
|
||
|
this.renderTargets = this.renderTargets.map(
|
||
|
function (apiRenderTarget) {
|
||
|
if (apiRenderTarget instanceof R3.D3.API.RenderTarget) {
|
||
|
return new R3.D3.RenderTarget(
|
||
|
this.graphics,
|
||
|
apiRenderTarget
|
||
|
)
|
||
|
} else {
|
||
|
console.warn('apiRenderTarget not of type API.RenderTarget');
|
||
|
throw new Error('apiRenderTarget not of type API.RenderTarget');
|
||
|
}
|
||
|
}.bind(this)
|
||
|
);
|
||
|
|
||
|
this.systems = this.systems.map(
|
||
|
function (apiSystem) {
|
||
|
if (apiSystem instanceof R3.API.System) {
|
||
|
return new R3.System(
|
||
|
this.graphics,
|
||
|
apiSystem
|
||
|
)
|
||
|
} else {
|
||
|
console.warn('apiSystem not of type API.System');
|
||
|
throw new Error('apiSystem not of type API.System');
|
||
|
}
|
||
|
}.bind(this)
|
||
|
);
|
||
|
|
||
|
if (this.entityManager) {
|
||
|
if (this.entityManager instanceof R3.API.EntityManager) {
|
||
|
this.entityManager = new R3.EntityManager(
|
||
|
this.graphics,
|
||
|
this.entityManager
|
||
|
);
|
||
|
} else {
|
||
|
console.warn('entityManager not of type API.EntityManager');
|
||
|
throw new Error('entityManager not of type API.EntityManager');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.buildIdToObject();
|
||
|
|
||
|
this.linkObjects(this.idToObject);
|
||
|
};
|
||
|
|
||
|
R3.D3.Game.prototype = Object.create(R3.D3.API.Game.prototype);
|
||
|
R3.D3.Game.prototype.constructor = R3.D3.Game;
|
||
|
|
||
|
R3.D3.Game.GAME_TYPE_VR_PONG = 0x1;
|
||
|
R3.D3.Game.GAME_TYPE_VR_RACER = 0x2;
|
||
|
|
||
|
/**
|
||
|
* Creates a camera instance of 'graphics' type (only THREE for now)
|
||
|
* @returns {THREE.Game}
|
||
|
*/
|
||
|
R3.D3.Game.prototype.createInstance = function(update) {
|
||
|
|
||
|
var instance = null;
|
||
|
|
||
|
if (update) {
|
||
|
instance = this.instance;
|
||
|
}
|
||
|
|
||
|
return instance;
|
||
|
};
|
||
|
|
||
|
// R3.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
|
||
|
*/
|
||
|
R3.D3.Game.prototype.updateInstance = function() {
|
||
|
this.instance = this.createInstance(true);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Converts a R3.D3.Game to a new R3.D3.API.Game
|
||
|
* @returns {R3.D3.API.Game}
|
||
|
*/
|
||
|
R3.D3.Game.prototype.toApiObject = function() {
|
||
|
|
||
|
var apiImageFactory = null;
|
||
|
var apiCameras = [];
|
||
|
var apiComposers = [];
|
||
|
var apiViewports = [];
|
||
|
var apiRenderers = [];
|
||
|
var apiRenderTargets = [];
|
||
|
var apiSystems = [];
|
||
|
var apiEntityManager = null;
|
||
|
|
||
|
if (this.imageFactory instanceof R3.D3.ImageFactory) {
|
||
|
apiImageFactory = this.imageFactory.toApiObject();
|
||
|
}
|
||
|
|
||
|
if (this.cameras) {
|
||
|
apiCameras = this.cameras.map(
|
||
|
function(camera) {
|
||
|
if (camera instanceof R3.D3.Camera) {
|
||
|
return camera.toApiObject();
|
||
|
} else {
|
||
|
console.warn('camera not an instance of Camera');
|
||
|
throw new Error('camera not an instance of Camera');
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (this.composers) {
|
||
|
apiComposers = this.composers.map(
|
||
|
function(composer) {
|
||
|
if (composer instanceof R3.D3.Composer) {
|
||
|
return composer.toApiObject();
|
||
|
} else {
|
||
|
console.warn('composer not an instance of Composer');
|
||
|
throw new Error('composer not an instance of Composer');
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (this.viewports) {
|
||
|
apiViewports = this.viewports.map(
|
||
|
function(viewport) {
|
||
|
if (viewport instanceof R3.D3.Viewport) {
|
||
|
return viewport.toApiObject();
|
||
|
} else {
|
||
|
console.warn('viewport not an instance of Viewport');
|
||
|
throw new Error('viewport not an instance of Viewport');
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (this.renderers) {
|
||
|
apiRenderers = this.renderers.map(
|
||
|
function(renderer) {
|
||
|
if (renderer instanceof R3.D3.Renderer) {
|
||
|
return renderer.toApiObject();
|
||
|
} else {
|
||
|
console.warn('renderer not an instance of Renderer');
|
||
|
throw new Error('renderer not an instance of Renderer');
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (this.renderTargets) {
|
||
|
apiRenderTargets = this.renderTargets.map(
|
||
|
function(renderTarget) {
|
||
|
if (renderTarget instanceof R3.D3.RenderTarget) {
|
||
|
return renderTarget.toApiObject();
|
||
|
} else {
|
||
|
console.warn('renderTarget not an instance of RenderTarget');
|
||
|
throw new Error('renderTarget not an instance of RenderTarget');
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (this.systems) {
|
||
|
apiSystems = this.systems.map(
|
||
|
function(system) {
|
||
|
if (system instanceof R3.System) {
|
||
|
return system.toApiObject();
|
||
|
} else {
|
||
|
console.warn('system not an instance of System');
|
||
|
throw new Error('system not an instance of System');
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (this.entityManager) {
|
||
|
if (this.entityManager instanceof R3.EntityManager) {
|
||
|
apiEntityManager = this.entityManager.toApiObject();
|
||
|
} else {
|
||
|
console.warn('entityManager not an instance of EntityManager');
|
||
|
throw new Error('entityManager not an instance of EntityManager');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return new R3.D3.API.Game(
|
||
|
this.id,
|
||
|
this.name,
|
||
|
this.baseUrl,
|
||
|
this.path,
|
||
|
apiImageFactory,
|
||
|
this.gameType,
|
||
|
apiCameras,
|
||
|
apiComposers,
|
||
|
apiViewports,
|
||
|
apiRenderers,
|
||
|
apiRenderTargets,
|
||
|
apiSystems,
|
||
|
apiEntityManager,
|
||
|
R3.Utils.IdOrNull(this.parentEntity)
|
||
|
);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Converts from an Object Game to a R3.D3.Game
|
||
|
* @param graphics R3.D3.Graphics
|
||
|
* @param objectGame Object
|
||
|
* @returns {R3.D3.Game}
|
||
|
* @constructor
|
||
|
*/
|
||
|
R3.D3.Game.FromObjectGame = function(graphics, objectGame) {
|
||
|
|
||
|
var apiGame = R3.D3.API.Game.FromObjectGame(objectGame);
|
||
|
|
||
|
return new R3.D3.Game(
|
||
|
graphics,
|
||
|
apiGame
|
||
|
);
|
||
|
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Loads a Game
|
||
|
* @param graphics
|
||
|
* @param objectGame
|
||
|
* @param onLoaded
|
||
|
* @constructor
|
||
|
*/
|
||
|
R3.D3.Game.LoadGame = function(
|
||
|
graphics,
|
||
|
objectGame,
|
||
|
onLoaded
|
||
|
) {
|
||
|
var game = R3.D3.Game.FromObjectGame(
|
||
|
graphics,
|
||
|
objectGame
|
||
|
);
|
||
|
|
||
|
onLoaded(game);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Loads a Game from the API
|
||
|
* @param graphics R3.D3.Graphics
|
||
|
* @param partialGameObject Object
|
||
|
* @param onLoaded callback
|
||
|
* @param apiUrl
|
||
|
* @returns {*}
|
||
|
* @constructor
|
||
|
*/
|
||
|
R3.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];
|
||
|
|
||
|
R3.D3.Game.LoadGame(
|
||
|
graphics,
|
||
|
objectGame,
|
||
|
onLoaded
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}(xhr);
|
||
|
|
||
|
xhr.send();
|
||
|
};
|
||
|
|
||
|
R3.D3.Game.prototype.setSize = function(width, height) {
|
||
|
this.renderers.map(
|
||
|
function(renderer) {
|
||
|
renderer.setSize(width, height);
|
||
|
}
|
||
|
);
|
||
|
};
|