Game Development Community

Ship won't move...

by Duey Oxburger · in Torque Game Builder · 09/02/2008 (10:39 pm) · 6 replies

I'm having a problem getting my little space ship to move around in the 'Shooter' tutorial2.
Here is the way my player.cs file looks... any suggestions?:

function PlayerShip::onLevelLoaded(%this, %scenegraph)
function pShipUp()

{
// Store a reference to the player's ship in a global variable
$pShip = %this;

moveMap.bindCmd(keyboard, "up", "pShipUp();", "pShipUpStop();");
moveMap.bindCmd(keyboard, "down", "pShipDown();", "pShipDownStop();");
moveMap.bindCmd(keyboard, "left", "pShipLeft();", "pShipLeftStop();");
moveMap.bindCmd(keyboard, "right", "pShipRight();", "pShipRightStop();");
}

{
$pShip.moveUp = true;
$pShip.updateMovement();
}

function pShipDown()
{
$pShip.moveDown = true;
$pShip.updateMovement();
}

function pShipLeft()
{
$pShip.moveLeft = true;
$pShip.updateMovement();
}

function pShipRight()
{
$pShip.moveRight = true;
$pShip.updateMovement();
}

function pShipLeftStop()
{
$pShip.moveLeft = false;
$pShip.updateMovement();
}

function pShipRightStop()
{
$pShip.moveRight = false;
$pShip.updateMovement();
}

function pShipUpStop()
{
$pShip.moveUp = false;
$pShip.updateMovement();
}

function pShipDownStop()
{
$pShip.moveDown = false;
$pShip.updateMovement();
}

function PlayerShip::updateMovement(%this)
{
if (%this.moveLeft) {
%this.setLinearVelocityX( -$pShip.hSpeed );
}

if (%this.moveRight) {
%this.setLinearVelocityX( $pShip.hSpeed );
}

if (%this.moveUp) {
%this.setLinearVelocityY( -$pShip.vSpeed );
}

if (%this.moveDown) {
%this.setLinearVelocityY( $pShip.vSpeed );
}

if (!%this.moveLeft && !%this.moveRight) {
%this.setLinearVelocityX( 0 );
}

if (!%this.moveUp && !%this.moveDown) {
%this.setLinearVelocityY( 0 );
}
}

#1
09/02/2008 (10:47 pm)
Did you copy and paste the entire .cs file?
#2
09/02/2008 (11:43 pm)
Are you initializing $pShip.hSpeed?

It seems like your have your braces screwed up, but its hard to tell if that might have been a copy/paste error?

If you have a syntax error like that you should get errors with line numbers in the console, or if you use Torsion (highly recommended) it will tell you when you precompile your scripts.

By the way, you can put {code} {/code} around your code to make it a lot more readable, but replace {} with straight braces.
#3
09/03/2008 (6:33 pm)
Well here's the tutorial section in context:

---------------------------------------

Adding Player Input



We now have our sky set up, as well as our player's ship in the level. However, there isn't anything for a player to do in the game so far. This section of the tutorial deals with adding player input into the game.




First, we will give the player's ship the ability to move around the game world. First, to group the code related to the player ship, we need to give it a class. To do that, select the ship and go into the Edit tab. Once we are in our Edit tab we need to expand the Scripting rollout (as shown in Figure 2.13) and set the Class to PlayerShip




Figure 2.13




Now that you have set up your ship to have a class, we can write the code that tells the ship what to do. To start with, we are going to give our player the ability to move their ship around the screen. To do that, we need to save our level and do a little coding in a text editor. Save the level using the "Save" menu item under the "File" menu, name it level1.t2d, and make sure it is saved into the "game/data/levels" folder inside of your game's project folder.




Open the "game/gameScripts" folder in your project folder. This is where your game scripts should be located. This folder is where we will create all of our script files that make up our game. Create a text file in this folder and name it player.cs. Be sure that when you create your file you add that .cs extension so TGB will recognize it as a script file. Now you can open your newly created "player.cs" in any plain text editing program. If you remember we set our ship's class to "PlayerShip" so we are going to add the following function to player.cs:




function PlayerShip::onLevelLoaded(%this, %scenegraph)
{
// Store a reference to the player's ship in a global variable
$pShip = %this;

moveMap.bindCmd(keyboard, "up", "pShipUp();", "pShipUpStop();");
moveMap.bindCmd(keyboard, "down", "pShipDown();", "pShipDownStop();");
moveMap.bindCmd(keyboard, "left", "pShipLeft();", "pShipLeftStop();");
moveMap.bindCmd(keyboard, "right", "pShipRight();", "pShipRightStop();");
}



This function does two things. First, it sets up our script so that when you see $pShip in code, it refers to the player ship in the level. Secondly, it binds the arrow keys to some movement functions (that we haven't created yet); one function when the player presses down on the key, the other when they let up on the key.




Beginner Note: If you are editing script in a text editor such as wordpad or notepad, it is good to note that when you save your file to make sure that you are saving it as a .cs file. Oftentimes you can accidentally save a file as scriptFile.cs.txt - meaning that it is a text file. Make sure that your text editor recognizes your script files as such, or else they won't work when you try to run them.





Add this code right below the onLevelLoaded function:




function pShipUp()
{
$pShip.moveUp = true;
$pShip.updateMovement();
}

function pShipDown()
{
$pShip.moveDown = true;
$pShip.updateMovement();
}

function pShipLeft()
{
$pShip.moveLeft = true;
$pShip.updateMovement();
}

function pShipRight()
{
$pShip.moveRight = true;
$pShip.updateMovement();
}

function pShipLeftStop()
{
$pShip.moveLeft = false;
$pShip.updateMovement();
}

function pShipRightStop()
{
$pShip.moveRight = false;
$pShip.updateMovement();
}

function pShipUpStop()
{
$pShip.moveUp = false;
$pShip.updateMovement();
}

function pShipDownStop()
{
$pShip.moveDown = false;
$pShip.updateMovement();
}



These functions handle movement for the ship. Basically whenever your player presses a key, it accesses the appropriate movement function, sets a movement variable to "true", and accesses a new function called updateMovement(). The updateMovement() function looks like:




function PlayerShip::updateMovement(%this)
{
if (%this.moveLeft) {
%this.setLinearVelocityX( -$pShip.hSpeed );
}

if (%this.moveRight) {
%this.setLinearVelocityX( $pShip.hSpeed );
}

if (%this.moveUp) {
%this.setLinearVelocityY( -$pShip.vSpeed );
}

if (%this.moveDown) {
%this.setLinearVelocityY( $pShip.vSpeed );
}

if (!%this.moveLeft && !%this.moveRight) {
%this.setLinearVelocityX( 0 );
}

if (!%this.moveUp && !%this.moveDown) {
%this.setLinearVelocityY( 0 );
}
}



This update movement function is what makes the whole thing work. What it does is read the input given by any of the movement functions and decides which direction and speed to move the player. It also waits until a key is released and then stops the ship.




Now that we have our code completely written, we need to tell the engine to run player.cs when it runs the game. To do this, open the main.cs file in yourProjectName/game. When you get your file open, you need to find these lines of code:




// Exec game scripts
exec("./gameScripts/game.cs");



Once you have located those, add this line of code right below it:




exec("./gameScripts/player.cs");



This line of code tells your game to load the code that is in the player.cs file when the game starts.




Now I want to draw your attention to these lines of code that we wrote in our updateMovement function in our player.cs file:





%this.setLinearVelocityX( $pShip.hSpeed );
%this.setLinearVelocityY( -$pShip.vSpeed );



You will notice that we are setting our velocity to hSpeed and vSpeed, two variables that don't exist yet. We need to create these variables for our ship before our ship will move around. Luckily, the Level Builder has built in an easy way to add variables to an object.





First, you will need to open up your project in the Level Builder again and select your ship. Once you have your ship selected you need to go back into the edit tab and find the Dynamic Fields rollout at the bottom of the list (as shown in Figure 2.16). Note: You may need to resize your right panel, by dragging outwards, to see the plus button.




Figure 2.16



You will notice that the Dynamic Fields rollout only has two things to do, add a field name, and a value for that field. With this option, you can add any variables to any object and set their value. This is useful because when you are testing gameplay, it is a lot easier to tweak with values easily found in the Level Builder than to search through pages of code trying to find where you used your variables. For our ship, we will be adding the two variables we used to control the speed of the ship - hSpeed and vSpeed. Add a field for each of those variables and click the green plus sign to create it (as shown in Figure 2.18). I chose values of 100 and 80, respectively (as shown in Figure 2.17).






Figure 2.17 Figure 2.18




If for any reason you ever decided that you needed to delete a variable you had created in the dynamic field rollout, simply click on the red minus sign to delete it.





Now that we have our ship's code ready, it is time to test it! Click on the play button on the top bar (as shown in Figure 2.19) or go to PROJECT → RUN GAME.




Figure 2.19



Once you are inside your game, you should be moving around smoothly! If you aren't moving like you are supposed to be, make sure that your code matches mine and that your variables are named correctly. When you get your ship working, you may want to tweak your speeds to get something you are happy with, thanks to them being dynamic fields, they can be easily changed in the Level Builder.
#4
09/03/2008 (8:26 pm)
What did posting the whole tutorial accomplish? How does that help identify your bug? What would help is if you answer the questions I already posed to you.

1. Are you getting syntax errors when your scripts compile
2. If so, fix them first, if not, set a breakpoint in PlayerShip::updateMovement and step through it looking for bugs (eg. is $pShip.vSpeed/hSpeed uninitialized, is this.moveUp/Down/Left/Right always false).
#5
09/03/2008 (10:07 pm)
Where would I find the syntax error window?
#6
09/03/2008 (10:30 pm)
You can open the console while the game is running by the tilde key (~), you can open a sub-window that will show only script compilation errors by clicking on the small right arrow at the top left.

I highly recommend trying out Torsion as it will make finding errors a ton easier.