<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://c4engine.com/wiki/index.php?action=history&amp;feed=atom&amp;title=SimpleBall_Source_Code</id>
	<title>SimpleBall Source Code - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://c4engine.com/wiki/index.php?action=history&amp;feed=atom&amp;title=SimpleBall_Source_Code"/>
	<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=SimpleBall_Source_Code&amp;action=history"/>
	<updated>2026-04-13T09:15:47Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=SimpleBall_Source_Code&amp;diff=534&amp;oldid=prev</id>
		<title>Eric Lengyel: Created page with &quot;This page contains the complete source code for the &lt;code&gt;SimpleBall&lt;/code&gt; example game module. See the Simple Games page for more information about the basic examples.  == SimpleBall.h ==  &lt;syntaxhighlight lang=&quot;c++&quot;&gt; #ifndef SimpleBall_h #define SimpleBall_h   #include &quot;C4Application.h&quot; #include &quot;C4World.h&quot; #include &quot;C4Input.h&quot; #include &quot;C4Cameras.h&quot; #include &quot;C4Interface.h&quot; #include &quot;C4Particles.h&quot;   // Every application/game module needs to declare a function ca...&quot;</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=SimpleBall_Source_Code&amp;diff=534&amp;oldid=prev"/>
		<updated>2023-09-12T21:41:35Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;This page contains the complete source code for the &amp;lt;code&amp;gt;SimpleBall&amp;lt;/code&amp;gt; example game module. See the &lt;a href=&quot;/wiki/index.php?title=Simple_Games&quot; title=&quot;Simple Games&quot;&gt;Simple Games&lt;/a&gt; page for more information about the basic examples.  == SimpleBall.h ==  &amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt; #ifndef SimpleBall_h #define SimpleBall_h   #include &amp;quot;C4Application.h&amp;quot; #include &amp;quot;C4World.h&amp;quot; #include &amp;quot;C4Input.h&amp;quot; #include &amp;quot;C4Cameras.h&amp;quot; #include &amp;quot;C4Interface.h&amp;quot; #include &amp;quot;C4Particles.h&amp;quot;   // Every application/game module needs to declare a function ca...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This page contains the complete source code for the &amp;lt;code&amp;gt;SimpleBall&amp;lt;/code&amp;gt; example game module. See the [[Simple Games]] page for more information about the basic examples.&lt;br /&gt;
&lt;br /&gt;
== SimpleBall.h ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef SimpleBall_h&lt;br /&gt;
#define SimpleBall_h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;C4Application.h&amp;quot;&lt;br /&gt;
#include &amp;quot;C4World.h&amp;quot;&lt;br /&gt;
#include &amp;quot;C4Input.h&amp;quot;&lt;br /&gt;
#include &amp;quot;C4Cameras.h&amp;quot;&lt;br /&gt;
#include &amp;quot;C4Interface.h&amp;quot;&lt;br /&gt;
#include &amp;quot;C4Particles.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Every application/game module needs to declare a function called CreateApplication()&lt;br /&gt;
// exactly as follows. (It must be declared extern &amp;quot;C&amp;quot;, and it must include the tag&lt;br /&gt;
// C4_MODULE_EXPORT.) The engine looks for this function in the DLL and calls&lt;br /&gt;
// it to create an instance of the subclass of the Application class that the&lt;br /&gt;
// application/game module defines.&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	C4_MODULE_EXPORT C4::Application *CreateApplication(void);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
namespace SimpleBall&lt;br /&gt;
{&lt;br /&gt;
	using namespace C4;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// These are action types used to define action bindings in the&lt;br /&gt;
	// Input Manager. If the four-character code for an action is&lt;br /&gt;
	// 'abcd', then any input control (there can be more than one)&lt;br /&gt;
	// bound to %abcd triggers the associated action.&lt;br /&gt;
&lt;br /&gt;
	enum : ActionType&lt;br /&gt;
	{&lt;br /&gt;
		kActionForward			= 'frwd',&lt;br /&gt;
		kActionBackward			= 'bkwd',&lt;br /&gt;
		kActionLeft				= 'left',&lt;br /&gt;
		kActionRight			= 'rght',&lt;br /&gt;
		kActionUp				= 'jump',&lt;br /&gt;
		kActionDown				= 'down'&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// Model types are associated with a model resource using the ModelRegistration&lt;br /&gt;
	// class. Models are registered with the engine in the Game constructor.&lt;br /&gt;
&lt;br /&gt;
	enum : ModelType&lt;br /&gt;
	{&lt;br /&gt;
		kModelBall				= 'ball'&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// New controller types are registered with the engine in the Game constructor.&lt;br /&gt;
&lt;br /&gt;
	enum : ControllerType&lt;br /&gt;
	{&lt;br /&gt;
		kControllerBall			= 'ball'&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// This is the type of our custom particle system.&lt;br /&gt;
&lt;br /&gt;
	enum : ParticleSystemType&lt;br /&gt;
	{&lt;br /&gt;
		kParticleSystemSpark	= 'sprk'&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// New locator types are registered with the engine in the Game constructor.&lt;br /&gt;
	// The 'spec' locator is used to specify where the spectator camera should&lt;br /&gt;
	// be positioned when a world is loaded.&lt;br /&gt;
&lt;br /&gt;
	enum : LocatorType&lt;br /&gt;
	{&lt;br /&gt;
		kLocatorSpectator		= 'spec'&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// An Action object represents an input action that can be triggered by some&lt;br /&gt;
	// input control, such as a key on the keyboard or a button on a gamepad.&lt;br /&gt;
	// The HandleEngage() and HandleDisengage() methods are called when the button&lt;br /&gt;
	// is pressed and released, respectively. Actions are registered with the Input&lt;br /&gt;
	// Manager when the Game class is constructed.&lt;br /&gt;
&lt;br /&gt;
	class MovementAction : public Action&lt;br /&gt;
	{&lt;br /&gt;
		private:&lt;br /&gt;
&lt;br /&gt;
			uint32			movementFlag;&lt;br /&gt;
&lt;br /&gt;
		public:&lt;br /&gt;
&lt;br /&gt;
			MovementAction(ActionType type, uint32 flag);&lt;br /&gt;
			~MovementAction();&lt;br /&gt;
&lt;br /&gt;
			void HandleEngage(void) override;&lt;br /&gt;
			void HandleDisengage(void) override;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// Controllers are used to control anything that moves in the world.&lt;br /&gt;
	// New types of controllers defined by the application/game module are&lt;br /&gt;
	// registered with the engine when the Game class is constructed.&lt;br /&gt;
	//&lt;br /&gt;
	// The BallController inherits from the built-in rigid body controller,&lt;br /&gt;
	// which handles the ball's motion and collision detection. We are only&lt;br /&gt;
	// adding a little bit of functionality that causes a particle system&lt;br /&gt;
	// to be created when a ball hits another ball.&lt;br /&gt;
&lt;br /&gt;
	class BallController final : public RigidBodyController&lt;br /&gt;
	{&lt;br /&gt;
		private:&lt;br /&gt;
&lt;br /&gt;
			BallController(const BallController&amp;amp; ballController);&lt;br /&gt;
&lt;br /&gt;
			Controller *Replicate(void) const override;&lt;br /&gt;
&lt;br /&gt;
		public:&lt;br /&gt;
&lt;br /&gt;
			BallController();&lt;br /&gt;
			~BallController();&lt;br /&gt;
&lt;br /&gt;
			static bool ValidNode(const Node *node);&lt;br /&gt;
&lt;br /&gt;
			void PreprocessController(void) override;&lt;br /&gt;
&lt;br /&gt;
			RigidBodyStatus HandleNewRigidBodyContact(const RigidBodyContact *contact, RigidBodyController *contactBody) override;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// The SparkParticleSystem class implements a simple particle system that&lt;br /&gt;
	// creates a small burst of sparks.&lt;br /&gt;
&lt;br /&gt;
	class SparkParticleSystem : public LineParticleSystem&lt;br /&gt;
	{&lt;br /&gt;
		// This friend declaration allows the particle system registration object&lt;br /&gt;
		// to construct a SparkParticleSystem object using the private default constructor.&lt;br /&gt;
&lt;br /&gt;
		friend class ParticleSystemReg&amp;lt;SparkParticleSystem&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		private:&lt;br /&gt;
&lt;br /&gt;
			enum {kMaxParticleCount = 100};&lt;br /&gt;
&lt;br /&gt;
			int32				sparkCount;&lt;br /&gt;
&lt;br /&gt;
			// This is where information about each particle is stored.&lt;br /&gt;
&lt;br /&gt;
			ParticlePool&amp;lt;&amp;gt;		particlePool;&lt;br /&gt;
			Particle			particleArray[kMaxParticleCount];&lt;br /&gt;
&lt;br /&gt;
			SparkParticleSystem();&lt;br /&gt;
&lt;br /&gt;
			bool CalculateBoundingSphere(BoundingSphere *sphere) const override;&lt;br /&gt;
&lt;br /&gt;
		public:&lt;br /&gt;
&lt;br /&gt;
			SparkParticleSystem(int32 count);&lt;br /&gt;
			~SparkParticleSystem();&lt;br /&gt;
&lt;br /&gt;
			void PreprocessNode(void) override;&lt;br /&gt;
			void AnimateParticles(void) override;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// The StartWindow class is a simple example of a window that handles button clicks.&lt;br /&gt;
	// We add the Global base class so that a pointer to the window can be tracked easily.&lt;br /&gt;
&lt;br /&gt;
	class StartWindow : public C4::Window, public Global&amp;lt;StartWindow&amp;gt;&lt;br /&gt;
	{&lt;br /&gt;
		private:&lt;br /&gt;
&lt;br /&gt;
			WidgetObserver&amp;lt;StartWindow&amp;gt;		startButtonObserver;&lt;br /&gt;
			WidgetObserver&amp;lt;StartWindow&amp;gt;		quitButtonObserver;&lt;br /&gt;
&lt;br /&gt;
			void HandleStartButtonEvent(Widget *widget, const WidgetEventData *eventData);&lt;br /&gt;
			void HandleQuitButtonEvent(Widget *widget, const WidgetEventData *eventData);&lt;br /&gt;
&lt;br /&gt;
		public:&lt;br /&gt;
&lt;br /&gt;
			StartWindow();&lt;br /&gt;
			~StartWindow();&lt;br /&gt;
&lt;br /&gt;
			void PreprocessWidget(void) override;&lt;br /&gt;
&lt;br /&gt;
			bool HandleKeyboardEvent(const KeyboardEventData *eventData) override;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// The application/game module will usually define a subclass of the World&lt;br /&gt;
	// class so that extra information can be associated with the current world.&lt;br /&gt;
	// In this case, an instance of the SpectatorCamera class is included&lt;br /&gt;
	// with the world. A new instance of this World subclass should be returned&lt;br /&gt;
	// when the Game::CreateWorld() function is called (see below).&lt;br /&gt;
&lt;br /&gt;
	class GameWorld : public World&lt;br /&gt;
	{&lt;br /&gt;
		private:&lt;br /&gt;
&lt;br /&gt;
			SpectatorCamera		spectatorCamera;&lt;br /&gt;
&lt;br /&gt;
			static const LocatorMarker *FindSpectatorLocator(const Zone *zone);&lt;br /&gt;
&lt;br /&gt;
		public:&lt;br /&gt;
&lt;br /&gt;
			GameWorld(const char *name);&lt;br /&gt;
			~GameWorld();&lt;br /&gt;
&lt;br /&gt;
			SpectatorCamera *GetSpectatorCamera(void)&lt;br /&gt;
			{&lt;br /&gt;
				return (&amp;amp;spectatorCamera);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			WorldResult PreprocessWorld(void) override;&lt;br /&gt;
			void RenderWorld(void) override;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// Every application/game module needs to define a subclass of the Application&lt;br /&gt;
	// class to serve as the primary interface with the engine. This subclass is&lt;br /&gt;
	// created and returned to the engine in the CreateApplication() function.&lt;br /&gt;
	// There should be only one instance of this class, and a pointer to it is&lt;br /&gt;
	// declared below.&lt;br /&gt;
&lt;br /&gt;
	class Game : public Application, public Global&amp;lt;Game&amp;gt;&lt;br /&gt;
	{&lt;br /&gt;
		private:&lt;br /&gt;
&lt;br /&gt;
			ModelRegistration						ballModelReg;&lt;br /&gt;
			ControllerReg&amp;lt;BallController&amp;gt;			controllerReg;&lt;br /&gt;
			ParticleSystemReg&amp;lt;SparkParticleSystem&amp;gt;	sparkParticleSystemReg;&lt;br /&gt;
			LocatorRegistration						locatorReg;&lt;br /&gt;
&lt;br /&gt;
			InputMgr::KeyCallback					*prevEscapeCallback;&lt;br /&gt;
			void									*prevEscapeCookie;&lt;br /&gt;
&lt;br /&gt;
			MovementAction							*forwardAction;&lt;br /&gt;
			MovementAction							*backwardAction;&lt;br /&gt;
			MovementAction							*leftAction;&lt;br /&gt;
			MovementAction							*rightAction;&lt;br /&gt;
			MovementAction							*upAction;&lt;br /&gt;
			MovementAction							*downAction;&lt;br /&gt;
&lt;br /&gt;
			static World *CreateWorld(const char *name, void *cookie);&lt;br /&gt;
&lt;br /&gt;
			static void EscapeCallback(void *cookie);&lt;br /&gt;
&lt;br /&gt;
		public:&lt;br /&gt;
&lt;br /&gt;
			Game();&lt;br /&gt;
			~Game();&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// This is a pointer to the one instance of the Game class through which&lt;br /&gt;
	// any other part of the application/game module can access it.&lt;br /&gt;
&lt;br /&gt;
	extern Game *TheGame;&lt;br /&gt;
&lt;br /&gt;
	// This is a pointer to the start window. We only keep this around so that&lt;br /&gt;
	// we can delete the window before exiting if it's still on the screen.&lt;br /&gt;
&lt;br /&gt;
	extern StartWindow *TheStartWindow;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimpleBall.cpp ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;SimpleBall.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
using namespace SimpleBall;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This is the definition of the pointer to the Game class global.&lt;br /&gt;
// It should be initialized to nullptr, and its value will be set by&lt;br /&gt;
// the Game class constructor.&lt;br /&gt;
&lt;br /&gt;
Game *SimpleBall::TheGame = nullptr;&lt;br /&gt;
&lt;br /&gt;
// This is the definition of the pointer to the StartWindow class global.&lt;br /&gt;
// It should be initialized to nullptr, and its value will be set by&lt;br /&gt;
// the StartWindow class constructor.&lt;br /&gt;
&lt;br /&gt;
StartWindow *SimpleBall::TheStartWindow = nullptr;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C4::Application *CreateApplication(void)&lt;br /&gt;
{&lt;br /&gt;
	// This function should simply return a pointer to a new instance of&lt;br /&gt;
	// the Application class. Normally, the application/game module will&lt;br /&gt;
	// define a subclass of the Application class (in this case, the&lt;br /&gt;
	// Game class) and return a pointer to a new instance of that type.&lt;br /&gt;
&lt;br /&gt;
	// This function is called exactly one time right after the&lt;br /&gt;
	// application/game module DLL is loaded by the engine. The returned&lt;br /&gt;
	// class is destroyed via the virtual destructor of the Application&lt;br /&gt;
	// class right before the application/game module DLL is unloaded.&lt;br /&gt;
&lt;br /&gt;
	return (new Game);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
MovementAction::MovementAction(ActionType type, uint32 flag) : Action(type)&lt;br /&gt;
{&lt;br /&gt;
	// Each instance of the MovementAction class represents a movement&lt;br /&gt;
	// in a single direction, as indicated by the flag parameter.&lt;br /&gt;
	// All of the MovementAction instances are constructed in the&lt;br /&gt;
	// Game class constructor.&lt;br /&gt;
&lt;br /&gt;
	movementFlag = flag;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
MovementAction::~MovementAction()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void MovementAction::HandleEngage(void)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called when the input control associated with this&lt;br /&gt;
	// particular action is engaged (e.g., a key was pressed).&lt;br /&gt;
&lt;br /&gt;
	World *world = TheWorldMgr-&amp;gt;GetWorld();&lt;br /&gt;
	if (world)&lt;br /&gt;
	{&lt;br /&gt;
		// If there's currently a world loaded, apply the movement to&lt;br /&gt;
		// the spectator camera.&lt;br /&gt;
&lt;br /&gt;
		SpectatorCamera *camera = static_cast&amp;lt;GameWorld *&amp;gt;(world)-&amp;gt;GetSpectatorCamera();&lt;br /&gt;
		camera-&amp;gt;SetSpectatorFlags(camera-&amp;gt;GetSpectatorFlags() | movementFlag);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void MovementAction::HandleDisengage(void)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called when the input control associated with this&lt;br /&gt;
	// particular action is disengaged (e.g., a key was released).&lt;br /&gt;
&lt;br /&gt;
	World *world = TheWorldMgr-&amp;gt;GetWorld();&lt;br /&gt;
	if (world)&lt;br /&gt;
	{&lt;br /&gt;
		// If there's currently a world loaded, remove the movement from&lt;br /&gt;
		// the spectator camera.&lt;br /&gt;
&lt;br /&gt;
		SpectatorCamera *camera = static_cast&amp;lt;GameWorld *&amp;gt;(world)-&amp;gt;GetSpectatorCamera();&lt;br /&gt;
		camera-&amp;gt;SetSpectatorFlags(camera-&amp;gt;GetSpectatorFlags() &amp;amp; ~movementFlag);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
BallController::BallController() : RigidBodyController(kControllerBall)&lt;br /&gt;
{&lt;br /&gt;
	// This constructor is called when a new ball model is created.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
BallController::BallController(const BallController&amp;amp; ballController) : RigidBodyController(ballController)&lt;br /&gt;
{&lt;br /&gt;
	// This constructor is called when a ball controller is cloned.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
BallController::~BallController()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Controller *BallController::Replicate(void) const&lt;br /&gt;
{&lt;br /&gt;
	return (new BallController(*this));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool BallController::ValidNode(const Node *node)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called by the engine to determine whether this&lt;br /&gt;
	// specific type of controller can be assigned to the particular&lt;br /&gt;
	// node passed in through the node parameter. This function should&lt;br /&gt;
	// return true if it can control the node, and otherwise it should&lt;br /&gt;
	// return false. In this case, the controller can only be applied&lt;br /&gt;
	// to model nodes.&lt;br /&gt;
&lt;br /&gt;
	return (node-&amp;gt;GetNodeType() == kNodeModel);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void BallController::PreprocessController(void)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called once before the target node is ever&lt;br /&gt;
	// rendered or moved. The base class PreprocessController() function&lt;br /&gt;
	// should always be called first, and then the subclass can do whatever&lt;br /&gt;
	// preprocessing it needs to do. In this case, we set a few of the&lt;br /&gt;
	// ball's physical parameters and give it a random initial velocity.&lt;br /&gt;
&lt;br /&gt;
	RigidBodyController::PreprocessController();&lt;br /&gt;
&lt;br /&gt;
	SetRestitutionCoefficient(0.99F);&lt;br /&gt;
	SetSpinFrictionMultiplier(0.1F);&lt;br /&gt;
	SetRollingResistance(0.01F);&lt;br /&gt;
&lt;br /&gt;
	SetLinearVelocity(Random::RandomUnitVector3D() * 2.0F);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RigidBodyStatus BallController::HandleNewRigidBodyContact(const RigidBodyContact *contact, RigidBodyController *contactBody)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called when the ball makes contact with another rigid body.&lt;br /&gt;
	// If we hit another ball, then we add a sound effect and some sparks to the world.&lt;br /&gt;
&lt;br /&gt;
	if (contactBody-&amp;gt;GetControllerType() == kControllerBall)&lt;br /&gt;
	{&lt;br /&gt;
		Node *node = GetTargetNode();&lt;br /&gt;
		World *world = node-&amp;gt;GetWorld();&lt;br /&gt;
		Point3D position = node-&amp;gt;GetWorldTransform() * contact-&amp;gt;GetContactPosition();&lt;br /&gt;
&lt;br /&gt;
		OmniSource *source = new OmniSource(&amp;quot;model/Ball&amp;quot;, 40.0F);&lt;br /&gt;
		source-&amp;gt;SetNodePosition(position);&lt;br /&gt;
		world-&amp;gt;AddNewNode(source);&lt;br /&gt;
&lt;br /&gt;
		SparkParticleSystem *sparks = new SparkParticleSystem(20);&lt;br /&gt;
		sparks-&amp;gt;SetNodePosition(position);&lt;br /&gt;
		world-&amp;gt;AddNewNode(sparks);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return (kRigidBodyUnchanged);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
SparkParticleSystem::SparkParticleSystem(int32 count) :&lt;br /&gt;
&lt;br /&gt;
		// Initialize the base class for line particles&lt;br /&gt;
		// and tell it where the particle pool is.&lt;br /&gt;
		LineParticleSystem(kParticleSystemSpark, &amp;amp;particlePool, &amp;quot;particle/Spark1&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
		// Initialize the particle pool by telling it where the array&lt;br /&gt;
		// of Particle structs is and how big it is.&lt;br /&gt;
		particlePool(kMaxParticleCount, particleArray)&lt;br /&gt;
{&lt;br /&gt;
	// The SparkParticleSystem node creates a small burst of sparks&lt;br /&gt;
	// and then self-destructs when all of them have burned out.&lt;br /&gt;
&lt;br /&gt;
	sparkCount = count;&lt;br /&gt;
	SetLengthMultiplier(4.0F);&lt;br /&gt;
	SetParticleSystemFlags(kParticleSystemSelfDestruct);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SparkParticleSystem::SparkParticleSystem() :&lt;br /&gt;
		LineParticleSystem(kParticleSystemSpark, &amp;amp;particlePool, &amp;quot;particle/Spark1&amp;quot;),&lt;br /&gt;
		particlePool(kMaxParticleCount, particleArray)&lt;br /&gt;
{&lt;br /&gt;
	// This constructor gets used when the particle system is being loaded from&lt;br /&gt;
	// a saved game. In this case, we don't need to initialize anything.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SparkParticleSystem::~SparkParticleSystem()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool SparkParticleSystem::CalculateBoundingSphere(BoundingSphere *sphere) const&lt;br /&gt;
{&lt;br /&gt;
	// Just return a sphere that's big enough to always enclose&lt;br /&gt;
	// all of the particles. This is in object-space coordinates.&lt;br /&gt;
&lt;br /&gt;
	sphere-&amp;gt;SetCenter(0.0F, 0.0F, 0.0F);&lt;br /&gt;
	sphere-&amp;gt;SetRadius(20.0F);&lt;br /&gt;
	return (true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SparkParticleSystem::PreprocessNode(void)&lt;br /&gt;
{&lt;br /&gt;
	// This function creates the spark particles.&lt;br /&gt;
&lt;br /&gt;
	// Always call the base class PreprocessNode() function.&lt;br /&gt;
	LineParticleSystem::PreprocessNode();&lt;br /&gt;
&lt;br /&gt;
	// If there's already a particle in the system, then the node was loaded from&lt;br /&gt;
	// a saved game. We only create new particles if the particle system is empty.&lt;br /&gt;
&lt;br /&gt;
	if (!GetFirstParticle())&lt;br /&gt;
	{&lt;br /&gt;
		// Calculate the world-space center.&lt;br /&gt;
		Point3D center = GetSuperNode()-&amp;gt;GetWorldTransform() * GetNodePosition();&lt;br /&gt;
&lt;br /&gt;
		const Vector2D *trig = Math::GetTrigTable();&lt;br /&gt;
&lt;br /&gt;
		int32 count = sparkCount;&lt;br /&gt;
		for (machine a = 0; a &amp;lt; count; a++)&lt;br /&gt;
		{&lt;br /&gt;
			// Grab a new unused particle from the pool.&lt;br /&gt;
			Particle *particle = particlePool.NewParticle();&lt;br /&gt;
			if (!particle)&lt;br /&gt;
			{&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			particle-&amp;gt;emitTime = 0;										// Particle appears right away.&lt;br /&gt;
			particle-&amp;gt;lifeTime = 500 + Random::RandomInteger(750);		// Particle lives 500-1250 milliseconds.&lt;br /&gt;
			particle-&amp;gt;radius = 0.02F;									// The radius is 20 mm.&lt;br /&gt;
			particle-&amp;gt;color.Set(1.0F, 1.0F, 0.1F, 1.0F);				// It's yellow.&lt;br /&gt;
			particle-&amp;gt;orientation = 0;									// This doesn't matter for line particles.&lt;br /&gt;
			particle-&amp;gt;position = center;								// It starts at the effect's center.&lt;br /&gt;
&lt;br /&gt;
			// Calculate a random velocity in a random direction.&lt;br /&gt;
			float speed = Random::RandomFloat(0.004F);&lt;br /&gt;
			const Vector2D&amp;amp; csp = trig[Random::RandomInteger(128)];&lt;br /&gt;
			const Vector2D&amp;amp; cst = trig[Random::RandomInteger(256)];&lt;br /&gt;
			particle-&amp;gt;velocity.Set(cst.x * csp.y * speed, cst.y * csp.y * speed, csp.x * speed);&lt;br /&gt;
&lt;br /&gt;
			// Add the particle to the particle system.&lt;br /&gt;
			AddParticle(particle);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SparkParticleSystem::AnimateParticles(void)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called once per frame to move the particles.&lt;br /&gt;
&lt;br /&gt;
	// Times are in milliseconds.&lt;br /&gt;
	int32 dt = TheTimeMgr-&amp;gt;GetDeltaTime();&lt;br /&gt;
	float fdt = TheTimeMgr-&amp;gt;GetFloatDeltaTime();&lt;br /&gt;
&lt;br /&gt;
	Particle *particle = GetFirstParticle();&lt;br /&gt;
	while (particle)&lt;br /&gt;
	{&lt;br /&gt;
		// Get the next particle here in case the current one is removed from the system.&lt;br /&gt;
		Particle *next = particle-&amp;gt;nextParticle;&lt;br /&gt;
&lt;br /&gt;
		int32 life = (particle-&amp;gt;lifeTime -= dt);&lt;br /&gt;
		if (life &amp;gt; 0)&lt;br /&gt;
		{&lt;br /&gt;
			// Update velocity with gravity.&lt;br /&gt;
			particle-&amp;gt;velocity.z += Const::gravity * fdt;&lt;br /&gt;
&lt;br /&gt;
			// Move the particle and see if it hit the floor plane at z = 0.&lt;br /&gt;
			float z1 = particle-&amp;gt;position.z - particle-&amp;gt;radius;&lt;br /&gt;
			particle-&amp;gt;position += particle-&amp;gt;velocity * fdt;&lt;br /&gt;
			float z2 = particle-&amp;gt;position.z - particle-&amp;gt;radius;&lt;br /&gt;
			if (z1 * z2 &amp;lt;= 0.0F)&lt;br /&gt;
			{&lt;br /&gt;
				// The particle hit the floor, so reflect its velocity and remove some energy.&lt;br /&gt;
				particle-&amp;gt;position.z = 0.05F - z2;&lt;br /&gt;
				particle-&amp;gt;velocity.z *= -0.5F;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// If the particle is nearing the end of its life, fade it out.&lt;br /&gt;
			if (life &amp;lt; 100)&lt;br /&gt;
			{&lt;br /&gt;
				particle-&amp;gt;color.alpha = (float) life * 0.01F;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else&lt;br /&gt;
		{&lt;br /&gt;
			// Particle burned out.&lt;br /&gt;
			FreeParticle(particle);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		particle = next;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// The StartWindow constructor initializes the Window base class with the name of the panel&lt;br /&gt;
// resource to load. The observer members are initialized with the functions that are&lt;br /&gt;
// called when the &amp;quot;Start&amp;quot; and &amp;quot;Quit&amp;quot; push buttons in the window post activate events.&lt;br /&gt;
&lt;br /&gt;
StartWindow::StartWindow() :&lt;br /&gt;
		Window(&amp;quot;panel/SimpleBall&amp;quot;),&lt;br /&gt;
		Global&amp;lt;StartWindow&amp;gt;(TheStartWindow),&lt;br /&gt;
		startButtonObserver(this, &amp;amp;StartWindow::HandleStartButtonEvent),&lt;br /&gt;
		quitButtonObserver(this, &amp;amp;StartWindow::HandleQuitButtonEvent)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StartWindow::~StartWindow()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void StartWindow::PreprocessWidget(void)&lt;br /&gt;
{&lt;br /&gt;
	// We must call the Window base class PreprocessWidget() function first to initialize&lt;br /&gt;
	// the internal structures that are used to search for widgets.&lt;br /&gt;
&lt;br /&gt;
	Window::PreprocessWidget();&lt;br /&gt;
&lt;br /&gt;
	// Assign observers to the push button widgets named &amp;quot;Start&amp;quot; and &amp;quot;Quit&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
	Widget *button = FindWidget(&amp;quot;Start&amp;quot;);&lt;br /&gt;
	button-&amp;gt;SetObserver(&amp;amp;startButtonObserver);&lt;br /&gt;
&lt;br /&gt;
	button = FindWidget(&amp;quot;Quit&amp;quot;);&lt;br /&gt;
	button-&amp;gt;SetObserver(&amp;amp;quitButtonObserver);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool StartWindow::HandleKeyboardEvent(const KeyboardEventData *eventData)&lt;br /&gt;
{&lt;br /&gt;
	if (eventData-&amp;gt;eventType == kEventKeyDown)&lt;br /&gt;
	{&lt;br /&gt;
		if (eventData-&amp;gt;keyCode == kKeyCodeEscape)&lt;br /&gt;
		{&lt;br /&gt;
			// The Escape key was pressed while this window had the focus.&lt;br /&gt;
			// If a world is loaded, then just delete the window and return to gameplay.&lt;br /&gt;
&lt;br /&gt;
			if (TheWorldMgr-&amp;gt;GetWorld())&lt;br /&gt;
			{&lt;br /&gt;
				delete this;&lt;br /&gt;
				return (true);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return (false);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void StartWindow::HandleStartButtonEvent(Widget *widget, const WidgetEventData *eventData)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called whenever the &amp;quot;Start&amp;quot; push button posts an event.&lt;br /&gt;
&lt;br /&gt;
	if (eventData-&amp;gt;eventType == kEventWidgetActivate)&lt;br /&gt;
	{&lt;br /&gt;
		// If the widget was activated, then the user clicked the push button.&lt;br /&gt;
		// Delete the window and load a world to play.&lt;br /&gt;
&lt;br /&gt;
		delete this;&lt;br /&gt;
&lt;br /&gt;
		TheWorldMgr-&amp;gt;LoadWorld(&amp;quot;world/SimpleBall&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void StartWindow::HandleQuitButtonEvent(Widget *widget, const WidgetEventData *eventData)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called whenever the &amp;quot;Quit&amp;quot; push button posts an event.&lt;br /&gt;
&lt;br /&gt;
	if (eventData-&amp;gt;eventType == kEventWidgetActivate)&lt;br /&gt;
	{&lt;br /&gt;
		// If the widget was activated, then the user clicked the push button.&lt;br /&gt;
		// Quit the engine.&lt;br /&gt;
&lt;br /&gt;
		TheEngine-&amp;gt;Quit();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
GameWorld::GameWorld(const char *name) :&lt;br /&gt;
		World(name),&lt;br /&gt;
		spectatorCamera(2.67F, 1.0F, 0.3F)&lt;br /&gt;
{&lt;br /&gt;
	// This constructor is called when the Game::CreateWorld() function is&lt;br /&gt;
	// called to create a new world class. The world hasn't actually been loaded&lt;br /&gt;
	// from disk yet when we get here.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GameWorld::~GameWorld()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const LocatorMarker *GameWorld::FindSpectatorLocator(const Zone *zone)&lt;br /&gt;
{&lt;br /&gt;
	// Iterate through all of the markers in the zone.&lt;br /&gt;
&lt;br /&gt;
	const Marker *marker = zone-&amp;gt;GetFirstMarker();&lt;br /&gt;
	while (marker)&lt;br /&gt;
	{&lt;br /&gt;
		if (marker-&amp;gt;NodeEnabled())&lt;br /&gt;
		{&lt;br /&gt;
			MarkerType type = marker-&amp;gt;GetMarkerType();&lt;br /&gt;
			if (type == kMarkerLocator)&lt;br /&gt;
			{&lt;br /&gt;
				const LocatorMarker *locator = static_cast&amp;lt;const LocatorMarker *&amp;gt;(marker);&lt;br /&gt;
				if (locator-&amp;gt;GetLocatorType() == kLocatorSpectator)&lt;br /&gt;
				{&lt;br /&gt;
					return (locator);&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Get the next marker in the list.&lt;br /&gt;
&lt;br /&gt;
		marker = marker-&amp;gt;GetNextListElement();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Recursively look in all of the subzones.&lt;br /&gt;
&lt;br /&gt;
	const Zone *subzone = zone-&amp;gt;GetFirstSubzone();&lt;br /&gt;
	while (subzone)&lt;br /&gt;
	{&lt;br /&gt;
		const LocatorMarker *locator = FindSpectatorLocator(subzone);&lt;br /&gt;
		if (locator)&lt;br /&gt;
		{&lt;br /&gt;
			return (locator);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		subzone = subzone-&amp;gt;ListElement&amp;lt;Zone&amp;gt;::GetNextListElement();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return (nullptr);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
WorldResult GameWorld::PreprocessWorld(void)&lt;br /&gt;
{&lt;br /&gt;
	// The PreprocessWorld() function is called after the world has been constructed.&lt;br /&gt;
	// We must always call the base class PreprocessWorld() function first. If it&lt;br /&gt;
	// returns an error, then we just return the same result code.&lt;br /&gt;
&lt;br /&gt;
	WorldResult result = World::PreprocessWorld();&lt;br /&gt;
	if (result != kWorldOkay)&lt;br /&gt;
	{&lt;br /&gt;
		return (result);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// The world is now completely loaded. We search for a locator node that represents the&lt;br /&gt;
	// spectator camera's starting position. It has a locator type of kLocatorSpectator.&lt;br /&gt;
&lt;br /&gt;
	const LocatorMarker *marker = FindSpectatorLocator(GetRootNode());&lt;br /&gt;
	if (marker)&lt;br /&gt;
	{&lt;br /&gt;
		// A spectator marker was found.&lt;br /&gt;
		// Set the spectator camera's initial position and orientation.&lt;br /&gt;
&lt;br /&gt;
		const Vector3D direction = marker-&amp;gt;GetWorldTransform()[0];&lt;br /&gt;
		float azimuth = Arctan(direction.y, direction.x);&lt;br /&gt;
		float altitude = Arctan(direction.z, Sqrt(direction.x * direction.x + direction.y * direction.y));&lt;br /&gt;
&lt;br /&gt;
		spectatorCamera.SetCameraAzimuth(azimuth);&lt;br /&gt;
		spectatorCamera.SetCameraAltitude(altitude);&lt;br /&gt;
		spectatorCamera.SetNodePosition(marker-&amp;gt;GetWorldPosition());&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		// A spectator marker was not found.&lt;br /&gt;
		// Put the spectator camera one meter above the origin by default.&lt;br /&gt;
&lt;br /&gt;
		spectatorCamera.SetNodePosition(Point3D(0.0F, 0.0F, 1.0F));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Set the world's current camera to be our spectator camera.&lt;br /&gt;
	// The world will not render without a camera being set.&lt;br /&gt;
&lt;br /&gt;
	SetWorldCamera(&amp;amp;spectatorCamera);&lt;br /&gt;
	return (kWorldOkay);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GameWorld::RenderWorld(void)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called once per frame to render the world.&lt;br /&gt;
	// The subclass may do whatever it needs to before or after rendering,&lt;br /&gt;
	// but at some point must call World::RenderWorld().&lt;br /&gt;
&lt;br /&gt;
	World::RenderWorld();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Game::Game() :&lt;br /&gt;
&lt;br /&gt;
		// This is the constructor for the main application/game module class.&lt;br /&gt;
		// This class is created by the CreateApplication() function, which is&lt;br /&gt;
		// called right after the application/game DLL is loaded by the engine.&lt;br /&gt;
		// We initialize the global pointer to the current game instance first.&lt;br /&gt;
&lt;br /&gt;
		Global&amp;lt;Game&amp;gt;(TheGame),&lt;br /&gt;
&lt;br /&gt;
		// A model registration represents a model that can be instanced.&lt;br /&gt;
		// This particular declaration associates the kModelBall type with the&lt;br /&gt;
		// model named &amp;quot;model/Ball.mdl&amp;quot;. The fourth parameter tells the engine&lt;br /&gt;
		// to precache the model resource, and the last parameter specifies&lt;br /&gt;
		// the default controller type to assign to models of type kModelBall.&lt;br /&gt;
&lt;br /&gt;
		ballModelReg(kModelBall, &amp;quot;Bouncing Ball&amp;quot;, &amp;quot;model/Ball&amp;quot;, kModelPrecache, kControllerBall),&lt;br /&gt;
&lt;br /&gt;
		// A controller registration tells the engine about an application-defined type of&lt;br /&gt;
		// controller and registers its name. In this case, the name &amp;quot;Bouncing Ball&amp;quot; will&lt;br /&gt;
		// appear in the list of available controllers in the World Editor for any node that&lt;br /&gt;
		// is determined to be a valid target node by the BallController::ValidNode() function.&lt;br /&gt;
&lt;br /&gt;
		controllerReg(kControllerBall, &amp;quot;Bouncing Ball&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
		// A particle system registration tells the engine about an application-defined&lt;br /&gt;
		// type of particle system and registers its name.&lt;br /&gt;
&lt;br /&gt;
		sparkParticleSystemReg(kParticleSystemSpark, &amp;quot;Sparks&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
		// Locator markers are registered so that the World Editor&lt;br /&gt;
		// can display their names in the Markers page.&lt;br /&gt;
&lt;br /&gt;
		locatorReg(kLocatorSpectator, &amp;quot;Spectator Camera&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
	// This sets the function that is called when the user hits the&lt;br /&gt;
	// escape key during gameplay. We save the old function so that&lt;br /&gt;
	// it can be restored when the game DLL is unloaded.&lt;br /&gt;
&lt;br /&gt;
	prevEscapeCallback = TheInputMgr-&amp;gt;GetEscapeCallback();&lt;br /&gt;
	prevEscapeCookie = TheInputMgr-&amp;gt;GetEscapeCookie();&lt;br /&gt;
	TheInputMgr-&amp;gt;SetEscapeCallback(&amp;amp;EscapeCallback, this);&lt;br /&gt;
&lt;br /&gt;
	// This registers our world class constructor with the World Manager.&lt;br /&gt;
	// We only need to do this if we have defined a subclass of the World&lt;br /&gt;
	// class that holds extra information.&lt;br /&gt;
&lt;br /&gt;
	TheWorldMgr-&amp;gt;SetWorldCreator(&amp;amp;CreateWorld);&lt;br /&gt;
&lt;br /&gt;
	// These create the movement actions that are used to fly the spectator camera around.&lt;br /&gt;
&lt;br /&gt;
	forwardAction = new MovementAction(kActionForward, kSpectatorMoveForward);&lt;br /&gt;
	backwardAction = new MovementAction(kActionBackward, kSpectatorMoveBackward);&lt;br /&gt;
	leftAction = new MovementAction(kActionLeft, kSpectatorMoveLeft);&lt;br /&gt;
	rightAction = new MovementAction(kActionRight, kSpectatorMoveRight);&lt;br /&gt;
	upAction = new MovementAction(kActionUp, kSpectatorMoveUp);&lt;br /&gt;
	downAction = new MovementAction(kActionDown, kSpectatorMoveDown);&lt;br /&gt;
&lt;br /&gt;
	// These register our new actions with the Input Manager.&lt;br /&gt;
&lt;br /&gt;
	TheInputMgr-&amp;gt;AddAction(forwardAction);&lt;br /&gt;
	TheInputMgr-&amp;gt;AddAction(backwardAction);&lt;br /&gt;
	TheInputMgr-&amp;gt;AddAction(leftAction);&lt;br /&gt;
	TheInputMgr-&amp;gt;AddAction(rightAction);&lt;br /&gt;
	TheInputMgr-&amp;gt;AddAction(upAction);&lt;br /&gt;
	TheInputMgr-&amp;gt;AddAction(downAction);&lt;br /&gt;
&lt;br /&gt;
	// Let the Interface Manager determine when to change input devices to gameplay mode.&lt;br /&gt;
&lt;br /&gt;
	TheInterfaceMgr-&amp;gt;SetInputManagementMode(kInputManagementAutomatic);&lt;br /&gt;
&lt;br /&gt;
	// Put the Message Manager in single-player mode.&lt;br /&gt;
&lt;br /&gt;
	TheMessageMgr-&amp;gt;BeginSinglePlayerGame();&lt;br /&gt;
&lt;br /&gt;
	// Create the start window and tell the Interface Manager to display it.&lt;br /&gt;
&lt;br /&gt;
	TheInterfaceMgr-&amp;gt;AddWidget(new StartWindow);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Game::~Game()&lt;br /&gt;
{&lt;br /&gt;
	// When the game DLL is about to be unloaded, this destructor is called.&lt;br /&gt;
&lt;br /&gt;
	TheWorldMgr-&amp;gt;UnloadWorld();&lt;br /&gt;
	TheWorldMgr-&amp;gt;SetWorldCreator(nullptr);&lt;br /&gt;
&lt;br /&gt;
	// If the start window exists, delete it. We need to do this here, instead of letting the&lt;br /&gt;
	// Interface Manager clean it up, because the destructor code for the window is in this DLL.&lt;br /&gt;
&lt;br /&gt;
	delete TheStartWindow;&lt;br /&gt;
&lt;br /&gt;
	// Tell the Message Manager to clean up.&lt;br /&gt;
&lt;br /&gt;
	TheMessageMgr-&amp;gt;EndGame();&lt;br /&gt;
&lt;br /&gt;
	delete downAction;&lt;br /&gt;
	delete upAction;&lt;br /&gt;
	delete rightAction;&lt;br /&gt;
	delete leftAction;&lt;br /&gt;
	delete backwardAction;&lt;br /&gt;
	delete forwardAction;&lt;br /&gt;
&lt;br /&gt;
	// Restore the previous escape key handling function.&lt;br /&gt;
&lt;br /&gt;
	TheInputMgr-&amp;gt;SetEscapeCallback(prevEscapeCallback, prevEscapeCookie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
World *Game::CreateWorld(const char *name, void *cookie)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called when a new world is being loaded. It should&lt;br /&gt;
	// return a pointer to a newly constructed subclass of the World class.&lt;br /&gt;
&lt;br /&gt;
	return (new GameWorld(name));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Game::EscapeCallback(void *cookie)&lt;br /&gt;
{&lt;br /&gt;
	// This function is called when the user hits the escape key in gameplay&lt;br /&gt;
	// mode because we registered it using the InputMgr::SetEscapeCallback() function.&lt;br /&gt;
	// In this case, we open the start window shwoing the main menu.&lt;br /&gt;
&lt;br /&gt;
	TheInterfaceMgr-&amp;gt;AddWidget(new StartWindow);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Simple Games]]&lt;br /&gt;
* [[SimpleChar Source Code]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
</feed>