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 eventsComponentes
Cada 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