Tutorials/02GameType
From NeoAxisWiki
Contents |
Tutorial 2 - Starting your own game
Introduction
We have created our first map so far, and tested it with the Action gameplay. This means that our map actually ran with gameplay code that is obviously not related to a BreakOut game.
In this tutorial we are going to provide the base architecture of our gameplay and then we are going to run the map we have already created with this new gameplay.
Preparing for this tutorials
This tutorial does not require the installation of any material. Please, just complete the first tutorial of the series, as this one catches up where the first one finished.
Defining a new Game Type
Open then NeoAxis Visual Studio solution, called NonCommercialLicense.sln.
Now what you see, is the code of the Example Game provided with the SDK. Our game will be heavily based on the existing code from the SDK, so as a general rule we will try to not modify anything unless it is strictly necessary, and place all our game code in new classes and files. This will make integration with new versions of the SDK easier.
The example SDK consists of three projects:
- Game, which contains the core classes of our game.
- GameEntities, which contains the entity classes that define the game objects.
- WindowAppExample, which is an example of how to run NeoAxis inside a WinForm.
Now locate the class GameMap inside the GameEntities project. This class contains the common functionality for all maps on our game.
The only modification we need to do, is to add a new game type called BreakOut to the existing GameTypes enum definition:
public enum GameTypes
{
None,
Action,
RTS,
TPSArcade,
//Put here your game type
BreakOut,
}
Creating the Game Window
The game Window is the core of the new gameplay. This class represents the entry point of our game logic processing.
A videogame core typically consists of two main game loops:
- The Update loop, in which everything is updated according to game logic. Updating the value of objects in a game allows you to simulate effects like animation, object movement and so on. In some game engines, like NeoAxis, update occurs at a fixed rate of 30 times per second.
- The Render loop, in which everything is rendered using the objects values, that where updated on the previous cycle. This occurs as many times per second as possible.
We are now creating a new class from scratch, called BreakOutGameWindow on the Game project.
Copy paste the following code into the class file:
using System;
using System.Collections.Generic;
using System.Text;
using GameEntities;
using Engine;
using Engine.MathEx;
using Engine.EntitySystem;
using Engine.MapSystem;
using Engine.UISystem;
namespace Game
{
class BreakOutGameWindow : GameWindow
{
protected override void OnTick(float delta)
{
base.OnTick(delta);
//This lauches a Tick event on all entities
EntitySystemWorld.Instance.Tick(false);
}
protected override void OnRender()
{
base.OnRender();
//TODO: Specific render logic goes here
}
protected override void OnGetCameraTransform(out Engine.MathEx.Vec3 position, out Engine.MathEx.Vec3 forward, out Engine.MathEx.Vec3 up, ref Engine.MathEx.Degree cameraFov)
{
//get the default spawn point
SpawnPoint spawnPoint = SpawnPoint.GetDefaultSpawnPoint();
//place the camara above the spawn point
position = spawnPoint.Position + new Vec3(0, 0, 10);
//look at some point above the paddle (around the center of the game board)
Vec3 lookAt = spawnPoint.Position + new Vec3(5, 0, 0);
//the forward direction of the camera is
forward = (lookAt - position).GetNormalize();
//the up vector, is the one perpendicular to XAxis and forward.
up = Vec3.Cross(forward, Vec3.YAxis);
//use a fov of 80 degrees
cameraFov = new Degree(80);
}
protected override bool OnKeyDown(KeyEvent e)
{
//To pass the command in Controllers system
if (GameControlsManager.Instance.DoKeyDown(e))
return true;
return base.OnKeyDown(e);
}
protected override bool OnKeyUp(KeyEvent e)
{
//To pass the command in Controllers system
if (GameControlsManager.Instance.DoKeyUp(e))
return true;
return base.OnKeyUp(e);
}
}
}
This is the minimal functionallity you need to provide the game window with. Let's take a closer look to the firs method:
protected override void OnTick(float delta)
{
base.OnTick(delta);
//This lauches a Tick event on all entities
EntitySystemWorld.Instance.Tick(false);
}
When you inherit from the GameWindow class, you are allowed to override the OnTick method. This code will be called by the engine at a fixed rate of 30 times per second. Here you have the chance to do any calculation required in your game update loop. In our case, we just tell the EntitySystemWorld to Tick. This call will allow each game entity to update themselves.
Now let's take a look at the following method:
protected override void OnRender()
{
base.OnRender();
//TODO: Specific render logic goes here
}
This method does nothing so far. It's only provided for future use. This will be called before each frame is rendered, for you to do any process that may be required to be done at that time, like updating the screen textual information (like a scoreboard, or a timer).
And now, let's take a look at the next one:
protected override void OnGetCameraTransform(out Engine.MathEx.Vec3 position, out Engine.MathEx.Vec3 forward, out Engine.MathEx.Vec3 up, ref Engine.MathEx.Degree cameraFov)
{
//get the default spawn point
SpawnPoint spawnPoint = SpawnPoint.GetDefaultSpawnPoint();
//place the camara above the spawn point
position = spawnPoint.Position + new Vec3(0, 0, 10);
//look at some point above the paddle (around the center of the game board)
Vec3 lookAt = spawnPoint.Position + new Vec3(5, 0, 0);
//the forward direction of the camera is
forward = (lookAt - position).GetNormalize();
//the up vector, is the one perpendicular to XAxis and forward.
up = Vec3.Cross(forward, Vec3.YAxis);
//use a fov of 80 degrees
cameraFov = new Degree(80);
}
The game window is also responsible for updating the camera position. This method will be called to let you specify on a per frame basis, where the camera should be placed.
In our game, we are using a static camera. ¿Remember the SpawnPoint we placed on the map? We are getting this spawnpoint and the using its position to place the camera 5 units above it. Then we make the camera point approximately to the center of the room, using some vector math.
The fov (field of view) is the lens aperture. We provide a fixed value of 80 degress.
protected override bool OnKeyDown(KeyEvent e)
{
//To pass the command in Controllers system
if (GameControlsManager.Instance.DoKeyDown(e))
return true;
return base.OnKeyDown(e);
}
protected override bool OnKeyUp(KeyEvent e)
{
//To pass the command in Controllers system
if (GameControlsManager.Instance.DoKeyUp(e))
return true;
return base.OnKeyUp(e);
}
Finally, we provide the methods for basic input handling, OnKeyDown and OnKeyUp. These methods will simply delegate the key presses on NeoAxis Controllers system. We'll be handling the user input in the next tutorial, so don't worry about that yet.
Associating our BreakOut map with our BreakOutGameWindow
We need to tell NeoAxis that we want our BeakOut01 map (created in the first tutorial) to run using our new BreakOutGameWindow. To do this, locate the method CreateGameWindowByGameType of the GameEngineApp class, which is also on the Game project.
Locate this method and modify it like this:
GameWindow CreateGameWindowByGameType( GameMap.GameTypes gameType )
{
switch( gameType )
{
case GameMap.GameTypes.Action:
case GameMap.GameTypes.TPSArcade:
return new ActionGameWindow();
case GameMap.GameTypes.RTS:
return new RTSGameWindow();
//Here it is necessary to add a your specific game mode.
case GameMap.GameTypes.BreakOut:
return new BreakOutGameWindow();
}
return null;
}
The new code, shown in bold, tells to return a new BreakOutGameWindow object when the game type of the map is set to BreakOut.
Now compile your code, and if everything went ok, just close the solution.
The next and final step is to configure our BreakOut01 map. Open the Map Editor application, and then open the BreakOut01 map.
Tick the Map item on the Map Hierarchy tool, then locate the GameType property of the map, in the Properties tool. Change the value from Action to BreakOut, as shown in the picture:
Now click on the SpawnPoint and locate its DefaultPoint property in the Properties tool. Change the value from False to True. This will make this SpawnPoint the default one (which is necessary for the SpawnPoint.GetDefaultSpawnPoint() method to work). Here is a picture:
Now save the map and run it!
What you see now is your very own map, running with your very own code! There is not much more you can do for now, but actually checking that the Action and the FPS player are not there anymore. We will be providing the code to spawn our own BreakOut paddle into the room in the next tutorial!


