Game Development Community

Infinite Jumps?

by John Walsh · in Torque 2D Beginner · 07/02/2013 (12:13 pm) · 12 replies

Hey I've made an action map so my character can move right, left and up (jump). But how can I script it so that my character can only jump when he is standing on something? At the moment I'm able to spam W and make him fly.

Here is the controls.cs:

function InputManager::Init_controls(%this)
{
new ActionMap(goblincontrols);


goblincontrols.bindCmd(keyboard, "w", "GoblinUp();", "GoblinUpStop();");  
//goblincontrols.bindCmd(keyboard, "s", "GoblinDown();","GoblinDownStop();"); 
goblincontrols.bindCmd(keyboard, "a", "GoblinLeft();","GoblinLeftStop();");  
goblincontrols.bindCmd(keyboard, "d","GoblinRight();","GoblinRightStop();");  

goblincontrols.push();
}

function GoblinUp(%this)
{
Goblin.SetLinearVelocityY(7);
}

/*function GoblinDown()
{
Goblin.SetLinearVelocityY(-15);
}*/
function GoblinLeft()
{
Goblin.SetLinearVelocityX(-8);
}
function GoblinRight()
{
Goblin.SetLinearVelocityX(8);
}
function GoblinUpStop()
{
Goblin.SetLinearVelocityY(0);
}
function GoblinDownStop()
{
Goblin.SetLinearVelocityY(0);
}
function GoblinLeftStop()
{
Goblin.SetLinearVelocityX(0);
}
function GoblinRightStop()
{
Goblin.SetLinearVelocityX(0);
}

#1
07/02/2013 (12:33 pm)
One way to do it is to have a Global Variable (something like $Intheair).

The basic logic here is that when your character collides with the ground, set it to false

//This obviously means that you have a ground object named "The_Ground"

Goblin.onCollision(%this, %object, %collisionDetails)
{
//%this will be the Goblin
//%object will be the object we've collided with
//%collisionDetails will contain several details, impulses, vectors and the like

if(%object.getName() $= "The_Ground")
{
$IntheAir = false;
}

}

then, in your jump function (GoblinUp)
if(!$IntheAir)
{
//We are on the ground
Goblin.SetLinearVelocityY(7);
$IntheAir = true;
}


!Free Tip!

When you want to see if a specific variable is equal to a string, use $= as in

if(mystringvariable $= "Some Text")

using == to compare strings won't work, use it instead to compare values

if(myvariable == 5)
#2
07/02/2013 (12:46 pm)
I put the code in but I'm getting a parse error from my player.cs:

C:/Users/John/Documents/Torque Projects/FirstGame/modules/myModule/scripts/player.cs Line: 33 - parse error
>>> Advanced script error report.  Line 33.
>>> Some error context, with ## on sides of error halt:
    %player.createPolygonBoxCollisionShape();



    %player.setCollisionCallback( true );



    %player.setCollisionLayers(5);    

    %player.setDefaultFriction(0);

    

    

    myScene.add( %player );   

   

  

  }

  

Goblin.onCollision(%this, %object, %collisionDetails)  

{

##/##/%this will be the Goblin  

//%object will be the object we've collided with  

//%collisionDetails will contain several details, impulses, vectors and the like     

   

if(%object.getName() $= "floor")  

{  

$IntheAir = false;  

}  

  

}
#3
07/02/2013 (1:32 pm)
Try:
function Goblin::onCollision(%this, %object, %collisionDetails)

When defining a function, put function in front of it and use :: to separate the class name from the method name. When using a function, just use the object and a dot, then the method name ( %this.onCollision()). In your case it is a callback and you will probably never call this yourself....

Simon, I'm disappointed. ;p
#4
07/02/2013 (2:08 pm)
I changed it and now the .exe does run, but it just behaves as before, here is the player.cs:

function createPlayer()
{
    %player = new Sprite(Goblin);
    $Goblin = %player;

    %player.setBodyType( dynamic );
       
  
    %player.Position = "0 0";

      
    %player.Size = "7 7";
    
  
    %player.SceneLayer = 1;
    
    %player.Image = "myModule:goblin";

    %player.createPolygonBoxCollisionShape();

    %player.setCollisionCallback( true );

    %player.setCollisionLayers(5);    
    %player.setDefaultFriction(0);
    
    
    myScene.add( %player );   
   
  
  }
  
function Goblin::onCollision(%this, %object, %collisionDetails)  
{
//%this will be the Goblin  
//%object will be the object we've collided with  
//%collisionDetails will contain several details, impulses, vectors and the like     
if(%object.getName() $= "floor")  
{  
$IntheAir = false;  
}  
  
}
It's late, am I missing something obvious?
#5
07/02/2013 (4:06 pm)
Quote:I changed it and now the .exe does run, but it just behaves as before,

Do you mean it runs but your character doesn't jump?

I don't see the GoblinJump function, I assume it sets $IntheAir to true?

In any case, first check if the 'onCollision' is called when it's supposed to by adding an echo statement like so

function Goblin::onCollision(%this, %object, %collisionDetails)    
{
echo("Testing Testing Testing"); 
}

The results will show up in the console (CTRL+~) when the function is called.
#6
07/02/2013 (4:17 pm)
Did you name your ground "floor"?

Did you add the check for $IntheAir == false (or !$IntheAir) in your jump function, and then set it to true after jumping?
#7
07/02/2013 (4:47 pm)
I think I've got %this.OnCollision(); in the wrong place as the echo "Testing" isn't appearing in the console, where should I be putting %this.OnCollision();?
#8
07/02/2013 (4:51 pm)
You don't explicitly call the Goblin::onCollision() yourself, it just gets called whenever collisions are occurring.

Bear in mind that when first creating your object, you need to set it to trigger this function

Goblin.setCollisionCallback(true);

If you don't do this, the physical collisions will still happen (objects will bounce off each other) but the function, even if it exists, will never be called.
#9
07/02/2013 (5:00 pm)
Hmm I have %player.setCollisionCallback(true); already in my player.cs... Maybe my "floor" is incorrect?

Here's the script for the floor (levelone.cs):
function createFloor()
{
    %floor = new Sprite(floor);
    %floor.setBodyType(static);
    %floor.Position = "0 -35";
    %floor.Size = "100 10";
    %floor.Image = "myModule:floor";
    %floor.createPolygonBoxCollisionShape();
//    %floor.createEdgeCollisionShape( -50, -37.5, -50, 37.5 );
    %floor.setCollisionCallback( true );
    %floor.SceneLayer = 5;
    %floor.setDefaultRestitution(0.1);
    myScene.add(%floor);
#10
07/02/2013 (5:16 pm)
Two things that might help,

1- %floor.createPolygonBoxCollisionShape();

You should specify a width and height for your collision shape.

You can also call SandboxScene.setDebugOn("collision"); to show the collision shape outlines of your scene. (If you're not using the Sandbox, your Scene might have a different name)

2 - Setting Collision Callbacks for the floor will work but might be overkill, usually you only need the callback on one of the main objects.
#11
07/02/2013 (5:44 pm)
It worked! Thanks so much for your help guys.
#12
07/02/2013 (5:47 pm)
We'd love to see screenshots or videos of that Goblin some day! :)