Torque 2D/Getting Started/T2DBasicTutorial1

From TDN

This page is a Work In Progress.

Image:T2D_tut_Basic01.jpg


Contents

Introduction


Welcome to Torque Game Builder (TGB)! We’re presently in an “Early Adopter” release, which means that TGB is in great shape, but it’s not at the pinnacle of where we want it to be yet. Our goal is to make TGB far and away the best 2D game engine around, and so many people wanted to get their hands on it as-is right now, that we decided to go ahead and offer this Early Adopter release. With your help, we can make this the best 2D game making tool ever! Your feedback is much appreciated, so please remember to stop by the TGB Private Forums and come talk with other TGB developers, get help, and much more. Also, check out the TGB Projects Page whenever there’s an update.

Okay, let’s get on with this tutorial. Here, we’re going to give you a quick example of how to use TGB. By the end of this basic tutorial, you’ll have seen how to load sprites, tilemaps, particle-effects, set-up collision detection, accept player input, and even add a hint of gameplay!

We’ll treat TGB pretty much as a black box - rather than explaining how everything works inside TGB, our goal here is just to get you up and running as quickly as possible. This tutorial is written so that pretty much anyone can understand it; experienced programmers will no doubt want to skip over some of the explanatory stuff. Note though that we’re not trying to provide a whole programming tutorial here. We assume you are at least capable of looking at simple script code without exploding your mind.  ;) If you want more information on TorqueScript, please see the Torque Documentation.

We’ll be adding to the TGB documentation more and more over time. If you want more technical details please see the informal TGB technical overviews included with the TGB documention and watch for additional documentation updates.

Alright, let’s see how to get some stuff up on the screen!

NOTE: References to forums and websites discussed can be found at the end of this document.

Getting Started


T2D comes with some example demos, which you can look at and learn from. You can think of these demos as mini-“Starter Kits”, which show you simple examples of how to do particular kinds of games. All by itself though, without any other demos running, T2D looks like this

Image:T2D_tut_Basic02.jpg
That’s the base T2D homepage. From here, you can launch T2D’s GUI editor, Particle editor, and Tile editor. And you can also hook into the T2D community and forums. We’ll start building our example game using the files in the base in this directory. Let’s dig in!

Note: This tutorial was written using the early release version of T2D, which has a default white background. To make your screenshots match those shown, open the SDK\games\T2D\gui\mainScreenGui.gui file and find/replace the text “logoblack” with “logowhite”.

Note: Any time you do a tutorial or experiment with Torque 2D, it’s a good idea to copy your entire Torque2D directory and modify only the copy. That way your original files remain intact.

Adding custom code


Go to your main T2D folder, and before we get started, save a back-up copy of this whole folder somewhere. Okay, now, go to the “games” folder. You’ll see the T2D.exe binary. If you double-click it, you’ll be brought to the T2D homepage. (Quit out any time)

By default, T2D operates scripts in the “T2D” script sub-folder. To start putting stuff up on the screen, you need to add some code to the base scripts in this folder. So, get your favorite script editor handy! (See the Torque Game Engine documentation for more information on common script editors)

The file we’ll start with is in the “gameScripts” sub-folder, and its name “game.cs”. Open that puppy up, and take a look inside it. Through a chain of start-up commands, the “game.cs” script is loaded, and the function “setupT2DScene()” is called. The code for this function is simple right now:


//---------------------------------------------------------------------------------------------
// setupT2DScene
// This function is the starting point for all game specific code.
//---------------------------------------------------------------------------------------------
function setupT2DScene()
{
   // Create our scenegraph
   new t2dSceneGraph(t2dScene);

   // Associate Scenegraph with Window.
   sceneWindow2D.setSceneGraph( t2dScene );
   
   // Set the current camera position
   sceneWindow2D.setCurrentCameraPosition("0 0 100 75");
}


We’ll be adding our custom code right after sceneWindow2D.setCurrentCameraPosition and before the functions closing curly brace

NOTE: If you have a more recent version of T2D, the code above may not show up in your game.cs file. Your game.cs file might look like this instead:


//---------------------------------------------------------------------------------------------
// Torque 2D. 
// Copyright (C) GarageGames.com, Inc.
//---------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------------
// startGame
// All game logic should be set up here. This will be called by the level builder when you
// select "Run Game" or by the startup process of your game to load the first level.
//---------------------------------------------------------------------------------------------
function startGame(%level)
{
   // Set The GUI.
   Canvas.setContent(mainScreenGui);
   Canvas.setCursor(DefaultCursor);
   
   moveMap.push();
   sceneWindow2D.loadLevel(%level);
}

//---------------------------------------------------------------------------------------------
// endGame
// Game cleanup should be done here.
//---------------------------------------------------------------------------------------------
function endGame()
{
   sceneWindow2D.endLevel();
   moveMap.pop();
}

If that is the case, just copy this code into the file instead, and you will be ready to go:


//---------------------------------------------------------------------------------------------
// Torque 2D. 
// Copyright (C) GarageGames.com, Inc.
//---------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------------
// startGame
// All game logic should be set up here. This will be called by the level builder when you
// select "Run Game" or by the startup process of your game to load the first level.
//---------------------------------------------------------------------------------------------
function startGame(%level)
{
   // Set The GUI.
   Canvas.setContent(mainScreenGui);
   Canvas.setCursor(DefaultCursor);
   
   //moveMap.push();
   //sceneWindow2D.loadLevel(%level);
   setupT2DScene();
}

//---------------------------------------------------------------------------------------------
// endGame
// Game cleanup should be done here.
//---------------------------------------------------------------------------------------------
function endGame()
{
   sceneWindow2D.endLevel();
   moveMap.pop();
}



//---------------------------------------------------------------------------------------------
// setupT2DScene
// This function is the starting point for all game specific code.
//---------------------------------------------------------------------------------------------
function setupT2DScene()
{
   // Create our scenegraph
   new t2dSceneGraph(t2dScene);

   // Associate Scenegraph with Window.
   sceneWindow2D.setSceneGraph( t2dScene );
   
   // Set the current camera position
   sceneWindow2D.setCurrentCameraPosition("0 0 100 75");
}


Loading images


So, what should we put up on the screen? Remember, we’ve got those nifty little demos to pull from, so let’s use art from those. In fact, let’s use the side-scrolling shooter demo, and in this tutorial, we’ll see how to get started making a little “game” just like this demo. When we’re all done, you should not only have a good feel for how to get started with T2D, but you can compare the simple example code we create to the full demo code, and see what the differences are. It’ll help you learn more about creating more complex projects in T2D.

Go back to the example folder. Now go to the spacescroller/data/images folder, and copy everything in there (a bunch of pictures) over to our T2D/data/images folder. Choose to replace any files that you get asked about. And viola, we’ve got some art to work with.

Now, finally, let’s get our first image up on the screen. Back in the “T2D/gameScripts/game.cs” script, let’s add some custom code where we’re told to in the “setupT2DScene()” function. It’d be cool to get a space ship up on screen, so let’s do that first.

We need to create a new sprite, and here’s the first bit of code to do it:


datablock t2dImageMapDatablock(playershipImageMap)
{
   imageMode = full;
   imageName = "~/data/images/playerShip";
};


This code creates a new “image map”, which sprites (and everything else in T2D) use to read graphical data. Here, we’re reading a graphics file called “playerShip” and saying that we want to load the entire file as our image. If you go to the “T2D/data/images” directory, you’ll see a file called “playerShip.png”. This is the file we’re reading from here!

NOTE: If the code above doesn’t make perfect sense to you, don’t worry about it yet. If you haven’t used the Torque Game Engine much, you probably don’t know what a datablock is. Really, you don’t need to worry about it right now. Suffice it to say, you can follow the code given in this tutorial to create new objects for your game. If you are interested in learning more about the guts of how all this stuff works, please check out the technical reference documentation provided with T2D, and watch for more documentation on scripting and other systems inherited from Torque in the near future!

Creating a sprite


Okay, from the code above, we have a handy-dandy image ready to be used. Now, let’s create a sprite object that uses it:


$player = new t2dStaticSprite() { scenegraph = t2dScene; };
$player.setPosition("-35 0");
$player.setSize("14 7");
$player.setImageMap(playershipImageMap);


Paste this code below the code we just finished with. If you run T2D again right now and select "Launch/Run Game", you’ll see the player ship on-screen!! Pretty simple ay? Pretty much everything in T2D is this easy.

Image:T2D_tut_Basic03.jpg
Now, let’s take a quick look at what this code does.

This first line of code creates a new T2D object - a sprite - and adds it to the scenegraph called “t2dScene”, which was created at the top of the “setupT2DScene()” function, see above. Once again, if you aren’t familiar with the concept of a scenegraph, don’t worry about it much for now. In T2D, you can think of a scenegraph as the “master” of a scene.

In order to have a scene (a world with objects in it), you need a scenegraph, and every object you want to display needs to be added to that scenegraph. (For more information on T2D’s scenegraph system, please see the technical overview documentation.)

The next line of code tells T2D where we want our sprite to show up at. And the next line of code tells T2D how big we want our new sprite to be. The last line of code tells T2D what image we want to use for this sprite. By setting an image map for a sprite, we load up its graphics.

Pretty simple stuff! You can make the ship bigger and smaller by calling the “setSize” method. If you want to see this sprite show up in different places, try changing the ship’s location by calling “$player.setPosition(“-30, 10”);” Why "-30,10"? Without going into too many details, look through the setupT2DScene function and you'll see a call to setup the camera using "0 0 100 75". What this means is that our screen is to be 100 units wide and 75 units high with 0,0 been in the center of the screen. Try moving the ship to the left of the screen "-50 0" or right "50 0" or put it in the top left "-50 -37.5". Have fun!

More sprites!


Okay, now we’ve got one ship out there. Let’s make a bad guy to fight. To do this, we’ll use the exact same code structure as we did before. Here goes:


// set up the enemy
datablock t2dImageMapDatablock(enemyship1ImageMap)
{
   imageMode = full;
   imageName = "~/data/images/enemyship1";
};

%enemy = new t2dStaticSprite() { scenegraph = t2dScene; };
%enemy.setSize( "14 7" );
%enemy.setPosition("40 0");
%enemy.setImageMap( enemyship1ImageMap );


Here, we’ve used the same code structure to create a new sprite. This time, our image map uses the file called “enemyship1.png”, and our new enemy sprite loads this up. The size of the enemy ship is the same as the player’s, and we set the sprite position so that it’s close to the far end of the screen.

Things are starting to come together, but we’ve still just got a couple static images on the screen. Let’s start doing some cool stuff.

Note: If you are wondering why enemy is prefixed with a % and player is prefixed by a $ this is a torque script convention for identifying local and global variables. % is a local variable while $ is a global variable.

Image:T2D_tut_Basic04.jpg

Moving Around


Enemy movement detected! Alright, let’s make something move. How about we make the enemy ship fly at us? As with just about everything in T2D, this is incredibly easy to do. Check it out:


// move the enemy towards us.
%enemy.setLinearVelocityX(-20);


That’s it. Run T2D again, and see that the bad guy is flying toward us. Woohoo! This line of code forces our %enemy sprite to move to the left (along the X-axis), at the speed of 20 units per second. The enemy sprite will keep moving with this velocity, unless we tell it not to any more.

Alright, let’s take the next step, and make it so that the player’s ship can be moved around and controlled.

Player Input


T2D uses the same input-capturing system as the Torque Game Engine. In script, we define things called “Action Maps” which tie user input to particular actions. For example, when you define an action map and tie the “w” key to an action called “playerUp()”, Torque will automatically perform the “playerUp()” action that you define whenever the “w” key is pressed. Let’s set up an action map for player input:


// Create a new action map.
new ActionMap(playerMap);

// Bind keys to actions.
playerMap.bindCmd(keyboard, "w", "playerUp();", "playerUpStop();");
playerMap.bindCmd(keyboard, "s", "playerDown();", "playerDownStop();");
playerMap.bindCmd(keyboard, "a", "playerLeft();", "playerLeftStop();");
playerMap.bindCmd(keyboard, "d", "playerRight();", "playerRightStop();");
playerMap.bindCmd(keyboard, "space", "playerFire();", "");

// Activate the action map.
playerMap.push();


Looking at this code, the first line tells T2D that we need to create a new ActionMap. Then, we start filling the action map up with keyboard bindings. Each call to “bindCmd” binds a new input to an action. In this example, the first parameter in the “bindCmd” method tells T2D what input device we’ll be referring to. Torque has some pre-defined input devices it recognizes, such “keyboard” and “mouse”. There are others of course, and you can define your own. Then you tell T2D the name of the input you’re going to be binding to. In the case of keyboard input, these are the names of keys that will get pressed. The last two parameters in the bindCmd methods define script functions which will be called when the input is pressed and released, respectively. In this example, we say that the script function called “playerUp()” (which we haven’t defined yet) should be called when the “w” key is pressed down, and that the “playerUpStop()” function should be called when the “w” key is let up.

The last line of code “playerMap.push();” tells Torque to actually activate our new ActionMap.

You can see from the other key binds we’ve defined here that we’re planning on letting the player move up, down, sideways, and eventually to fire. To enable this capability, we need to define the actions, such as “playerUp()” and “playerUpStop()”, which we intend to call with the ActionMap.

Let’s take a look at defining the “playerUp()” functionality. The goal here is to define a chunk of code that, when executed, will get the player’s ship moving upwards on the screen. So far, we’ve been defining all our new code inside the “setupT2DScene()” function. Now, we need to define a new function – “playerUp()”.

To do this, just go below the “setupT2DScene()” function, and insert this new code:


function playerUp()
{
   // Set the player moving up.
   $player.setLinearVelocityY( -10 );
}


Here, we’ve created our first new function! Once again, the actual code inside the function to make something happen is incredibly simple. We just tell the player ship to start moving upward at a speed of 10 world units per second!

Though we haven’t finished defining all our actions yet, you can actually run T2D as-is right now, and see this code working. Go ahead and load up, the press the “w” key.

You’ll see the player start moving upward! Pretty cool. Of course, he just keeps going up and up and up after one press of the key. Let’s make it so he stops when we release the key.

To do this, we define our next action: “playerUpStop()”. Remember, we set-up our ActionMap so that this function will get called when the “w” key is released after being pressed. Our goal here is to make the player stop moving when the “w” key is released. As you might have guessed, this means we just have to set the $player’s linear velocity along the y-axis to zero! It’s easy:


function playerUpStop()
{
   $player.setLinearVelocityY( 0 );	
}


Try it out. You’ll see that when you let go of the “w” key, the player stops moving. And if you press it again, he’ll start moving again. When you release, he’ll stop again. Torque is using the ActionMap we defined and enabled perfectly.

Great, so our little dude can move up. Not very useful with just that though. We need to add the ability to move down, right, and left.

The process for adding these actions is very simple, it’s just like adding the ability to move up. Before we do that though, let’s handle a little bit of clean-up work. Our “playerUpStop()” function needs a little more code in it to be really useful. Really, before setting the player’s up and down movement speed to zero, we should first check that he’s actually moving up. It’s not very likely, but if we don’t do this, it’s possible the “playerUpStop()” function might get called while the player is moving downwards. And we wouldn’t want to affect downward movement in a function called “playerUpStop()”!

Detecting the player’s velocity, is easy. Here’s the new code to use for the “playerUpStop()” function:


function playerUpStop()
{
   // If we're moving up then nullify any upward movement.
   if ( $player.getLinearVelocityY() < 0 )
      $player.setLinearVelocityY( 0 );	
}


All we do here is ask the object about its linear velocity in the Y axis only. If it is less than zero, that means the player is moving upward on the screen. In that case, we’re moving up, and we’re inside the playerUpStop() function, so we set the new linear velocity along the Y axis to zero, as before.

Just a bit of clean-up code. This is an example of the kind of safe double-checking code you need to write in order to create production-quality games. However, if you don’t understand this code, or just plain don’t like it, you can choose to use the initial, simple version of “playerUpStop()” we created. Either way will work, but the original version is a little susceptible to rare bugs.

Okay, with that out of the way let’s get back to the fun stuff and let the player ship move around in all directions. Again, we need to define functions to handle moving down, left, and right. You can see these functions below, just copy and paste them below the “PlayerUpStop()” function.


function playerDown()
{
   // Set the player moving down.
   $player.setLinearVelocityY( 10 );
}

function playerDownStop()
{
   // If we're moving down then nullify any downward movement.
   if ( $player.getLinearVelocityY() > 0 )
      $player.setLinearVelocityY( 0 );	
}

function playerLeft()
{
   // Set the player moving left.
   $player.setLinearVelocityX( -10 );
}

function playerLeftStop()
{
   // If we're moving left then nullify any leftward movement.
   if ( $player.getLinearVelocityX() < 0 )
      $player.setLinearVelocityX( 0 );	
}

function playerRight()
{
   // Set the player moving right.
   $player.setLinearVelocityX( 10 );
}

function playerRightStop()
{
   // If we're moving right then nullify any rightward movement.
   if ( $player.getLinearVelocityX() > 0 )
      $player.setLinearVelocityX( 0 );	
}


Here, we’ve defined the player’s down, left, and right movement functions, along with their Stop counterparts.

These act and are structured exactly like the “playerUp()” and “playerUpStop()” functions. If you run the code with this in, you’ll have a fully moving player ship!! Have fun with it, the little player behaves very smoothly.

Image:T2D_tut_Basic05.jpg
Well, from the ActionMap we defined above, we just have the player firing action to define. Let’s do it! And we might as well make the bad guy fire back at us too.

Fighting is good


Missiles away! Alright, let’s make the enemy fire at us. To make the enemy fire a missile, we first need to load up a missile graphic. We do this in the same way we loaded up other graphics. In the “SetupT2DScene()” function, add this code below the line where we set the enemy’s linear velocity.


datablock t2dImageMapDatablock(enemymissileImageMap)
{
   imageMode = full;
   imageName = "~/data/images/enemyMissile";
};


Once again, all we’re doing here is creating an image that T2D can access. This one loads the enemy missile’s graphic. Now that we have this graphic established, we can create new missile sprites easily. Let’s set-up one up right now, and make it fire at us. Insert the following code just below the new image map definition we just pasted in:


%enemyFire = new t2dStaticSprite() { scenegraph = t2dScene; };
%enemyFire.setPosition( %enemy.getPosition() );
%enemyFire.setSize( "3 1.5" );
%enemyFire.setImageMap( enemymissileImageMap );
%enemyFire.setLinearVelocityX( -35 );
%enemyFire.setWorldLimit( kill, "-60 -40 60 40" );


Here, we’re creating a new sprite, adding it to our scenegraph, setting its position and size, and loading up a graphic (the one for the enemy missile, which we just defined in the above image map). Then we set the missile’s speed so that it’s rushing our way horizontally.

We’re doing something new here as well. The last line makes a call to the “setWorldLimit” method. This is a standard method for all objects, such as sprites, in T2D. Its name describes what it does pretty well - it just defines a rectangular boundary in the world which an object cannot go beyond. setWorldLimit’s last parameter defines the 4 corner points of the rectangle which serves as this object’s world limit. The first parameter specifies one of six pre-defined world limit reaction modes that T2D defines. In this example the “kill” reaction is chosen. Using this reaction means that when the object meets its world limit, it will be deleted. So, for our example, we’re saying that enemy missiles should be deleted from memory once they go past their world limit (which is the edge of the screen, here).

Run the code now and watch what happens! The enemy will fire a missile at you right away, and it’ll come flying towards you. Dodge!

Cleaning up


Well, if you didn’t quite make it out of the way of the missile in time, you noticed that it didn’t hurt you. That’s because we haven’t turned on collisions for the player, enemy, or enemy missiles yet. We will do that just a little in the tutorial. Before we do so though, let’s look at our code so far.

At this point, we’ve created about 120 lines of code, and already have some simple action going on. You can see we’re getting on our way to having a little game up and running. But, take a look at our code so far, especially in the “SetupT2DScene()”. If you are starting to feel like this function is getting a little too long and complicated, pat yourself on the back; you’ve got good coder’s instincts.

In general, we want to try to write short, easy to understand functions that take care of individual, specific tasks. This way, we make our code easier to understand now, and easier to change later on. Let’s start cleaning up the code in “SetupT2DScene()” a little.

Going back up near the top of the function, where we first started inserting code, let’s trace over things and see exactly what we’re doing so far. Here’s a high-level outline of what our code is doing so far:

  • Set-up an image for the player ship
  • Create the player ship
  • Set-up an image for the enemy ship
  • Create the enemy ship
  • Set-up an image for the enemy missile
  • Create an enemy missile and fire it
  • Set-up the Player’s ActionMap.


That’s quite a few pieces of functionality for one function to do, and if we continue creating things this way, the “SetupT2DScene()” function is just going to get longer, uglier, and harder to understand. Let’s separate things up a bit, and create some sub-functions to call.

Looking at the list of tasks we’re performing so far, it seems we could categorize them in a few ways. We might group together all the image set-ups. Next, we might group the creation of the player and setting his ActionMap. Next, we might group the creation of the enemy ship and enemy missile, along with making it fire.

This is a simplistic set of groupings, but breaking out our functionality according to such lines will make code easier to write from this point on. So let’s do it.

Create a new function called “SetupImages()” and paste it just below the “SetupT2DScene()” function:


function SetupImages()
{
}


Now, take all the code that sets up images from “SetupT2DScene()” - creating the image maps for the player ship, enemy ship, and enemy missile-- and cut and paste it all into our new “SetupImages()” function:


function SetupImages()
{
   // Create an image for the player ship
   datablock t2dImageMapDatablock(playershipImageMap)
   {
      imageMode = full;
      imageName = "~/data/images/playerShip";
   };

   // Create an image for enemy ships
   datablock t2dImageMapDatablock(enemyship1ImageMap)
   {
      imageMode = full;
      imageName = "~/data/images/enemyship1";
   };
   
   // Create an image for the enemy's missiles
   datablock t2dImageMapDatablock(enemymissileImageMap)
   {
      imageMode = full;
      imageName = "~/data/images/enemyMissile";
   };
}


Now, back in “SetupT2DScene()”, where we first began inserting new code, call the “SetupImages()” function:


// Set up the images for the game
SetupImages();


At this point, you can run the game again. You’ll see that everything behaves just as it did before, and our code is already starting to look more modularized and clean. Let’s keep it up. Next, let’s create a function for setting-up the player’s stuff:


function CreatePlayer()
{
}


Now, just as before, let’s cut the Player set-up stuff from “SetupT2DScene()” and move it in here:


function CreatePlayer()
{
   // Create the player's ship sprite
   $player = new t2dStaticSprite() { scenegraph = t2dScene; };
   $player.setPosition("-35 0");
   $player.setSize( "14 7" );
   $player.setImageMap( playershipImageMap );   

   // Create a new action map.
   new ActionMap(playerMap);
   
   // Bind keys to actions.
   playerMap.bindCmd(keyboard, "w", "playerUp();", "playerUpStop();");
   playerMap.bindCmd(keyboard, "s", "playerDown();", "playerDownStop();");
   playerMap.bindCmd(keyboard, "a", "playerLeft();", "playerLeftStop();");
   playerMap.bindCmd(keyboard, "d", "playerRight();", "playerRightStop();");
   playerMap.bindCmd(keyboard, "space", "playerFire();", "");
   
   // Activate the action map.
   playerMap.push();
}


And then make sure to call this new function in “SetupT2DScene()”


// Set up the player's stuff
CreatePlayer();


If you run the game again, you’ll see that everything behaves normally. The player’s ship is created, and the ActionMap works great.

Finally, let’s do a similar set-up function for the enemies stuff. This one will need to create the enemy’s stuff:


function CreateEnemy()
{
   // Create an enemy ship
   %enemy = new t2dStaticSprite() { scenegraph = t2dScene; };
   %enemy.setImageMap( enemyship1ImageMap );
   %enemy.setSize( "14 7" );
   %enemy.setPosition("40 0");
   
   // Move the enemy towards us.
   %enemy.setLinearVelocityX(-20);

   // Create an enemy missile and fire it
   %enemyFire = new t2dStaticSprite() { scenegraph = t2dScene; };
   %enemyFire.setPosition( %enemy.getPosition() );
   %enemyFire.setSize( "3 1.5" );
   %enemyFire.setImageMap( enemymissileImageMap );
   %enemyFire.setLinearVelocityX( -35 );
   %enemyFire.setWorldLimit( kill, "-60 -40 60 40" );
}


And then we need to call it “SetupT2DScene()” like so:


// Set up the enemy
CreateEnemy();


Alright! Our code’s looking pretty nice and clean. Now, let’s get on with making a game again. Next on our agenda is to allow the player ship to fire missiles. And then, to make firing missiles mean something by enabling collision.

The Player Strikes Back


Remember back when we defined our “actionMap()”? We specified that whenever the space bar was pressed down, a script function called “playerFire()” should be called, but we never defined that function. Let’s do it now, and add in the code we need to create and fire a missile for the player.

In order to create and fire a player missile, we of course need to set-up an image for it, then create a sprite using the image, and move that sprite across the screen, just as before. To create the image, let’s add code to our shiny “SetupImages()” function, I’d add it right below the part that create’s the player’s ship:


// Create an image for the player's missiles
datablock t2dImageMapDatablock(playermissileImageMap)
{
   imageMode = full;
   imageName = "~/data/images/playerMissile";
};


Now that we have an image for player missiles, let’s finally create our “playerFire()” function, so we spawn a missile when the space key is pressed:


function playerFire()
{
   // Create player projectile.
   %projectile = new t2dStaticSprite() { scenegraph = t2dScene; };
   %projectile.setPosition( $player.getPosition() );
   %projectile.setSize( "3 1.5" );
   %projectile.setImageMap( playermissileImageMap );
   %projectile.setWorldLimit( kill, "-52 -40 52 40" );
   %projectile.setLinearVelocityX( 35 );
}


No problems. As per usual, we’re just creating a sprite, settings its position, size, and image. And as with the enemy projectile, we’re setting the player missiles’ world limit and speed.

Jump in and test. Every time you press space, a missile will fire now!

Pretty cool ay? If you’ve got a sharp eye, you’ll notice that our missiles aren’t quite firing from right spot on the player’s image. There’s a little cannon on the player ship sprite which is meant to launch missiles from. It’s easy to fix this. In our current “playerFire()” code, we’re setting the projectile’s position to the player’s exact position, by calling “$player.getPosition();” Well, the player’s position isn’t quite the same spot as where we want to fire from. So, let’s see how to fix this.

We’ll just use T2D’s link mechanism. Links are convenient ways to define points that you want to keep track of on an object. If we go back to the “CreatePlayer()” function, we can set-up a missile fire link point. Add the following code just after the code to $player.setImageMap in the “CreatePlayer()” function:


$player.fireLinkPoint = $player.addLinkPoint( "0.45 0.2" ); 


The “addLinkPoint()” method creates a new anchor point, taking a space-delimted pair of relative x, y coordinates that define the point on the player sprite that we want to link to. In this line of code, we’ve also created a new variable inside our $player object, called “fireLinkPoint”, and by setting this new variable to the new link point we create, we can easily refer to the link point later.

Now, let’s see how to use this link point. Go back to the “playerFire()” function, and “%projectile.setPostion” as follows:


%projectile.setPosition( $player.getLinkPoint($player.fireLinkPoint) );


Okay! This little change sets the projectiles initial position by calling the $player’s “getLinkPoint()” method. The “getLinkPoint()” method returns the position of a particular link point. You tell this method what link point to look for by calling the link point by name. So, when we call “$player.getLinkPoint( $player.fireLinkPoint );” we’re telling T2D to return the coordinates of the link point named “fireLinkPoint” inside the $player object.

And hey, while we’re in here, we might as well give the player a world limit too. Add this line of code:


$player.setWorldLimit( clamp, "-49 -37 40 37" );


This set’s up the player’s world limits, as per usual, but instead of using the “kill” response type, now we’re using the “clamp” type. T2D defines this type, and using it means that player sprite will simply brush against its world limit, but won’t bounce off, stick to it, be deleted, etc.

Okay, now run this sucker again and check out the results. Your player fires missiles just dandy, and they come from the right spot now!

Looking good, but this would be a lame game so far, it only lasts for a few seconds, then the enemy goes off-screen and all you can do is run and fire missiles at the air. Let’s add more bad guys. Then, we’ll finally turn on collisions between ourselves and our foes.

Adding more baddies


Bring ‘em on! Let’s see how to make more bad guys. We’ll do it in our handy-dandy “CreateEnemy()” function. Before we get started, if we’re going to be creating a bunch of enemies, we should make sure we delete old ones before going much further. So, let’s add some world limits to our enemy sprites, just like we do for projectiles. In the “CreateEnemy()” function, add this line of code after the call to “%enemy.setLinearVelocityX()”:


%enemy.setWorldLimit( kill, "-60 -40 60 40" );


Now, just like with projectiles, enemy ships which reach their world limits will be deleted.

Next, let’s create a bunch of enemies over time. Add the following line to the very bottom of the “CreateEnemy()” function:


schedule(2000, 0, "CreateEnemy");


The schedule function is defined by T2D (inherited from TGE) and allows you to call a function at some point in the future. In this example, we are saying that we want to call the “CreateEnemy()” function again in 2000 milliseconds (2 seconds). The result of adding this line of code to the “CreateEnemy()” function is that a new enemy will be created every two seconds!

Run this code… weeha! Gonna be fun to kill all these guys. The only problem now is that they all spawn in the same point. Let’s change it up a bit.

Back inside the “CreateEnemy()” function, change the call to “%enemy.setPosition()” to the following:


%enemy.setPosition("40" SPC (-30 + (getRandom() * 60)));


Image:T2D_tut_Basic06.jpg
Funky looking, but what this does is set each enemy’s vertical position randomly along the Y (vertical) axis. Each time an enemy is spawned, it will be created at x-position 40 (near the right edge of the screen), and with a random Y position between -30 and 30.

And there you have it. Three easy lines of code to change and suddenly we’ve got a serious amount of enemies to fight. It’s so easy with T2D.

Alright, great, we’ve got a bunch of enemies, and they’re firing at us, we’re able to fire back, and it looks like this game might be getting pretty cool. It’s just too bad our attacks can’t harm anything. What good is fighting if you can’t hurt the other guy? Let’s turn on collisions between ourselves and our enemies.

Collision


Turning on collisions is really simple. It really just takes some set-up work. Let’s visit our two favorite functions again, “CreatePlayer()” and “CreateEnemy()”.

We just need to tell T2D to turn on collisions for our objects. Specifically, we’ll set-up collision properties for the player ship, player missiles, enemy ships, and enemy missiles. Here’s what we do in “CreatePlayer()”:


// Set player's collision info:
$player.setGraphGroup( 1 );
$player.setLayer( 1 );
$player.setCollisionActive( true, true );
$player.setCollisionPolyCustom( 4, "-1 0 -0.1 -0.6 0.98 0.15 -0.1 0.7" );
$player.setCollisionMasks( BIT(2), BIT(2) );
$player.setCollisionCallback( true );


Just add this code in. What we’re doing here is telling T2D how we want our sprite to behave when it comes to collision. First, we tell T2D what group and layer our object is a part of. We can use groups and layers of objects to define collision groups… for example, if the player is in group 1 and the player’s missile is in group 2, we can make sure that the player does not collide against group 2 (so that player missile’s can’t harm the player when they’re first fired). For more information on this system, please see the detailed technical overview documentation.

Next, we call “$player.setCollisionActive(true, true);” to tell T2D that we want the player to both be affected by collisions with other objects and to cause collisions with other objects. Once again, please see the technical overview documentation for more information on this system.

Next, we call the “setCollisionScale()” method. This is an advanced function, but what it does is scale down the object’s collision polygon by the multiples specified along the x and y axis. T2D’s collision system is very powerful, and we encourage you to find out more about it. For now, the technical overview documentation (and the source code) are the best places to look for detailed information. This tutorial is just meant to show you how to get stuff like this up and running, not explain in complete detail how it works. Moving on then…

We next call “setCollisionMasks()”. This call relates to our previous calls to “setGraphGroup()” and “setLayer()”. The collisionMasks determine what groups and layers of other objects this object collides against. In this demo, we’re going to assign the player and player missiles to group and layer #1. Then, we’ll assign the enemy ships and missiles to group and layer #2. Then, we want to make sure that the player ship and missiles collide against objects in group / layer #2 (enemy ships and missiles). The opposite would be true for enemy ships and missiles… we want enemy ships and missiles to collide with the player’s stuff, so we’ll set the enemy collisionMasks to group and layer #1.

Finally, we call “setCollisionCallback( true );”. This tells T2D that we want this object to spawn a script collision callback. We’ll see how to use this feature in just a bit. For now, let’s get on with the rest of this code.
We need to set-up the player projectiles similarly to how we set-up the player ship sprite itself. So, in the “playerFire()” function, add:


// Setup collision info
%projectile.setGraphGroup( 1 );
%projectile.setLayer( 1 );
%projectile.setCollisionActive(true, true);
%projectile.setCollisionPolyScale("0.9 0.5");
%projectile.setCollisionMasks( BIT(2), BIT(2));
%projectile.setCollisionCallback( true );


This does exactly the same thing as the player script’s collision set-up work.

Next, in “CreateEnemy()”, we do almost the same thing again. Add this group of code:


// Set enemy collision info
%enemy.setGraphGroup( 2 );
%enemy.setLayer( 2 );
%enemy.setCollisionActive( true, true );
%enemy.setCollisionPolyCustom( 5, "-0.9 0 0 -0.6 1 -0.3 1 0.3 0 0.5" );
%enemy.setCollisionMasks( BIT(1), BIT(1) );
%enemy.setCollisionCallback( true );


And this:


// Set up collision info
%enemyFire.setGraphGroup( 2 );
%enemyFire.setLayer( 2 );
%enemyFire.setCollisionActive( true, true );
%enemyFire.setCollisionPolyScale("0.9 0.5");
%enemyFire.setCollisionMasks( BIT(1), BIT(1) );
%enemyFire.setCollisionCallback( true );


Again, these two groups of code do the same thing as the player sprite and missile collision set-up code. Only this time, we’re adding the objects to group and layer #2, and setting our collision masks so that we collide with objects in group or layer #1.

That’s all the set-up work. Now, we need to do something with this “collision callback”. The collision callback is a script function that T2D calls whenever an object that has its “collisionCallback” parameter set to true collides with another object. The name of the function called is t2dSceneObject::onCollisionCallback(…)
T2D v1.02 Note: call this fxSceneObject2D::onCollisionCallback(...)

It’s gnarly sounding. And kind of gnarly looking. Check it out:


function t2dSceneObject::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
}


We need to add a function like this somewhere in our script any time we have an object which has its collisionCallback value set to true. In this example, we’re going to put some code into this collision callback function which will kill the player or enemies that get hit.

One way to do this, in this example, would just be to delete any objects that collide with each other. Since all we have is ships and missiles in this simple example, and since we’ve made it so that only enemy stuff can collide with the player, and only the player’s stuff can collide with enemies, we can assume that whenever there’s a collision detected, both objects in the collision should be destroyed.

The t2dSceneObject::onCollision function passes us a lot of information to read from. The first two parameters it returns are the srcObj and dstObj for a given collision. “srcObj” refers to the “source object”, or the object which caused the collision. “dstObj” refers to the destination object, which is the object receiving the collision.

So, a simplistic approach to handling collision detection in our little game would be to simply delete both srcObj and dstObj whenever the collision callback function is called.

This would work just fine, except that if we delete the player object, we have to recreate a player to get it back. Also, because of the way the ActionMap works, if we delete the player object while keys are being pressed and the ActionMap is active, T2D will complain (silently). We also need to be careful about “memory leaks”, or leaving objects floating around that we never delete.

Really, we should be a bit more careful about how we handle collision response here. It’s true that no matter what happens, whenever there’s a collision detected between two objects in this simple little game, we want both objects to be killed. In order to get this behavior in a way that doesn’t waste memory or abuse the ActionMap, we have to be a little bit careful.

The whole problem here arises from the fact that it is not advisable to delete the player object. However, we still want the player to “die” when it gets hit by enemies. So, let’s create a couple useful functions for ourselves: “KillPlayer()” and “ResetPlayer()”, then we’ll come back and see a decent way to handle things in our collision callback.
The “KillPlayer()” function is a simple little thing intended to “kill” the player’s ship. Check it out:


function KillPlayer()
{
   $player.setVisible( false );
   playerMap.pop();
   schedule(2000, 0, "ResetPlayer");
}


Insert this function somewhere in your script. What it does is, first, set the player’s ship to invisible. Then it calls the “pop()” method on the playerMap ActionMap. This disables the action map, meaning that the player’s input will be ignored (until the playerMap is reactivated). Finally, this function schedules the execution of the “ResetPlayer()” function which we’re just about to define.

The net result here is that the player has effectively been “killed”. For this simple example game, this just means that we hide the player, disable their gameplay input, and re-spawn them after a short delay. If we were making a different game, we could put whatever we wanted in this function - a score penalty, a load game dialog, or whatever we wanted.

Now, we’ll define the “ResetPlayer()” function, as you might have guessed, in order to restore the player to life after he’s been killed. Here’s the code:


function ResetPlayer()
{
   $player.setPosition("-35 0");
   $player.setVisible(true);
   playerMap.push();
}


You can see, we’re returning the player’s ship to it’s originally position, making it visible once again, and re-enabling the playerMap ActionMap. Basically, this function “re-spawns” the player.
Okay. With these two functions in hand, we’re ready to write a decent collision callback function. Here goes:


function t2dSceneObject::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
   if (%srcObj == $player)
   {
      KillPlayer();
      %dstObj.safeDelete();
   } 
   else if (%dstObj == $player)
   {
      KillPlayer();
      %srcObj.safeDelete();
   } 
   else
   {
      %srcObj.safeDelete();
      %dstObj.safeDelete();
   }
}


Remember, this function will get called every time a pair of objects (where at least one has their collision callback enabled) collide with each other. The code above first checks if either the %srcObj or %dstObjs are the $player ship. If neither object involved in the collision is the player ship - say it’s an enemy ship and one of our missile’s - we can just delete both objects. That’s what the calls to “safeDelete()” do.

If either %srcObj or %dstObj is the player ship though, we need to be careful, for all the reasons above. In either case, we’ll call the “KillPlayer()” function - since the player was hit by an enemy object, he needs to die. Then, we’ll delete the other object involved in the collision.

Got it? Good. Then let’s run this puppy! And hey, look at that, collisions are working. We can now kill or be killed.

Sweet, we’re getting pretty far a long now. We have a very simple, but truly interactive little game going on here now. And look how little code it’s taken so far! Less than 250 lines! Still, why are we fighting on this background? Is this Logo Wars? Let’s add a real background, and make this project really start looking good with some special particle effects.

Adding a tilemap


Crank it up to eleven!! Alright, our current background just won’t do for a game. Let’s set-up a scrolling tilemap for a background instead.

T2D has an incredibly flexible tile system, but going into detail about how it works and how to use the Tile Editor is beyond the scope of this basic tutorial (but see the tile editor documentation for more information on it). For now, we’ll just use a pre-existing tile map, just like we used pre-existing images for our player ship, enemy ship, and missiles.

Go back to the “games” folder in your copy of T2D, and head down to “games/spacescroller/data/tilemaps”. Copy the contents of the “maps” folder into games/T2D/data/tilemaps. The maps folder which you’ve just copied over contains a file called “skytutorial.map”. This is a T2D tile map definition, saved in T2D’s custom tile map file format. We can use this saved map definition to quickly and easily create a nice tile map for our little game.

There are 4 steps to loading up a tilemap:

1) Set up the images to be used (just as with sprites or any other object)
2) Create the tilemap object itself.
3) Load a saved tilemap file (if you want to load one from disk)
4) Configure the tile layer for display

We’ll perform the first step, setting up the images to be used by the tile layer, in our existing “SetupImages()” function. Then, we’ll create a new function to handle the last four steps. Let’s get started! This is actually very, very simple with T2D.

At the bottom of “SetupImages()”, add the following lines of code:


// Create images for the tilemap
datablock t2dImageMapDatablock(bgBlankSkyImageMap)
{
   imageMode = full;
   imageName = "~/data/images/bg_blank_sky";
};
  
datablock t2dImageMapDatablock(bgCloud1ImageMap)
{
   imageMode = full;
   imageName = "~/data/images/bg_cloud_1";
};
   
datablock t2dImageMapDatablock(bgCloud2ImageMap)
{
   imageMode = full;
   imageName = "~/data/images/bg_cloud_2";
};

datablock t2dImageMapDatablock(bgCloud3aImageMap)
{
   imageMode = full;
   imageName = "~/data/images/bg_cloud_3a";
};
   
datablock t2dImageMapDatablock(bgCloud3bImageMap)
{
   imageMode = full;
   imageName = "~/data/images/bg_cloud_3b";
};


Note that the map we’ll load has been created specifically for this tutorial and only contains a single tile-layer to produce a ‘sky’ background whereas the scroller-demo map contains multiple tile-layers for mountains, buildings etc. This one layer uses five images, and the datablocks above define the image maps used to access the images. With that, we’ve taken care of step one on our list for creating a tilemap.

Next, let’s create a new function called “CreateTileMap()”. In this function, we’ll handle each of the remaining steps described above one by one.


function CreateTileMap()
{
   // Create tile-map.
   %scrollerMap = new t2dTileMap() { scenegraph = t2dScene; };
	
   // Load saved tile-map file.
   %scrollerMap.loadTileMap("~/data/tilemaps/skytutorial.map");

   // Fetch reference to the first (and only) tile-layer from tile-map.
   %skyLayer = %scrollerMap.getTileLayer( 0 );

   // Generate Scrolling Sky, re-size to fill the whole screen
   %skyLayer.setArea( "-50 -37.5 50 37.5" );
   %skyLayer.setTileSize( "25 25" );
   %skyLayer.setWrap( true, false );
   %skyLayer.setAutoPan( "30 0" );
}


At the top of this function, we create a new tilemap object, %scrollerMap, and add it to our scenegraph so that it can be displayed. Next, we tell %scrollerMap to load the information saved in the file “skytutorial.map”. Again, this file was saved from T2D’s tile editor.

Now, tilemaps are comprised of tile layers, which are in turn comprised of individual tiles. In the next line of code, we fetch a reference to a particular tile layer from %scrollerMap. We create a reference called %skyLayer, and set it to %scrollerMap’s first tile layer object.

Finally, we set-up our %skyLayer.

We want to position/size the tile-layer window such that it covers to whole screen. We do this with “setArea()” (see reference documentation for more details on this function).

Unlike other objects, the tile-layer does not rescale its contents (the tiles) automatically. It allows you to control the size of the tiles yourself. This, at first, may be confusing but it does allow precise control over the tile-sizes. Setting the tile-layer to cover the whole screen allows us to cover the screen with tiles, it does not scale the tiles! The final step then is to size the tiles such that they do cover the screen with “setTileSize(“25 25”);”. The tile-layer is 4 tiles wide by 3 tiles high. Because the scene-size is 100x75 world-units, setting all tiles to be 25x25 world-units will ensure that the tiles completely cover the window.

The “setWrap( true, false );” function tells %skyLayer that it should smoothly wrap its tile graphics along the x-axis, and not worry about wrapping around the y-axis. The “setAutoPan( “30 0” );” call tells %skyLayer to scroll its tiles by the screen at the rate of 30 world units per second.

Okay, now just remember to call “CreateTileMap();” from the “SetupT2DScene()” function. Once you’ve done so, run T2D again…

Image:T2D_tut_Basic07.jpg
How ‘bout that? A few quick, easy steps and suddenly we have a fully scrolling tile background up and running in our game. Pretty neat.

Things are starting too look good here. Now, let’s make it look even fancier. Time to add some special effects.

Adding effects


Here, we’ll see how to attach particle effects to our player and enemy ships. Just as with tiles, T2D has an incredibly powerful particle effects system. You can do all kinds of stuff with T2D particles, but once again, going into detail about how the system works and how to use the Particle Editor is beyond the scope of this basic tutorial. Watch for forthcoming docs on this topic in the near future! For now, we’ll just use some pre-existing particle effects, just like we have for images and tiles so far.

Head to the “games” folder again, and go to “games/spacescroller/data/particles”. Once there, copy all the files and paste them into “games/T2D/data/particles” folder. With that, you have a whole new slew of particle effects to choose from.

Now we have some effects to use, so let’s add a couple neat looking ones to the game. First, we’ll add thrusters to the player and enemy ships, it looks weird having ships flying around without big thrusters powering them. After we get that effect in, we’ll add explosions when something gets hit.

To do the thruster effect, let’s create another new function. We need to add the same jet effect to the player ship and all the enemy ships, so let’s define a separate function which can just attach a jet effect to any object we specify. We’ll call it “attachThruster()”, because it’s good to name your functions in obvious ways. Here’s the code for our new function:


function attachThruster(%mountObj, %mountPosition, %angle)
{
   // Create Player Thruster.	
   %thruster = new t2dParticleEffect() { scenegraph = t2dScene; };
   %thruster.loadEffect("~/data/particles/smallThruster.eff");
   %thruster.mount( %mountObj, %mountPosition, 0, false );
   %thruster.setRotation( %angle );
   %thruster.playEffect();
}


This function creates a new particle effect and the form for doing so is just like creating a new sprite or tilemap. Next, a saved effect file is loaded. T2D creates and saves .eff files from the Particle Editor, which you can access any time by hitting “F11” on your keyboard. Effect files define entire particle effects, and for more information on these, please see the T2D Technical Overview.

Next, “attachThruster()” mounts the smallThruster effect to the object specified by the %mountObj parameter. You’ll see how this is used in a moment. The %mountPosition passed into this function defines where on the %mountObj object to mount this effect.

Finally, “attachThruster()” sets the rotation for the effect, and actually begins running the effect as soon as “playEffect()” is called. This is all it takes to get neat particle effects working in your game.

Now, let’s do something with this attachThruster function. Go to the “CreatePlayer()” function, and add this line:


   attachThruster( $player, "-0.12 -0.33", 0 );


$player is passed to the “attachThruster()” function, so it will have the smallThruster effect attached at the specified position.

Our enemies have two thrusters, so we need to create and attach two copies of the smallThruster effect for each enemy ship. To do so, just go to the “CreateEnemy()” function and add these two lines:


   attachThruster( %enemy, "0.8 -0.12", 180 );
   attachThruster( %enemy, "0.8 0.18", 180 );


This time the current %enemy object is passed into “attachThruster()”, and the effect is loaded to it, in the specified position (and with the specified angle).

And there you have it! About ten lines of code, and suddenly all our sprites have nice particle effects attached to them.  :)

Image:T2D_tut_Basic08.jpg
Let’s see how to do one more effect. When something blows up (the player or an enemy ship), we should spawn an explosion effect. It’s just not cool to hit something with a missile and not see it blow up.

To add in explosion effects, let’s create one last new function: “createExplosion()”:


function createExplosion( %object )
{
   // Ignore if object not around anymore.
   if ( !isObject(%object) )
      return;
		
   // Shockwave Explosion.	
   %explosion = new t2dParticleEffect() { scenegraph = t2dScene; };
   %explosion.loadEffect("~/data/particles/shockwave_burst.eff");
   %explosion.setPosition( %object.getPosition() );
   %explosion.setEffectLifeMode( kill, 0.1 );
   %explosion.playEffect();
}


This function is very similar to “attachThruster()”. We pass in an object, and create an explosion near it. This time, we don’t need to actually mount the effect to the object though. The explosion effect will just play out wherever it was created.

There are a couple new calls in this function. First, we’re checking to make sure that the %object we’re passed in is still a valid one. If not, we’re just going to skip this function - no point spawning an explosion for an object that’s already been deleted. Also, we’re calling the “setEffectLifeMode()” method here, with the parameters “kill” and “0.1”, this specifies that we want the explosion effect to kill itself after 0.1 seconds (though any particles the effect spawns will stick around until they naturally die out).

Alright, now, we just need to call this function in order to spawn some explosion effects. To do that, let’s go back into our collision callback function:


function t2dSceneObject::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
   // Create an explosion for the collision that just occurred
   createExplosion( %dstObj );
   
   if (%srcObj == $player)
   {
      KillPlayer();
      %dstObj.safeDelete();
   } 
   else if (%dstObj == $player)
   {
      KillPlayer();
      %srcObj.safeDelete();
   } 
   else
   {
      %srcObj.safeDelete();
      %dstObj.safeDelete();
   }
}


We just added two lines at the very top of the collision callback function, and that’s it! Run the code, and you’ll see that stuff blows up when it gets hit now.

Woohoo! Okay… I’d say that’s a wrap. We’ve got a little game here. Congratulations, you’re well on your way to becoming a T2D master.

Now, we just need to make a quick note on how to release your games and projects made with T2D.

Image:T2D_tut_Basic09.jpg

Releasing Games Made With T2D


When you release a T2D-based game, you have to be careful not to give away the T2D editors or your source scripts. People shouldn’t be able to use your game as a game-making tool! Part of the T2D EULA states that you must remove the T2D-specific editors (tile editor and particle editor, for now) from your project before you release, and that you must not release any un-compiled scripts containing T2D-specific code (though, you can release raw scripts which don’t contain T2D-based code).

Fulfilling this requirement is really easy. Before you release your game, demo, or project publicly in any way, all you need to do is delete the T2D editors folders (eg “tileeditor” and “particleeditor”) from your distribution package, and then go through and delete the relevant .cs files (using command-line utils, such as “del /S *.cs” on Windows can be helpful here) . That’s all you have to do! And in the near future, we’ll be providing a utility which does this release packaging work for you.

Okay, we just wanted to make note of this important requirement, thanks for reading.

Conclusion


Alright, then… we did it! Now you know how to create a simple game in T2D, in practically no time. Took less than 25 pages of text to explain how to build this simple game from the ground-up, and less than 300 lines of code (counting blank lines and lots of comments!) to get this puppy up and running. Very cool.

This tutorial was pretty simple, but we hope you enjoyed it. And hopefully you now have a very solid idea of just how powerful T2D is and how quickly you can create cool games with it.

If you want more documentation, please check out the detailed technical overview, tile editor documentation, and T2D class reference. Or, just dig straight into the source code. It’s pretty well commented, simply structured, and easy to get a grasp on. Also, you can look at the script files used to create the T2D demos for nice examples of how to build things in T2D. In fact, looking at the code in this tutorial versus the code in the shooter T2D demo will help you get a feel for what other kinds of code you need to begin writing for more advanced situations. Again, you can think of these demos as mini-“Starter Kits”, giving you a leg up on creating particular kinds of games.

We’ll have many, many more docs rolling out over time here, so keep your eyes out for them.

Thanks for reading, and we hope you enjoy T2D! Please stop on by the forums or the community site at any time, where you can sign up for T2D announcements. We really, really want to hear from you on T2D, so please get involved in the community somehow. Working together, we can make this the best game making tool around!

Best wishes,

Melv, Josh, and the GarageGames team.


Complete SourceCode for this Tutorial (game.cs)

Here is the T2DBasicTutorial1_CompleteSourceCode , which would go into your games\t2d\gameScripts\game.cs file. (Note: As T2D is still in EA phase, this file may be for an older version of T2D which used slightly different syntax)

If you get stuck you can look at this 'complete' version of the basic tutorial for guidance and to see what you did wrong.

Torque 2D Web References


T2D Private Forums http://www.garagegames.com/mg/forums/result.area.php?qa=42
T2D Public Forums http://www.garagegames.com/mg/forums/result.area.php?qa=41
T2D Projects Page http://www.garagegames.com/mg/projects/t2d/