Tutorial 1 - Introducing The Render Engine
If you'd like, you can download the source for this tutorial here.Setup
Download Tomcat 5.5 and install it. This will be your web server and how you view your games in development. This will allow you to do local development and testing.
Next, download the full version of The Render Engine into a folder on your machine. The full version contains source code comments and isn't compressed so debugging is easier.
Next, look at the file ./setup/tomcat/renderengine.xml to set up a context on Tomcat within which to run your game. It should point to the folder where your copy of the engine was installed.
After the context is up and running on Tomcat, verify that you can run the demos by navigating to one of the demo folders on your machine. The URL will look something like the following, assuming you didn't change Tomcat's port:
If the Asteroids clone game starts up and runs, you've successfully configured a context for your testing. Now you are ready to create your first game. For your tests, you may want to add a folder in your Render Engine directory in the root folder (the one where the /demos folder is located. If your copy of the engine is located on your C:\ drive (on Windows) in the renderengine folder, you'll find that the source code for this tutorial is located in:
Creating the Index File
Your game will need an index.html file in your game folder. This will be the boot file for your game and will need to load the library files and the engine's runtime. We will use context-relative URI's to get to the libraries and engine runtime.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Tutorial One</title>
<!-- Load the supporting libraries -->
<script type="text/javascript" src="../../libs/base.js"></script>
<script type="text/javascript" src="../../libs/jquery.js"></script>
<script type="text/javascript" src="../../libs/jquery.ext.engine.js"></script>
<script type="text/javascript" src="../../libs/sylvester.js"></script>
<!-- Load the main engine script -->
<script type="text/javascript" src="../../engine/runtime/engine.js"></script>
</head>
<body>
<script type="text/javascript">
// Load the game's script
Engine.loadGame('game.js','Tutorial1', 'Tutorial 1');
</script>
</body>
</html>
The engine requires a strict interpretation of the document object model, thus the DOCTYPE descriptor indicates it by loading the strict DTD. The next section loads the required libraries. Let me explain those here:
- base.js - This is the class from which all classes extend. It extends the Javascript Object class and adds a method to make extension simpler. Additionally, it handles the distinction between the prototyping phase and the construction phase by overriding the default constructor of all objects.
- jquery.js - jQuery is a well-known Javascript library that simplifies interacting with the DOM. The Render Engine depends on this library being loaded, and without it, will not run.
- jquery.ext.engine.js - An plug-in to jQuery written for The Render Engine which adds additional information to the browser object and adds some selectors which are handy.
- sylvester.js - An excellent math library for the manipulation of vectors, planes, matrices, and lines. The Render Engine extends upon these objects and exposes them.
Next, the engine runtime is loaded. The engine.js file is a combination of the six engine libraries which handle: engine processes, linking, the console abstraction, script loading, and initialization. An Ant task is defined for creating the engine.js file. Note: The engine.js file should not be modified. If you have need to, modify the engine.[PART].js file located in ./engine/build/ to your liking and re-run the Ant task which builds the runtime file.
A progress bar will be rendered while the game's scripts are loaded. When the necessary engine objects have been loaded and initialized, your game class (Tutorial1) will enter setup(). This is because we told the engine which file to load to run our game, and what the game's object class name is.
Engine.loadGame('game.js','Tutorial1', 'Tutorial 1');
Creating the Game Class
Every game has to extend the Game class. This provides some essential methods that The Render Engine will be looking for. You'll want it to include some engine files which will establish our rendering context and other needed objects. The structure is important... First you will include engine and game files, then you will tell the engine about this new object class so that it can resolve dependencies via the Linker before initializing it.
// Load all required engine components
Engine.include("/rendercontexts/context.canvascontext.js");
Engine.initObject("Tutorial1", "Game", function(){
/**
* @class Tutorial One. Render a simple filled rectangle to
* the Canvas context.
*/
var Tutorial1 = Game.extend({
constructor: null,
// The rendering context
renderContext: null,
// Engine frames per second
engineFPS: 15,
// The play field
fieldBox: null,
fieldWidth: 200,
fieldHeight: 200,
/**
* Called to set up the game, download any resources, and initialize
* the game to its running state.
*/
setup: function(){
// Set the FPS of the game
Engine.setFPS(this.engineFPS);
// Create the render context
this.fieldBox = Rectangle2D.create(0, 0, this.fieldWidth, this.fieldHeight);
this.renderContext = CanvasContext.create("Playfield",
this.fieldWidth, this.fieldHeight);
this.renderContext.setBackgroundColor("black");
// Add the new rendering context to the default engine context
Engine.getDefaultContext().add(this.renderContext);
},
/**
* Called when a game is being shut down to allow it to clean up
* any objects, remove event handlers, destroy the rendering context, etc.
*/
teardown: function(){
this.renderContext.destroy();
},
/**
* Return a reference to the render context
*/
getRenderContext: function(){
return this.renderContext;
},
/**
* Return a reference to the playfield box
*/
getFieldBox: function() {
return this.fieldBox;
}
});
return Tutorial1;
});
Save the file in your new game folder as game.js.
Breaking it Down
First we load the rendering context (CanvasContext). Next we tell the engine that to initialize the game object, the object (Tutorial1) will primarily depend on the Game object existing. The Linker will assure that the object's dependencies are resolved before it is initialized.
Next we create the actual object and assign it to the variable Tutorial1, indicating that it extends the Game object. Games have a null constructor because they are what is known as a single instance object. A single instance is kind of like a static class, but it is a self-referencing instance of an object. You don't have to create and instance with the new operator — it will be created for you and assigned to the variable.
The instance fields are defined to hold references to the render context, its dimensions, and the frames per seconds (fps) that we want the game to run at. The next two methods are important for the game to run and must exist. Besides these two methods, the remainder of them provide access to the game's rendering context and its dimensions.
The setup() Method
Every game must implement this method. The engine will call this method to start the game running. You can use this method any way you want to, but in this case we're using it to establish the rendering context and tell the engine what FPS to run at. Finally, we ask the Engine object for the default rendering context and add our own to it.
The teardown() Method
When the engine is shutdown, it will call the teardown method of your game, giving you a chance to destroy game objects and clean up anything else. Destroying your rendering context, as is done in the above example, will automatically destroy any objects that have been added to it.
That's It!
You're done with the first tutorial. It isn't much of a game, but examine the code and try to understand what it's doing. This is the foundation for all games running on The Render Engine. Following the structure above, and using the good coding practices outlined, your games will be easier for the engine to run. I know it doesn't look like much, but this is it:
When you're ready, move onto the next tutorial to see about adding your first object to a game. This will be the foundation for understanding the component system upon which the engine is built.