Simple Game Engine
Oct 2007 (C++) 3D Game Engine
Overview
The following document was created before starting programming the project and was updated during the development to correct mistakes and add other unforeseen cases.
Project Objectives
- Train C++ skills
- Experience DirectX API
- Design a simple game engine to complete a simple function requirement
Functional Requirements
- Load a mesh file
- Rotate the camera around it
Non Functional Requirements
- Use DirectX
- Use C++ language
Classes and Design Descriptions
This section will only describe the intention of each class developed. This section was done before coding and updated when needed.
Game Engine Design
My main idea was to create a simple game engine were the programmer would not have to worry about DirectX and would only have to use the engine object functions. To do this I have created a class to control the application and the DirectX Devices. The class is BSDevice and it controls many aspects of the program.
The main object is the BSScene, which would have every object of the Scene such as terrains, meshes and effects, but in this test I only implemented the mesh. Each scene can have only one main camera, although we are able to create many cameras and select which one to use.
The last main object is the BSGUI, it holds every 2D objects to be draw. My initial idea was to have only one simple component to draw a debug in the screen, however I decided to prepare the base of a GUI system.
BSDevice
We will be able to choose the configurations before creating the devices. It is really created when the function .run() is executed and it returns a boolean value in order to confirm that everything is working properly. It can also be created when adding new objects to the device. In the .run() function we will also verify the inputs but only if we have defined the listener.
Device Event
This case is based on Observer Design Pattern. The BSDevice has the DirectX inputs (keyboard and mouse) and it will process every input in the run. A method will be used to manipulate those events, so every piece of code can have its own events added on the device, and then they would be able to process it. For example, a game form (like connection form) would be a complete and isolated piece of code with its event methods added onto the device.
To do so, we have two different methods (mouse and keyboard) with two different structs defined by the DirectX with the data to be processed and those methods are inserted on respective listeners of the Device.
BSScene
The scene will hold every object of the Scene, so it will have a global function named DrawAll to draw every object however we are able to draw isolated scene objects.
BSCamera
This object is the perspective view of the scene; it will hold the looking position or object and view properties. The camera is independent from devices and scenes. This way we can use the same camera position to various scenes and devices.
BSSceneContainer
This class provide the ability to be a Scene Container. The scene itself is one, and the SceneNod. Note: functions in this class are protected and must be overloaded to be public.
BSSceneObject
The scene object has the position and can generate the matrixes of their angles, scales and position.
BSSceneNod
This class allows to the scene objects have containers and draw them. Mostly of objects will be derived from this class, for example, cars could hold people and a mesh could hold a sword.
BSMeshObject
It holds the DirectX Mesh and has the basic attributes and functions to handle meshes. This must be the base object to handle every kind of Mesh type. I will create a specific sub class to handle with unique mesh characteristics (if any). Note: I will not abstract this object even further, like textures (to various mesh use same textures).
BSGUIContainer
Some GUI components will have the ability to hold some other components, and this class will allow it. For now, only the BSGUI has the property, but later probably the Edit Box will have it.
BSGUI
This object will hold every 2D object such as sprites and texts however initially I was only creating the Label to debug, but later I decide to create buttons and an editbox. This class will hold a single sprite to draw which will be used to draw texts.
BSGUIObject
This is the base object for all Gui Components. It has only the basic information such as parent and draw functions. This class does not hold the position because some objects are “ invisible” such as BSFont.
BSGUIPosObject
This class now add the positioning properties to the BSGUIObject.
BSFont
BSFont will create the font in the device with some properties which we could change later. Every FONT component will use this class as reference to draw, for example BSLabel.
BSLabel
We need to draw some texts in the screen and this class allows it. It uses the BSFont to draw the text, but it contains the text itself, colour and position. Probably other classes will use this object to draw texts, for example BSEdit.
Test Use Cases
How the things are supposed to work. It is ideas of how to do the code and help to develop ideas and foresee mistakes.
Game Engine Test Case
First we would define the properties of the device and then create it. Before running it we will define the functions to be added in the device’s listener. Those functions would be to use the keyboard and mouse to rotate the camera, also to verify the mouse click to hit the mesh. Now we will create the camera to be used in the scene and create the scene using the MeshObjects.
For the first development I will use an .X to be able to test the MeshObject and later I will create my own mesh file type.
In a while we will verify if the device is running and draw the scene. I will also add an extra object to keep moving around the main central mesh.
EditBox Test Case
To create a EditBox we first need to create font to be used. Then, we reate the Editbox itself and define the font. The EditBox itself will be a GUIPosObject and it will have a BSGUILabel inside to use as text.
Drawing Object Test Case
The scene have many objects and every object can have many objects inside. When we call the draw method we will first draw the object itself and then draw the rest of his “childrens”. If we move one object, every object inside will also move; same for rotation. The positions of each object are relative to the Parent’s position. Currently we can’t get the real position or define the real position of the childrens, but later I could calculate the angles of each parent to get it.
Know Problems
I have made this section just because I know this engine is not perfect and I know about some problems, and others may come when using. So it I am listing them to improve and learn.
I am fully aware that basically it has almost no error handling. The object lists are really unsafe.
No pattern used to name the variables. Later I realised how important it is in C++.
The abstraction level is not even higher to save time and due to my lack of experience in this kind game developing and language by itself.
No priority order to draw elements. The order is defined when added to the containers and by groups (e.g.: first 3d objects then GUI objects [both sprites and texts])
It is a really simple and limited game engine. Many objects could have more functions to control their properties, like the device could have method to change its configurations easily.
|