당신의 플레이어와 트롤은 우리가 당신의 세계를 설명하는 데이터 모델이라고 부르는 데이터 세트 일뿐입니다. 수명, 인벤토리, 공격 기능, 세계에 대한 지식까지 모두 데이터 모델로 구성됩니다.
자신의 세계를 설명하는 모든 데이터를 보유하는 단일 기본 Model 객체를 유지하십시오. 난이도, 물리 매개 변수 등과 같은 일반적인 세계 정보를 보유 할 것입니다. 또한 위에서 설명한 특정 개체 의 데이터 목록 / 배열도 보유합니다 . 이 주요 모델은 세계를 설명하기 위해 많은 하위 오브젝트로 구성 될 수 있습니다. 게임 로직이나 디스플레이 로직을 제어하는 기능이 모델 어디에도 없습니다. 게터는 유일한 예외이며 공개 멤버가 아직 트릭을 수행하지 않는 경우 모델에서 더 쉽게 데이터를 가져올 수 있도록하기 위해 사용됩니다.
다음으로, 하나 이상의 "컨트롤러"클래스에서 함수를 작성하십시오. 메인 클래스에서 도우미 함수로 모두 작성할 수 있지만 잠시 후에 약간 커질 수 있습니다. 이것들은 각기 다른 목적 (이동, 공격 등)을 위해 엔티티의 데이터에 작용하기 위해 모든 업데이트라고합니다. 엔티티 클래스 외부에서 이러한 함수를 유지하는 것이 더 효율적입니다. 엔티티를 설명 하는 것이 무엇인지 알고 나면 해당 함수에 대해 수행해야하는 함수를 자동으로 알게됩니다.
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.
}
마지막으로 디스플레이 로직을 게임 로직과 분리하여 유지하는 것도 유용합니다. 디스플레이 로직은 "어디에서 화면에 어떤 색으로 그려야합니까?"입니다. vs. 게임 로직은 위의 의사 코드에서 설명한 것입니다.
(Dev 's note : 클래스를 사용하는 동안 이것은 모든 메소드를 이상적인 상태 비 저장으로 간주하는 함수형 프로그래밍 방식을 느슨하게 따르며 유지 된 상태로 인한 버그를 최소화하는 깨끗한 데이터 모델 및 처리 방식을 허용합니다. FP는 MVC를 달성하므로 궁극적 인 MVC입니다. 우려를 명확하게 구분하는 목표.이 질문을 참조하십시오 .)