注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

秒大刀 博客

好好学习 天天向上

 
 
 

日志

 
 
 
 

[译]QuickStart 3D引擎设计文档  

2010-02-02 21:17:35|  分类: Game |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
[译]QuickStart 3D引擎设计文档 - 秒大刀 - 秒大刀 博客

 >> Click here for screenshots

 

    QuickStart Engine (3D Game Engine for XNA)

    The QuickStart Engine is an engine designed to allow a programmer to get a 3D game started in XNA Game Studio as quick as possible. The QuickStart Engine is designed to make it easier to get a 3D XNA project off the ground, by taking care of the framework for you, like physics, animation, rendering, etc. Some of this is still lacking, but the point in having a community project is that anyone can pick it up and add to the engine, or optimize what is already there.


QuickStart 3D引擎

设计文档

Overview
QuickStartGame

    QuickStart引擎主要是QuickStart.Common 名字空间下的QuickStartGame(译注:在对应的代码中QuickStartGame已经被更名为QSGame)类控制的。该类从XNA的Game继承而来,并封装了QuickStart的功能,用户不必关心底层的处理细节。用户从QuickStartGame继承的方式和通常情况下从XNA框架的Game继承类似。Game类的所有功能对QuickStartGame的子类都是可用的。
    QuickStartGame引擎的主要功能是管理各个子系统,确保子系统能进行消息传递,并管理游戏状态。从QuickStartGame继承而来的用户类中可以按需去重写任何public virtual方法,但要确保该方法调用时基类实现也会被调用。例子:如果用户重写了QuickStartGame中的BeginDraw方法,则在实现中必须有一句base.BeginDraw()来保证基类对应的方法被调用。
    客户代码通过QuickStartGame类来访问子系统的方式确实非常优雅。子系统通过BindSubSystem()方法绑定到QuickStartGame后,即可通过GetSubSystem<T>()得到对应子系统的引用,其中T为子系统的接口类型。

Game States
    为了处理游戏中常见的各种状态,QuickStart引擎实现了一个游戏状态栈来维护当前的游戏状态,上一个游戏状态,以及当前未启用的游戏状态。任何时候,至少有一个游戏状态处于活动状态,否则引擎将会终止运行。游戏状态是对游戏中各种具有不同实现状态的抽象,如菜单、切屏、选择菜单等。
    所有的游戏状态必须从GameState抽象类继承而来。通过该类提供的通用接口,引擎得以和游戏状态交互。游戏状态子类需要实现以下方法:

EnterState():  当状态第一次进入时激发
ExitState():  当离开状态时激发
SuspendState(): 将状态挂起(非活动状态,但并未离开状态)时激发
ReEnterState(): 当挂起的状态被激活时激发
Update(float dt):  每帧调用
Render():   每帧调用

    状态通过QuickStartGame (或其子类)实例中的PushState()和PopState()方法进入活动和非活动状态。若要状态总是(除非退出时)保持活动状态,则需要在调用Game.Run()启动游戏前先调用PushState()。

Message Passing
    大多数子系统之间的通过消息解析系统来通信。其中包括输入状态改变,每帧的更新广播等时间。任何类都可通过给QuickStartGame实例的QuickStartGame.EngineMessageEvent事件赋上一个事件处理句柄来对其订阅。事件处理句柄必须返回void,并且只能携带一个EngineEvent类型的参数。EngineEvent中包括了要接受到的消息相关的所有信息,如下所示:

type: 消息类型枚举,参考EngineEventType。
intValue:  赋给消息的一个整型值
vectorValue: 赋给消息的一个4D向量
axis: 输入相关的字段,用来描述改变了的输入控制轴。
dt:   Update消息之间消逝的时间

一等子系统
    QuickStart引擎采用模块化设计,由一组相互独立的一等子系统组成。每个一等子系统都通过接口实现,并对引擎的其余部分保持逻辑上的抽象。用户在运行时创建子系统实例,并通过BindSubSystem()将其绑定到QuickStartGame实例。提倡子系统通过消息解析来实现某种逻辑处理和通信(参考上面的消息解析章节)。用户代码可以任意实现子系统,只要实现和所要求的接口相匹配即可。

Input
    输入子系统的接口IInputSubSystem提供了对所有平台上输入设备的抽象,如Xbox 360或Windows平台上的键盘鼠标。 InputEventBegin事件将在键盘、鼠标或手柄的按键按下时触发,InputEventEnd事件将在这些键被释放时触发。类似的,InputAxisMove事件在鼠标移动或者手柄按钮移动后触发。
    InputEventBegin和InputEventEnd事件只对绑定的键/按钮发送。调用BindKeyMapping()、 BindMouseMapping()和BindGamePadMapping()需要将输入事件绑定到用户事件上。输入事件在Microsoft.Xna.Framework.Input.Keys、 QuickStart.Common.Interfaces.MouseEvents和QuickStart.Common.Interfaces.GamePadEvents枚举中定义。绑定函数将上面枚举的值与用户自定义的一个整型事件类型映射起来。当某个被绑定的输入键/按钮被按下或释放,对应的用户定义的整型事件类型的InputEventBegin或InputEventEnd事件将会被激发。比如,下面的代码将‘A’键绑定到MyEvents枚举下的MoveLeft的用户事件枚举(假设input是IInputSubSystem接口的实例):

input.BindKeyMapping(Keys.A, (int)MyEvents.MoveLeft);

    留意上面需要将枚举事件类型转型为整型。出于性能原因,用户的事件类型被作为整型处理而不是枚举类型。这使得输入子系统内部的键映射尽可能的高效,而且也为用户提供了使用不同种类枚举的可能性。
    InputAxisMove事件中的axis字段表明了那个输入轴发生了移动,相应的值参考InputAxis定义。此外,对于手柄事件,intValue字段定义了手柄数量[0-3]。

Graphics
    [未完待续]
    图形子系统尚未被实现。在当前版本中仅为一个占位原型。有志愿者吗?

Scene Manager
    场景管理接口ISceneManager提供了对场景管理器的抽象接口,用来处理空间分割,游戏逻辑更新,渲染队列更新等。如果把QuickStartGame比作引擎大脑的话,场景管理器其实就是引擎的心脏。场景管理器负责将游戏逻辑表现在场景上,通常通过扩展的用户脚本,也从物理处理器获得位置信息。

Audio
    [未完待续]

Network
    [未完待续]

二级子系统
    二级子系统功能上合一级子系统等价,但其并不是对可通过QuickStartGame实例访问,并对所有类可见的普通接口实现。仍可以通过BindSubSystem()方法将子系统注册到引擎,但注册时需要使用该二级子系统的真实类型,而不是其接口类型。二级子系统通常由一级子系统或用户代码实例化,并且不会在和其他的子系统交互。

GUI
    图形用户界面系统实现了GUI元素的绘制和更新,以实现玩家和游戏的互动。
    [未完待续]

Physics
    物理子系统是用来模拟环境物理特性的。考虑到性能原因,物理系统通常直接绑定到场景管理器。
    [未完待续]

Tutorials
    创建基本的游戏框架
    [我们有场景管理之后会很快实现]


QuickStart 3D Engine
Design Document

Overview
QuickStartGame
    The QuickStart engine is centrally controlled by the QuickStartGame class, found in the QuickStart.Common namespace.  This class derives from the XNA Game class and encapsulates the QuickStart engine functionality so clients need not be concerned with low-level processing details.  As such, clients should derive a class from QuickStartGame in the same way a typical XNA Framework game will derive from Game.  All functionality available to derived classes of Game is available to derived classes of QuickStartGame.
    The primary responsibility of QuickStartGame is to manage the engine sub-systems, enable message-passing between sub-systems, and manage the game state system.  Clients deriving from QuickStartGame are free to override any of the public virtual methods, provided that control is passed to the base class implementation once per call.  For example, if a client overrides QuickStartGame’s BeginDraw() method, a call to base.BeginDraw() must appear in the implementation.
    If needed, direct access to sub-systems from client code can be achieved through the QuickStartGame class.  Once a sub-system has been bound with BindSubSystem(), a call to GetSubSystem<T>(), where T is the interface type, will return a reference to the sub-system in the form of the interface type T.

Game States
    To handle the many possible states found in a game, the QuickStart engine implements a game state stack which maintains the current game state, as well as previous, currently inactive game states.  At any given time, at least one game state must be active.  Otherwise, the engine will terminate.  This abstracts a specific game state from the rest of the game and allows for states such as menus, cut-scenes, and options menus to be implemented independently of each other.
    All game states must derive from the GameState abstract class.  This class provides a common interface through which the engine can communicate with game states.  Derived game states must implement the following methods:

EnterState():  Called when a state is activated for the first time.
ExitState():  Called when a state is terminated.
SuspendState(): Called when a state is suspended (inactivated), but not terminated.
ReEnterState(): Called when a suspended state is re-activated.
Update(float dt): Called once per frame.  
Render():   Called once per frame.

    States are activated/deactivated through calls to PushState() and PopState() on the client’s (derived) QuickStartGame instance.  As it is necessary for a state to be active at all times (except when exiting), a call to PushState() must be made before Game.Run() is called to start the game.

Message Passing
    The majority of inter-sub-system communication occurs through a message-passing scheme.  This includes events such as input state changes and per-frame system update broadcasts.  Any class with a reference to a QuickStartGame instance can subscribe to these events by assigning an event handler to the QuickStartGame.EngineMessageEvent event.  The event handler must return void and take exactly one parameter, an instance of EngineEvent.  This structure contains all information related to the message being received, and is outlined below:

type: The enumerated type of the message.  See EngineEventType.
intValue:  The integer value assigned to the message.
vectorValue: The 4D vector value assigned to the message.
axis: Input-specific field describing the input control axis that has changed.
dt:   The elapsed time between updates for Update messages.


First-Class Sub-Systems
    The QuickStart engine is designed to be modular, and as such it is composed of several first-class sub-systems, each of which acts independently of the others.  Each sub-system is implemented through an interface and is logically abstracted from the rest of the engine.  At run-time, instances of sub-systems are created by the client program and bound to the QuickStartGame instance through a call to BindSubSystem().  Each sub-system is responsible for implemented a certain form of processing logic, and communication using message-passing is encouraged (see Message Passing section above).  Client code is free to re-implement sub-systems at will, provided the implementations match the given interfaces.

Input
    The input sub-system interface IInputSubSystem provides an abstraction to the Xbox 360 controller on all platforms, as well as the mouse and keyboard devices on Windows platforms.  InputEventBegin events are sent whenever a bound key, mouse button, or game pad button is pressed, and InputEventEnd events are sent whenever a bound key, mouse button, or game pad button is released.  Similarly, InputAxisMove events are sent whenever the mouse or a game pad thumb stick is moved. 
    InputEventBegin and InputEventEnd events are only sent for bound keys/buttons.  Calls to BindKeyMapping(), BindMouseMapping(), and BindGamePadMapping() need to be made to bind input events to client events.  Input events are defined in the Microsoft.Xna.Framework.Input.Keys, QuickStart.Common.Interfaces.MouseEvents, and QuickStart.Common.Interfaces.GamePadEvents enumerations.  The bind functions will map the appropriate enumeration value to a client-defined integer event type.  When the corresponding input key/button is pressed/released, a corresponding InputEventBegin or InputEventEnd event will be fired with the client’s integer event type.  For example, the following code will bind the ‘A’ key to a client event named MoveLeft, found in the client-defined MyEvents enumeration (assume input is a reference to a IInputSubSystem instance):

input.BindKeyMapping(Keys.A, (int)MyEvents.MoveLeft);

    Note the casting to integer for the enumerated event type.  For efficiency reasons, the client event type is treated as an integer and not an enumerated value.  This allows the input sub-system to internally be as efficient as possible in key mappings, as well as provide the client the ability to use arbitrary enumerations.
    For InputAxisMove event, the axis field specifies which input axis has moved.  The InputAxis enumeration defines the corresponding values.  Furthermore, for game pad events, the intValue field defines the game pad number [0-3].
Graphics
    [Section Needed]
    The graphics sub-system has not been outlined/implemented as of yet.  The version in the prototype is merely a place-holder.  Volunteers?
Scene Manager
    The Scene Manager interface ISceneManager provides an abstraction to the scene manager, which handles all spatial partitioning, game logic updates, and render queue updates.  In essence, the scene manager can be considered the heart of the engine, while the QuickStartGame class is the brain.  The scene manager is in charge of applying game logic to the scene representation, usually in the form of external client scripting, as well as receiving position data from the physics processor.
Audio
    [Section needed]
Network
    [Section needed]
Second-Class Sub-Systems
    Second-class sub-systems are functionally equivalent to first-class sub-systems, except that they do not implement a common interface that is visible to all classes with a reference to QuickStartGame.  BindSubSystem() can still be called on these sub-systems if required, but they must be registered with their full types, not interface types.  Second-class sub-systems are typically instantiated directly by first-class sub-systems or client code, and are not shared among other sub-systems.
GUI
    The graphical user interface sub-system is responsible for drawing and updating GUI elements that allow users to interact with the game.
    [Section needed]
Physics
    The physics sub-system is responsible for simulating physical attributes of the environment.  It is usually directly tied to the scene manager for efficiency reasons.
    [Section needed]

Tutorials

1. Creating a basic game skeleton

    [Implement once we have a working scene manager]


原始设计文档地址:http://quickstartengine.codeplex.com/SourceControl/list/changesets 下载源码中doc目录下的DesignDocument.doc,文档最后更新日期为2007-10-26。

  评论这张
 
阅读(1125)| 评论(2)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018