| Todas as entidades estão dentro de GameEngine, que controla inclusive os updates |
Entidades
Cada entidade tem um id, uma chave (pela qual pode ser acessada depois), um transform (posição e ângulo) e EventHandlers. O design utilizado é o de componentes: cada entidade possui vários componentes, que são acoplados.
As entidades podem ainda estar ligadas a outras entidades, e nesse caso, sua posição no mundo é setada em relação a ela. Por isso, foram definidas também subentidades. O player, por exemplo, possui uma barra de vida e vários canhões, e que, como são diferentes do player em si, são subentidades. Os eventos die (morte) e de revive (reviver) também estão relacionados.
function Entity(id, key) {
this.key = key;
this.id = id;
this.transform = new Transform(this);
this.components = new ComponentManager(this);
this.subentityManager = new SubentityManager(this);
this._eventHandlers = {};
this.baseEntity;
},
Entity.prototype.sync = function(transform) {
//Trigger of sync event here
},
Entity.prototype.destroy = function() {},
Entity.prototype.update = function() {},
Entity.prototype.die = function() {},
// Other functions that trigger events
ComponentesCada entidade possui vários componentes. Um exemplo é o Player no cliente:
| Componentes do Player no cliente |
function RespawnComponent(team) {
this.key = "respawn";
this._currentRespawnTime = null;
this._currentTime = null;
this._teamName = team.name;
};
// Inherit from a generic GameComponent class
RespawnComponent.prototype = Object.create(GameComponent.prototype);
RespawnComponent.prototype.constructor = RespawnComponent;
RespawnComponent.prototype.init = function() {
// Add events
this.owner.on('entity.die', this.onEntityDie.bind(this));
this.owner.on('entity.revive', this.onEntityRevive.bind(this));
};
RespawnComponent.prototype.update = function() {
// If the player is currently dead, count time to respawn
};
RespawnComponent.prototype.onEntityDie = function() {
// Start respawn counter
};
RespawnComponent.prototype.onEntityRevive = function() {
// Ends respawn counter
};
Game Engine Todas as entidades devem estar inseridas em um contexto. A GameEngine é quem controla tudo. Como é única para cada partida e não deve ser instanciada mais de uma vez, é uma classe Singleton, ou seja, só possui uma instância.
A Game Engine, que é a mesma tanto para o cliente como servidor, trata da física e é o mais genérico possível, podendo ser utilizada inclusive para outro jogo totalmente diferente.
Uma versão "resumida" está representada aqui.
// Singleton class
var GameEngine = (function () {
var instance;
function init() {
// Private properties, functions and physics stuff
var _world = //receive world from p2
var _entities = {};
var _deleteEntities = function() {
// Delete entities
};
/* Physics stuff skipped here */
return {
// Public properties and functions
entities: _entities,
world: _world,
gameStep: function() {
// Runs game step
// Calls entities update
},
addEntity: function(entity, id) {},
deleteEntity: function(entity) {}
};
};
return {
getInstance: function () {
if (!instance) {
instance = init();
}
return instance;
}
};
})();
Todas as classes aqui representadas são protótipos, claro, mas é fácil ver que podemos extender a lógica para componentes e para o jogo.
Nenhum comentário:
Postar um comentário