Game Development Community

Movement-related bug

by Daniel McNeese · in Torque Game Builder · 06/19/2007 (11:00 pm) · 22 replies

I created a simple "playerMovement.cs" script to move the player's avatar in response to the arrow keys. The avatar is 32*32 pixels, and moved 32 pixels in the appropriate direction in response to each key press. It worked fine.

Then I improved the script, adding variables called "canMove" (boolean) and "direction" (string) which would be checked before moving the avatar to allow for better control. And then something odd started happening. Movement works normally as long as I only move left, right or down. But once I move up the avatar freezes, as though "canMove" were set to false. I used cut-and-paste (with appropriate modifications) multiple times to make sure that the various functions all worked the same, but to no avail.

Now here's were it gets really bad: I pulled the references to "canMove" and "direction" from the functions, but it still gives the same problem even though there's no longer a check to see if the avatar should move or not. Up still freezes the avatar, even though there's nothing left in the code that should cause this.

What's more, I've even started a fresh project and copied the "game.cs" and "playerMovement.cs" scripts to it and the avatar in the new project won't move at all (yes, I've assigned it the "player" class). It's as though TGB suddenly lost the ability to accept script changes at some point.

Here's my current "playerMovement.cs" script:

Quote:
function player::onLevelLoaded (%this, %scenegraph)
{
$player = %this;
$player.canMove = true;
$player.direction = "none";
$player.jumpX = 4;
$player.jumpY = 4;

moveMap.bindCmd(keyboard, "up", "playerMoveUp();", "playerMoveUpStop();");
moveMap.bindCmd(keyboard, "down", "playerMoveDown();", "playerMoveDownStop();");
moveMap.bindCmd(keyboard, "left", "playerMoveLeft();", "playerMoveLeftStop();");
moveMap.bindCmd(keyboard, "right", "playerMoveRight();", "playerMoveRightStop();");
}

function playerMoveUp()
{
{
%temp = $player.getPositionY();
$player.setPositionY(%temp - $player.jumpY);
}
}

function playerMoveDown()
{
{
%temp = $player.getPositionY();
$player.setPositionY(%temp + $player.jumpY);
}
}

function playerMoveLeft()
{
{
%temp = $player.getPositionX();
$player.setPositionX(%temp - $player.jumpX);
}
}

function playerMoveRight()
{
{
%temp = $player.getPositionX();
$player.setPositionX(%temp + $player.jumpX);
}
}

Any ideas what's going on, or how to fix it?
Page «Previous 1 2
#1
06/24/2007 (4:08 am)
Okay, I've purged everything from the computer and reinstalled multiple times, and I keep getting a "this installation is damaged, please reinstall" message every time. Nonetheless, TGB seems to work up to a point: when I try the PlayerFish movement script from the Fish Game demo, it works. But when I modify it to suit my purposes it fails. Can anyone tell me if there's something wrong with the following script:

Quote:
function player::onLevelLoaded(%this, %scenegraph)
{
$player = %this;
$player.jumpX = 4;
$player.jumpY = 4;

moveMap.bindCmd(keyboard, "w", "playerUp();", "playerUpStop();");
moveMap.bindCmd(keyboard, "s", "playerDown();", "playerDownStop();");
moveMap.bindCmd(keyboard, "a", "playerLeft();", "playerLeftStop();");
moveMap.bindCmd(keyboard, "d", "playerRight();", "playerRightStop();");
}

function playerUp()
{
%temp = $player.getPositionX() - $player.jumpX;
player.setPositionX(%temp);
}

function playerDown()
{
%temp = $player.getPositionX() + $player.jumpX;
player.setPositionX(%temp);
}

function playerLeft()
{
%temp = $player.getPositionY() - $player.jumpY;
player.setPositionY(%temp);
}

function playerRight()
{
%temp = $player.getPositionY() + $player.jumpY;
player.setPositionY(%temp);
}

function playerUpStop()
{
}

function playerDownStop()
{
}

function playerLeftStop()
{
}

function playerRightStop()
{
}



The object I want to move has been given the "player" class and game.cs has an exec command calling the script. Yet nothing happens when I try to move the player avatar.
#2
06/24/2007 (5:00 pm)
This is frustrating.

I pulled my copy of 1.5 and reinstalled 1.3 to test this in a stable environment. But my script is still not having any effect, even after stripping it down still further:

Quote:
function player::onLevelLoaded(%this, %scenegraph)
{
$player = %this;

moveMap.bindCmd(keyboard, "w", "playerUp();", "playerUpStop();");
moveMap.bindCmd(keyboard, "s", "playerDown();", "playerDownStop();");
moveMap.bindCmd(keyboard, "a", "playerLeft();", "playerLeftStop();");
moveMap.bindCmd(keyboard, "d", "playerRight();", "playerRightStop();");
}

function playerUp()
{
player.setPositionY(-4);
}

function playerDown()
{
player.setPositionY(4);
}

function playerLeft()
{
player.setPositionX(-4);
}

function playerRight()
{
player.setPositionX(4);
}

function playerUpStop()
{
}

function playerDownStop()
{
}

function playerLeftStop()
{
}

function playerRightStop()
{
}



Again, can anybody tell me why the Fish Game scripts work and this doesn't? Can someone confirm that this works on their computer?
#3
06/25/2007 (4:45 am)
Daniel

I am not much of a programmer but have you executed the player.cs script in game.cs ?

Just recheck it.

Someway the script is not getting executed I believe.
#4
06/25/2007 (8:02 am)
I would double check the exec like Sunny suggested.
#5
06/25/2007 (8:18 am)
Also when you try and move the player avatar in your test, hit the "~" (tilde) key to bring up the console... if it's running into any problems it will be displayed here. You can also look in the console (scroll up) for any red text that may represent a syntax error.
#6
06/25/2007 (8:20 am)
Just found your problem

player.setPositionY(-4);

should be


$player.setPositionY(-4);

You were referring to it as $player in some areas and player in others, since you stored it in the global variable $player then that is how you should refer to it.
#7
06/25/2007 (6:01 pm)
Sunny: Yes, I did just that - and checked the player avatar's class - several times. But thanks.

Matthew: Thanks, it works now. But while that explains why the second and third scripts I posted didn't work, it doesn't explain the problems I described in the original post.
#8
06/26/2007 (6:29 am)
Maybe because you have not yet mentioned the stop function.

Try giving the stop function and then check, maybe it is reading the script as incomplete and not executing.

Sorry cannot help much. Had only 8 programming classes in my life till now ;) lols
#9
06/26/2007 (7:05 am)
As long as the stop functions are there and properly defined, having them do nothing isn't a problem.

EDIT: Never mind, I see what you meant. I didn't have them in the first script.

But that still doesn't explain the exact problem I described... Why could I move left, right and down normally but get stuck when moving up?
#10
06/26/2007 (9:33 am)
Daniel I tried using your script, my player is not moving at all.

What name and class you gave for it ? Let me know so I can test for you.

BTW if this not a platform game but a game like pacman then be sure you have not applied any gravity and force to it which will pull it down thus making it stuck.
#11
06/26/2007 (9:37 am)
Could you post your current script you are running with, just in case it may be different from your original script now.
#12
06/27/2007 (1:38 am)
Matthew: Here's my current script, though I'm about to start adding the more complicated parts back in.

Quote:function player::onLevelLoaded(%this, %scenegraph)
{
$player = %this;
$player.jumpX = 4;
$player.jumpY = 4;

moveMap.bindCmd(keyboard, "w", "playerUp();", "playerUpStop();");
moveMap.bindCmd(keyboard, "s", "playerDown();", "playerDownStop();");
moveMap.bindCmd(keyboard, "a", "playerLeft();", "playerLeftStop();");
moveMap.bindCmd(keyboard, "d", "playerRight();", "playerRightStop();");
}

function playerUp()
{
%temp = $player.getPositionY() - $player.jumpY;
$player.setPositionY(%temp);
}

function playerDown()
{
%temp = $player.getPositionY() + $player.jumpY;
$player.setPositionY(%temp);
}

function playerLeft()
{
%temp = $player.getPositionX() - $player.jumpX;
$player.setPositionX(%temp);
}

function playerRight()
{
%temp = $player.getPositionX() + $player.jumpX;
$player.setPositionX(%temp);
}

function playerUpStop()
{
}

function playerDownStop()
{
}

function playerLeftStop()
{
}

function playerRightStop()
{
}

#13
06/27/2007 (4:44 am)
I'm trying to flesh out my movement script, but the timer I'm using doesn't seem to be working. Given that my player avatar has the "player" class, is refered to by the global variable "$player" and I have an integer value stored in "$player.delay" can someone confirm that I'm getting the following right:

1) To create a timer for the object, use:
Quote:$player.setTimerOn($player.delay);

2) To destroy the timer, use:
Quote:$player.setTimerOff();

3) To tell the object what to do whenever its own timer goes off, use:
Quote:function player::onTimer($player)
{
}
#14
06/27/2007 (4:48 am)
Function player::onTimer($player)
{
}

should be

function player::onTimer(%player)
{
}

don't know if globals will work on the object the function is called at all.
#15
06/27/2007 (5:11 am)
I just tried this, and it doesn't seem to help.

Here's the movement script as a whole:

Quote:function player::onLevelLoaded(%this, %scenegraph)
{
$player = %this;
$player.jumpX = 4;
$player.jumpY = 4;
$player.moveState = "move";
$player.direction = "none";
$player.delay = 200;

moveMap.bindCmd(keyboard, "w", "playerUp();", "playerUpStop();");
moveMap.bindCmd(keyboard, "s", "playerDown();", "playerDownStop();");
moveMap.bindCmd(keyboard, "a", "playerLeft();", "playerLeftStop();");
moveMap.bindCmd(keyboard, "d", "playerRight();", "playerRightStop();");
}

function playerUp()
{
if ($player.moveState == "move")
if (($player.direction == "up") or ($player.direction == "none"))
{
{
%temp = $player.getPositionY() - $player.jumpY;
$player.setPositionY(%temp);
$player.direction = "up";
$player.setTimerOn($player.delay);
$player.moveState = "delay";
}
}
}

function playerDown()
{
if ($player.moveState == "move")
if (($player.direction == "down") or ($player.direction == "none"))
{
{
%temp = $player.getPositionY() + $player.jumpY;
$player.setPositionY(%temp);
$player.direction = "down";
$player.setTimerOn($player.delay);
$player.moveState = "delay";
}
}
}

function playerLeft()
{
if ($player.moveState == "move")
if (($player.direction == "left") or ($player.direction == "none"))
{
{
%temp = $player.getPositionX() + $player.jumpX;
$player.setPositionX(%temp);
$player.direction = "left";
$player.setTimerOn($player.delay);
$player.moveState = "delay";
}
}
}

function playerRight()
{
if ($player.moveState == "move")
if (($player.direction == "right") or ($player.direction == "none"))
{
{
%temp = $player.getPositionX() + $player.jumpX;
$player.setPositionX(%temp);
$player.direction = "right";
$player.setTimerOn($player.delay);
$player.moveState = "delay";
}
}
}

function playerUpStop()
{
if ($player.direction == "up")
{
$player.moveState = "move";
$player.direction = "none";
$player.setTimerOff();
}
}

function playerDownStop()
{
if ($player.direction == "down")
{
$player.moveState = "move";
$player.direction = "none";
$player.setTimerOff();
}
}

function playerLeftStop()
{
if ($player.direction == "left")
{
$player.moveState = "move";
$player.direction = "none";
$player.setTimerOff();
}
}

function playerRightStop()
{
if ($player.direction == "right")
{
$player.moveState = "move";
$player.direction = "none";
$player.setTimerOff();
}
}

function player::onTimer(%player)
{
if ($player.moveState == "delay")
{
$player.moveState = "move";
}

else if ($player.direction == "up")
{
%temp = $player.getPositionY() - $player.jumpY;
$player.setPositionY(%temp);
}

else if ($player.direction == "down")
{
%temp = $player.getPositionY() + $player.jumpY;
$player.setPositionY(%temp);
}

else if ($player.direction == "left")
{
%temp = $player.getPositionX() - $player.jumpX;
$player.setPositionX(%temp);
}

else if ($player.direction == "right")
{
%temp = $player.getPositionX() + $player.jumpX;
$player.setPositionX(%temp);
}
}

On pressing and holding a direction key (a, s, d, f) the avatar should move once in that direction, hesitate briefly, then move rapidly until either that key is released or another one is pressed. At present the avatar moves once and then stops, though it will move again in response to another key press.
#16
06/27/2007 (5:50 am)


Something is wrong here, again. I just changed the jumpX and jumpY values to make sure I didn't have a repeat of my orginal problems, and apparently I do. The game seems to once again be ignoring changes to the script. I tried both raising jumpX and jumpY all the way to 50 and dropping them to 0, but the avatar still moves just like he did before.
#17
06/27/2007 (7:49 am)
One thing to note, when you run into a syntax error in script it will not re-compile the .dso... (when you run the engine it compiles all of your .cs script files into binary .dso files for efficiency, much like the Unreal engine does with packages) So if you have a syntax error that is probably what is halting it. To Find a syntax error, simply play your game, hit the "~" key and look for red text :) It will point out a syntax error it ran into.
#18
06/27/2007 (7:50 am)
Also a little more info, when it runs into the syntax error and doesn't recompile the .dso, that means it will use the previous .dso, so yo uwill get the effect of that file with the error not updating to your latest version.
#19
06/27/2007 (7:50 am)
Also another note, for posing code on this forum, you can use code tags, just like the quote ones, and it will preserve indenting.
#20
06/27/2007 (7:53 am)
One thing I see a lot of... here's an example:

else if ($player.direction == "right")
{
%temp = $player.getPositionX() + $player.jumpX;
$player.setPositionX(%temp);
}

When doing a string comparison in TorqueScript you need to use "$=" instead of "==". So you would change this to

else if ($player.direction $= "right")
{
   %temp = $player.getPositionX() + $player.jumpX;
   $player.setPositionX(%temp);
}

If you can all string comparison cases like this that may solve your problem
Page «Previous 1 2