Difference between revisions of "Flappy Tim - Part One"

From Contraptionmaker Wiki
Jump to: navigation, search
 
(28 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
== Flappy Tim - Part One ==
 +
 
If you are just getting started, be sure to read [[Contraption Maker Modding Guide]] first.
 
If you are just getting started, be sure to read [[Contraption Maker Modding Guide]] first.
  
 
The very first mod we at Spotkin decided to make is the new “Hello, World” of games - a clone of the game “Flappy Bird”. We were amazed at how little code it took. Let’s walk through the construction of “Flappy Tim” step by step.
 
The very first mod we at Spotkin decided to make is the new “Hello, World” of games - a clone of the game “Flappy Bird”. We were amazed at how little code it took. Let’s walk through the construction of “Flappy Tim” step by step.
  
 +
=== Create the Level ===
 
The first thing you need to do is create a simple level with a Toolman Tim and a wall piece as a floor. Then you will need to give Toolman Tim a script name so that we can access him from the script. You do this by clicking the script button after selecting Toolman Tim.
 
The first thing you need to do is create a simple level with a Toolman Tim and a wall piece as a floor. Then you will need to give Toolman Tim a script name so that we can access him from the script. You do this by clicking the script button after selecting Toolman Tim.
  
Line 10: Line 13:
  
 
[[File:Nameflappy.png|400px|center]]
 
[[File:Nameflappy.png|400px|center]]
 +
 +
=== Adding Forces ===
  
 
Contraption Maker will automatically create the script object “FlappyTim” so that it can be accessed with the modding script. Say for example we wanted to make FlappyTim jump when the level first starts. We could add a force to him like this:
 
Contraption Maker will automatically create the script object “FlappyTim” so that it can be accessed with the modding script. Say for example we wanted to make FlappyTim jump when the level first starts. We could add a force to him like this:
  
<code>
+
<syntaxhighlight lang="javascript">
function onStart()
+
function onStart()
{
+
{
   FlappyTim.addForce(CM.DIR_UP,5);
+
   FlappyTim.addForce(CM.DIR_UP,5000);
}
+
}
</code>
+
</syntaxhighlight>
  
 
There a few new things introduced in this one line of code that you should notice.
 
There a few new things introduced in this one line of code that you should notice.
  
We are calling a method on a script object that we named in the Make editor. That object’s name is FlappyTim.
+
* We are calling a method on a script object that we named in the Make editor. That object’s name is FlappyTim.
We are calling a method on that object called “addForce” and passing in two parameters: a direction in which to apply the force and the size of the force. Technically, in physics terms, we are actually adding an impulse.
+
* We are calling a method on that object called “addForce” and passing in two parameters: a direction in which to apply the force and the size of the force.
The direction is a property on a global object “CM”. You will frequently use this object’s properties and methods when writing mods. This global object is always available from any function. For a complete list of properties and methods on the CM object, see the Javascript API Documentation: [link]
+
* The direction is a property on a global object “CM”. You will frequently use this object’s properties and methods when writing mods. This global object is always available from any function. For a complete list of properties and methods on the CM object, see the Javascript API Documentation: [http://jsdocs.contraptionmaker.net/CM.html CM]
  
 
Try entering this script and hitting play. You should see FlappyTim jump up in the air!
 
Try entering this script and hitting play. You should see FlappyTim jump up in the air!
Line 30: Line 35:
 
Just for fun, try adding another force to the right:
 
Just for fun, try adding another force to the right:
  
<code>
+
<syntaxhighlight lang="javascript">
function onStart()
+
function onStart()
 +
{
 +
  FlappyTim.addForce(CM.DIR_UP,5000);
 +
  FlappyTim.addForce(CM.DIR_RIGHT,5000);
 +
}
 +
</syntaxhighlight>
 +
 
 +
This time when you hit play FlappyTim will jump up and to the right, and possibly fall off the screen if the floor isn’t long enough!
 +
 
 +
=== Let's Flap! ===
 +
 
 +
That was fun, but now lets figure out how we can make FlappyTim move like he should. In Flappy Bird, the bird is constantly flying to the right. We've seen how to apply a single force. How can we apply a constant force? The trick is to apply the force not in the onStart method, but in the onUpdate method. The onUpdate method is called once every frame. Remove the addForce calls from the onStart method and modify your onUpdate function to apply a force every call.
 +
 
 +
The FlappyTim script should now look like this:
 +
 
 +
<syntaxhighlight lang="javascript">
 +
function onStart()
 +
{
 +
}
 +
 +
function onUpdate()
 +
{
 +
  FlappyTim.addForce(CM.DIR_RIGHT,1000);
 +
}
 +
</syntaxhighlight>
 +
 
 +
When you run this you will notice a problem. FlappyTim flies too fast off the right side of the screen. We need a way to cap his velocity. We can do this by only applying a force if his velocity is less than the velocity we want him to move.
 +
 
 +
<syntaxhighlight lang="javascript">
 +
function onUpdate()
 
  {
 
  {
  FlappyTim.addForce(CM.DIR_UP,5);
+
  if (FlappyTim.getVelX() < 50)
  FlappyTim.addForce(CM.DIR_RIGHT,5);
+
  {
 +
    FlappyTim.addForce(CM.DIR_RIGHT,1000);
 +
  }
 
  }
 
  }
</code>
+
</syntaxhighlight>
  
This time when you hit play FlappyTim will jump up and to the right, and possibly fall off the screen if the floor isn’t long enough.
+
Now FlappyTim moves at a nice even speed.
 +
 
 +
But wait - how can we let the user make him actually jump? In addition to the onStart and onUpdate methods, there is a third built-in callback function that Contraption Maker will call if it is in your script: onKeyDown. In this method, we can check for a particular key and apply an upward force when that key is pressed.
 +
 
 +
<syntaxhighlight lang="javascript">
 +
function onKeyDown(key)
 +
{
 +
  if (key == CM.KEY_SPACEBAR)
 +
  {
 +
      FlappyTim.addForce(CM.DIR_UP,5000);
 +
  }
 +
}
 +
</syntaxhighlight>
 +
 
 +
Now when you press play, Tim starts moving right, and by pressing the spacebar you can keep him aloft indefinitely. Now what we need are to add some obstacles to make things more challenging. Drag some pipes out to make a wall with a gap that Tim must get through, so it looks like this:
 +
 
 +
[[File:Timpipes.png|500px|center]]
 +
 
 +
=== Game Over ===
 +
 
 +
If you run the game now, Tim will hit the pipes and get stuck. We want the game to actually end, so lets add some code that ends the game when Tim hits a pipe. In order to do this, we need to add a function that will be called when Tim hits the pipe. Contraption Maker looks for the function “onCollision” attached to any script object and will call that function when the object hits something. The part that the object hits is passed into the function.
 +
 
 +
<syntaxhighlight lang="javascript">
 +
FlappyTim.onCollision = function(otherPart)
 +
{
 +
    partType = otherPart.getType();
 +
    if (partType == CM.PART_BIG_PIPE)
 +
    {
 +
        CM.showGameOver();
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 
 +
 
 +
There are a few new things being introduced here, lets break this down.
 +
 
 +
* We have created a new function to handle the collision and assigned it to the property "onCollision" on the FlappyTim object. The function takes a single parameter, which is the other part involved in the collision. If you are not used to Javascript - seeing a function assigned to a property like this is a little confusing at first. In Javascript, functions are objects that can be assigned to properties, just like values.
 +
* Inside the method, we call the function “getType” on the part parameter passed into the function.
 +
* We compare the part type we have collided with to the CM global constant for the big pipe part. If they are equal, we call a CM global function to end the game.
 +
 
 +
=== Next Steps ===
 +
 
 +
That is it for this first part of making FlappyTim. In the [[Flappy Tim - Part Two]], we’ll look at making the camera follow FlappyTim around and add a score, sound effects, and an explosion. Right now the completed script should look like this:
 +
 
 +
<syntaxhighlight lang="javascript">
 +
// onStart called when play is hit
 +
function onStart()
 +
{
 +
}
 +
 +
// onUpdate called every frame
 +
function onUpdate()
 +
{
 +
    if (FlappyTim.getVelX() < 50)
 +
    {
 +
      FlappyTim.addForce(CM.DIR_RIGHT,1000);
 +
    }
 +
}
 +
 +
function onKeyDown(keyCode)
 +
{
 +
    if (keyCode == CM.KEY_SPACEBAR)
 +
    {
 +
      FlappyTim.addForce(CM.DIR_UP,5000);
 +
    }
 +
}
 +
 +
FlappyTim.onCollision = function(otherPart)
 +
{
 +
    partType = otherPart.getType();
 +
 +
    if (partType==CM.PART_BIG_PIPE)
 +
    {
 +
        CM.showGameOver();
 +
    }
 +
}
 +
</syntaxhighlight>

Latest revision as of 23:42, 16 September 2014

Flappy Tim - Part One

If you are just getting started, be sure to read Contraption Maker Modding Guide first.

The very first mod we at Spotkin decided to make is the new “Hello, World” of games - a clone of the game “Flappy Bird”. We were amazed at how little code it took. Let’s walk through the construction of “Flappy Tim” step by step.

Create the Level

The first thing you need to do is create a simple level with a Toolman Tim and a wall piece as a floor. Then you will need to give Toolman Tim a script name so that we can access him from the script. You do this by clicking the script button after selecting Toolman Tim.

Selecttoolman.png

Clicking that button brings up a dialog where you can enter the name. We’ll call him “FlappyTim”.

Nameflappy.png

Adding Forces

Contraption Maker will automatically create the script object “FlappyTim” so that it can be accessed with the modding script. Say for example we wanted to make FlappyTim jump when the level first starts. We could add a force to him like this:

function onStart()
{
   FlappyTim.addForce(CM.DIR_UP,5000);
}

There a few new things introduced in this one line of code that you should notice.

  • We are calling a method on a script object that we named in the Make editor. That object’s name is FlappyTim.
  • We are calling a method on that object called “addForce” and passing in two parameters: a direction in which to apply the force and the size of the force.
  • The direction is a property on a global object “CM”. You will frequently use this object’s properties and methods when writing mods. This global object is always available from any function. For a complete list of properties and methods on the CM object, see the Javascript API Documentation: CM

Try entering this script and hitting play. You should see FlappyTim jump up in the air!

Just for fun, try adding another force to the right:

function onStart()
{
  FlappyTim.addForce(CM.DIR_UP,5000);
  FlappyTim.addForce(CM.DIR_RIGHT,5000);
}

This time when you hit play FlappyTim will jump up and to the right, and possibly fall off the screen if the floor isn’t long enough!

Let's Flap!

That was fun, but now lets figure out how we can make FlappyTim move like he should. In Flappy Bird, the bird is constantly flying to the right. We've seen how to apply a single force. How can we apply a constant force? The trick is to apply the force not in the onStart method, but in the onUpdate method. The onUpdate method is called once every frame. Remove the addForce calls from the onStart method and modify your onUpdate function to apply a force every call.

The FlappyTim script should now look like this:

function onStart()
{
}
 
function onUpdate()
{
   FlappyTim.addForce(CM.DIR_RIGHT,1000);
}

When you run this you will notice a problem. FlappyTim flies too fast off the right side of the screen. We need a way to cap his velocity. We can do this by only applying a force if his velocity is less than the velocity we want him to move.

 function onUpdate()
 {
  if (FlappyTim.getVelX() < 50)
  {
    FlappyTim.addForce(CM.DIR_RIGHT,1000);
  }
 }

Now FlappyTim moves at a nice even speed.

But wait - how can we let the user make him actually jump? In addition to the onStart and onUpdate methods, there is a third built-in callback function that Contraption Maker will call if it is in your script: onKeyDown. In this method, we can check for a particular key and apply an upward force when that key is pressed.

 function onKeyDown(key)
 {
   if (key == CM.KEY_SPACEBAR)
   {
      FlappyTim.addForce(CM.DIR_UP,5000);
   }
 }

Now when you press play, Tim starts moving right, and by pressing the spacebar you can keep him aloft indefinitely. Now what we need are to add some obstacles to make things more challenging. Drag some pipes out to make a wall with a gap that Tim must get through, so it looks like this:

Timpipes.png

Game Over

If you run the game now, Tim will hit the pipes and get stuck. We want the game to actually end, so lets add some code that ends the game when Tim hits a pipe. In order to do this, we need to add a function that will be called when Tim hits the pipe. Contraption Maker looks for the function “onCollision” attached to any script object and will call that function when the object hits something. The part that the object hits is passed into the function.

 FlappyTim.onCollision = function(otherPart)
 {
    partType = otherPart.getType();
    if (partType == CM.PART_BIG_PIPE)
    {
        CM.showGameOver();
    }
 }


There are a few new things being introduced here, lets break this down.

  • We have created a new function to handle the collision and assigned it to the property "onCollision" on the FlappyTim object. The function takes a single parameter, which is the other part involved in the collision. If you are not used to Javascript - seeing a function assigned to a property like this is a little confusing at first. In Javascript, functions are objects that can be assigned to properties, just like values.
  • Inside the method, we call the function “getType” on the part parameter passed into the function.
  • We compare the part type we have collided with to the CM global constant for the big pipe part. If they are equal, we call a CM global function to end the game.

Next Steps

That is it for this first part of making FlappyTim. In the Flappy Tim - Part Two, we’ll look at making the camera follow FlappyTim around and add a score, sound effects, and an explosion. Right now the completed script should look like this:

 // onStart called when play is hit 
 function onStart()
 {
 }
 
 // onUpdate called every frame
 function onUpdate()
 {
    if (FlappyTim.getVelX() < 50)
    {
       FlappyTim.addForce(CM.DIR_RIGHT,1000);
    }
 }
 
 function onKeyDown(keyCode)
 {
    if (keyCode == CM.KEY_SPACEBAR)
    {
       FlappyTim.addForce(CM.DIR_UP,5000);
    }
 }
 
 FlappyTim.onCollision = function(otherPart)
 {
     partType = otherPart.getType();
 
     if (partType==CM.PART_BIG_PIPE)
     {
         CM.showGameOver();
     }
 }