Su jugador y su troll no son más que conjuntos de datos, lo que llamamos el Modelo de datos que describe su mundo. Vida, inventario, capacidades de ataque, incluso su conocimiento del mundo, todo consiste en el modelo de datos.
Mantenga un único objeto Modelo principal que contenga todos los datos que describan su mundo. Contendrá información general del mundo, como dificultad, parámetros físicos, etc. También contendrá una lista / matriz de datos de entidades específicas como he descrito anteriormente. Este modelo principal puede consistir en muchos subobjetos para describir su mundo. En ninguna parte de su modelo debería tener alguna función que controle la lógica del juego o la lógica de visualización; los captadores son la única excepción, y se usarían solo para permitirle obtener datos del modelo con mayor facilidad (si los miembros públicos aún no hacen el truco).
A continuación, cree funciones en una o más clases de "controlador"; puede escribirlos todos como funciones auxiliares en su clase principal, aunque esto puede aumentar un poco después de un tiempo. Se llamará a cada actualización para actuar sobre los datos de las entidades para diferentes propósitos (movimiento, ataque, etc.). Mantener estas funciones fuera de una clase de entidad es más eficiente en cuanto a recursos, y una vez que sepa qué describe su entidad, sabrá automáticamente qué funciones deben actuar sobre ella.
class Main
{
//...members variables...
var model:GameModel = new GameModel();
//...member functions...
function realTimeUpdate() //called x times per second, on a timer.
{
for each (var entity in model.entities)
{
//command processing
if (entity == player)
decideActionsFromPlayerInput(entity);
else //everyone else is your enemy!
decideActionsThroughDeviousAI(entity);
act(entity);
}
}
//OR
function turnBasedUpdate()
{
if (model.whoseTurn == "player")
{
decideActionsFromInput(model.player); //may be some movement or none at all
act(player);
}
else
{
var enemy;
for each (var entity in model.entities)
{
if (entity != model.player)
{
enemy = entity;
decideActions(enemy);
act(enemy);
}
}
}
}
//AND THEN... (common to both turn-based and real-time)
function decideActionsThroughDeviousAI(enemy)
{
if (distanceBetween(enemy, player) <= enemy.maximumAttackDistance)
storeAttackCommand(enemy, "kidney punch", model.player);
else
storeMoveCommand(player, getVectorFromTo(enemy, model.player));
}
function decideActionsFromPlayerInput(player)
{
//store commands to your player data based on keyboard input
if (KeyManager.isKeyDown("A"))
storeMoveCommand(player, getForwardVector(player));
if (KeyManager.isKeyDown("space"))
storeAttackCommand(player, "groin slam", currentlyHighlightedEnemy);
}
function storeAttackCommand(entity, attackType, target)
{
entity.target = target;
entity.currentAttack = attackType;
//OR
entity.attackQueue.add(attackType);
}
function storeMoveCommand(entity, motionVector)
{
entity.motionVector = motionVector;
}
function act(entity)
{
entity.position += entity.motionVector;
attack(entity.target, entity.currentAttack);
}
}
class GameModel
{
var entities:Array = []; //or List<Entity> or whatever!
var player:Entity; //will often also appear in the entity list, above
var difficultyLevel:int;
var globalMaxAttackDamage:int;
var whoseTurn:Boolean; //if turnbased
//etc.
}
Una nota final es que también es útil mantener su lógica de visualización separada de la lógica de su juego. La lógica de visualización sería: "¿Dónde dibujo esto en la pantalla y de qué color?" vs. la lógica del juego es lo que describí en el pseudcode anterior.
(Nota de Dev: Al usar clases, esto sigue un enfoque de programación funcional que considera todos los métodos como idealmente sin estado, lo que permite un modelo de datos limpio y un enfoque de procesamiento que minimiza los errores causados por el estado retenido. FP es el MVC definitivo, ya que logra MVC objetivo de separación de preocupaciones explícitamente. Ver esta pregunta .)