Game engine mode design
(USING DESIGN PATTERNS in Game Engines)
BY
Rasmus Christian Kaae
Kaae@daimi.au.dk
Student of Computer Science and Program At Tietoenator Consulting A / S
August 2001
All Rights Reserved
Translation: Room3rd@hotmail.com
April 5, 2005
1.0 Introduction
About mode design, we are not strange, in the initial phase of the project design, can give us a great help, providing how to segment the policy and how to make a smaller segment into several functions. In this article, I will use the pattern design to explain how to construct the game engine. These awareness is based primarily based on personal experience and study in computer sciences in AARHUS Comprehensive University. For different purposes and needs, the design model is also different. Here I will clear the basic mode design by constructing the MODEL-View-Control of the game, and the core structure of the 3D engine.
Before reading, it is recommended that you know the polymorphism of C .
Model-View-Control of the 2.0 engine kernel
The engine kernel should be able to handle all tasks involved in the game, which means that processing may include user input, other users' possible input (online games), game event, of course, should also include audio, video output. In order to achieve this, I introduced Model-View-Control design mode, which divides the engine into three important parts.
Model-View-Control is very useful for GUI program designs, which can provide some degree of modularity, so that programs can be implemented using existing graphics output devices. For example, using the latest DirectX SDK, the game engine can implement a DirectX program that creates an execution, and if it is changed to OpenGL. Since the implementation of the dialog box for the game engine and DirectX is hidden in the View class, the transplant is too simple - should only be changed if the View class needs to be changed.
Detailed description of the Model-View-Control structure can be viewed at http://ootips.org/mvcpattern.html and http://compsci.about.com/cs/mvcpattern/index.htm.
2.1 Model (Model)
The structural model should contain all game structures, such as 3D-engine structures, behavioral modes (Behaviour Pattern, how to handle user input).
The model part is independent of the VIEW and Control parts of the structure, which means that the model portion can be used separately in additional environments.
2.2 View
The View section contains all the outputs of the user, so you should include video audio conveying. For example, here you need to implement OpenGL and DirectX drivers.
This part is related to the model part, that is, the VIEW portion can deliver information between the user and the model.
2.3 Control
The Control section is the most basic part of the structure. After initialization, it assigns a View instance and model class instance, and waits for user input. Then the user's input is processed by the mutual model part, and then the view is requested to map the current model status.
2.4 sample code
The following code is a pseudo-C code, so it cannot be compiled.
/ * InputBlock contains the current input of the user * /
Class InputBlock
{
// Todo: Add some interesting variables and functions to display user input
}
/ * Game Model * /
Class Model
{
PUBLIC:
Engine3D * m_ENGINE;
Sound * m_sound;
MODEL ();
UpdateControl (InputBlock * INPUT) {
// TODO: Definitely current input
}
}
/ * Viewvisual is an interface class that implements video drivers * /
Class ViewVisual
{
PUBLIC:
Viewvisual ()
{
}
// Pure virtual function is used to handle changes in the current model
Virtual void Update (model * model) = 0;
}
/ * ViewvisualOpenGL is an implementation of ViewVisual interface * /
Class ViewVisualopenGL
{
PUBLIC:
ViewvisualopENGL ()
{
// Todo: Initialization code
}
// Display the current state of the model
Void Update (Model * Model)
{
// Todo: Draw MODEL-> M_ENGINE
}
}
/ * ViewAudio is an interface class for audio driver * /
Class Viewaudio
{
PUBLIC:
Viewaudio ()
{
// Todo: Initialization code
}
/ / Pure virtual function contains processing of current model changes
Virtual void Update (model * model) = 0;
}
/ * ViewaudiodirectSound DirectSound implementation for Viewaudio interface * /
Class ViewaudiodirectSound
{
PUBLIC:
ViewaudiodirectSound ()
{
// Todo: Initialization code
}
Void Update (Model * Model)
{
// Todo: Play the current sound from model-> m_sound
}
}
/ * View is a video, audio class * /
Class view
{
protected:
Viewvisual * m_visual;
Viewaudio * m_audio;
PUBLIC:
View (Model * Model, ViewVisual * Visual, Viewaudio * Audio)
{
M_Model = Model;
M_Visual = Visual;
m_audio = Audio;
}
void update ()
{
m_visual-> Update (m_model);
m_Audio-> Update (M_Model);
}
}
/ * Control class handler user input and start output * /
Class Control
{
ENUM
{
Escape_is_pressed,
User_INPUT
}
Private:
View * m_view;
MODEL * M_MODEL;
PUBLIC:
Control ()
{
M_Model = new model ();
m_view = new view (m_model, new viewvisualopENGL (),
New ViewAudiodirectSound ());
}
~ Control ()
{
DELETE M_MODEL;
Delete M_View;
}
InputBlock Input (INT Which)
{
Switch (Which)
{
Case User_exit:
IF (escape_is_pressed) Return NewInputBlock (escape_is_pressed);
Break;
Case User_Input:
IF (user_has_made_an_input) Return New InputBlock (THE_NEW_INPUT_INFO);
Break;
}
}
Void Run ()
{
While (! INPUT (user_exit))
{
IF (Input (user_INPUT))
M_Model-> UpdateControl (INPUT); M_VIEW-> Update ();
}
}
}
/ * Main function assigns our structure and starts running * /
Void
Main
(int Argc, char ** argv)
{
Control * control = new control ();
Control-> Run ();
DELETE control;
}
2.4.1
Description of the code
The above code will first initialize the controller (Controller) and then assign an OpenGL output device, a DirectSound output device, a model, after the assignment, the main program calls the controller's Run () function, the function A loop knows that a loop knows that the user is pressed. The program will update the model and view until the user exits according to the input given. If the input is given, the input is analyzed to the model module. When the input (or missing input) has been processed, the controller requests the View to update. When exiting, the above also demonstrates the clearance code.
2.5 a graphical representation
The above figure shows the connection between the current Model-View-Control structure, and the Control passes the message to Model and View, and the View retrieves data from Model. These relationships should be changed to adapt to actual needs. I I like the above way, because all types have sufficient independence. However, it is better to add a communication line between Model and View to Controller, which allows a notification when there is a sudden error occurred.
3.0 3D engine layer mode
The original intention of the tissue 3D engine kernel is to access the code as easy as possible. As an example, it should be able to "say" Scene-> M_ActiveCameraera-> Lookat (POS, TARGET), and then the entire scene will change by this; also should be 3D-Model load in the "hidden" layer, so anything All will be handled at higher levels (thus drawing the View section of the engine kernel). The entire engine will be differentiated to at least 3 layers, each of which is an upper extension, and it is getting lower and lower.
3.1 top
The top layer provides a basic interface for modifying the current scenario status. The upper layer passes the input to the low layer of the structure, for example, the player moves to a new location, the top layer will confirm that a specific player object will get a new panning point, and the next redrawn can guarantee the player in the correct position. The lights and cameras are also true (in the first person design game, the camera is the player's perspective).
3.2 2nd floor
The second layer is more in-depth, including all classes and future extension interface classes, such as different types of light sources (spotlights, floodlights, lighting points, etc.).
3.3 Level 3 and lower level
These layers will include specific implementations such as light, hiearchy-objects, and more.
3.4 sample code
In order to illustrate the definition of (unclear) 3D-engine layer, some sample code is given here.
/ * Layer 2 - lighting, including a variety of different types of light source interfaces to be implemented * /
Class Light
{
PUBLIC:
ENUM
{
Omni
}
INT M_LIGHT_TYPE;
Virtual void * getdata () = 0;
}
/ * Layer 3 - Lightomni - Direct implementation of lights * /
Class Lightomni: Public Light? PUBLIC LIGHT
{
PUBLIC:
Lightomnidata * m_light_omni_data;
Lightomni () {m_light_type = omni;
Void * getdata () {return m_light_omni_data;}};
/ * Layer 2 - object, including object interface to be implemented * /
Class Object
{
PUBLIC:
Vector * m_vertices;
Face * m_faces;
/ / Set the current panning point of the specified object
Virtual void settranslation (vector & v) = 0;
// Fill the pointer with a large amount of data
Virtual Void getObjectData (Vector * Out_vertices, Face * Out_Faces,
INT * OUT_NUM_FACES = 0;
}
/ * Layer 3-ObjectHierachy - Direct implementation of the object * /
Class Objecthierachy: Public Object
{
PUBLIC:
Objecthiearchy * m_child;
Vector m_translation;
// Set the current pan
Void setTranslation (Vector V) {Translation = V;
// Fill the pointer with a large amount of data
Void getObjectData (Vector * Out_vertices, Face * Out_Faces,
INT * OUT_NUM_FACES)
{
Objecthiearchy * o = this;
While (O-> CHILD! = NULL)
{
// Add data from "O" to OUT_VERTITICES, OUT_FACES and OUT_NUM_FACES
}
}
}
/ * Contains the upper layer of the hierarchical structure
Note: It is recommended to use a link list in the scene class (LinkedLists) instead of static arrays, because this is only example, it is not described in detail * /
Class Scene
{
PUBLIC:
Camera * m_currentcamera;
Camera ** m_cameras;
Light ** m_lights;
Object ** m_Objects;
}
3.5 illustration
Top
Scene
Second floor
Objects
Light
Camera
the third floor
Hiearchy
Other
Spot
Other
The above figure shows the relationship between each layer. Designed or above, you can get rid of the tedious detail, and abstract each of the object types and write universal code to complete the Object class (also Light, Camera).
4.0 Conclusion
Due to need, I wrote this article - I have already found similar articles for a long time (and not so lucky). This article should be considered to be inspired by the game engine (it may not be a perfect solution). As a programmer, I'm using the design model, (in development) is very good, Since it is allows you to lean back and use trusted structures, instead of reinventing the wheel (I don't know how to translate better J).
Chapter 3.0 and 4.0 Might Be Subject To Discussions Since The IMPIDIVIDUAL ELEments To BeconsideRed. For the 3D-Engine The IMPLEMENTATION MAY DIFFER from ONE 3D-Editor To Another.
Have fun with the programming,
Rasmus Christian Kaae