onUpdate() function
by Brandon Fenty · in Torque 2D Beginner · 04/02/2014 (3:17 pm) · 11 replies
I'm trying to write a movement script that updates on every tick.I think the way to do this is to use the onUpdate() function. essentially:
assuming I've calculated the position updates based on key presses, how would I implement this?
(I can't find the documentation for onUpdate() anywhere, so if you could even just link me to documentation that'd be great!)
function onUpdate(%this)
{
%this.owner.newPosX = %this.owner.oldPosX + (%this.right - %this.left);
%this.owner.newPosY = %this.owner.oldPosY + (%this.up - %this.down);
%newPos = %this.owner.newPosX SPC %this.owner.newPosY;
%this.owner.setPosition(%newPos);
%this.owner.oldPosX = %this.owner.getPositionX();
%this.owner.oldPosY = %this.owner.getPositionY();
}assuming I've calculated the position updates based on key presses, how would I implement this?
(I can't find the documentation for onUpdate() anywhere, so if you could even just link me to documentation that'd be great!)
#2
How would you move a camera to follow a character on screen?
04/02/2014 (7:14 pm)
ok. never worked with a physics-based engine before, just having to relearn everything.How would you move a camera to follow a character on screen?
#3
SceneObject = the sceneobject to mount the camera to
offset = "0 5" would make the camera follow the object but be offset 5 units in the y direction, above the object.
MountForce = Physics force governing how fast the camera follows the object. A high number would follow it precisely, a lower number would lag behind
SendToMount = Boolean value, true or false. If true, the camera automatically snaps to the desired position. If false, it will move to the position according to MountForce.
MountAngle = Angle at which the camera is mounted to SceneObject.
Take a look at SceneWindow_Scriptbinding.h, all camera functions are in there.
04/02/2014 (8:28 pm)
There is a function for mounting a camera to any sceneobject, calculating lag and offsets.MySceneWindow.mount(Sceneobject, offsetx/y, MountForce , SendToMount , MountAngle);The parameters are as follow
SceneObject = the sceneobject to mount the camera to
offset = "0 5" would make the camera follow the object but be offset 5 units in the y direction, above the object.
MountForce = Physics force governing how fast the camera follows the object. A high number would follow it precisely, a lower number would lag behind
SendToMount = Boolean value, true or false. If true, the camera automatically snaps to the desired position. If false, it will move to the position according to MountForce.
MountAngle = Angle at which the camera is mounted to SceneObject.
Take a look at SceneWindow_Scriptbinding.h, all camera functions are in there.
#4
04/02/2014 (8:36 pm)
Thanks for being so patient with me with my questions, this is very helpful! Is there something I should be reading for help here? I've read many of the github documentation pages, but it's difficult to search and the fact that there are two versions of Torque2d (the open and non-open source versions) make google searches very difficult to follow. Any suggestions so I don't have to run to the forum here every time I have a little confusion?
#5
2. The best source of documentation is the Github wiki and this forum. 95% of the other stuff out on the internet is probably from the older commercial engine.
3. As Simon mentioned, either looking through each ScriptBinding file in the source, or looking at the TorqueScript reference guide on the wiki will help you understand what functions are available to you from script. Now, that won't clearly tell you that camera functions, for example, are found in the SceneWindow class - so until we have more tutorials that guide newcomers along - please ask here.
4. To one of your original questions, there isn't really any good documentation on callbacks at the moment. One of the weaker areas of the docs that needs to be addressed. SceneObjects, and all classes that inherit from it, have onUpdate, onCollision, onWake, and onSleep. You can even create your own callback with the startTimer/stopTimer methods (base function of SimObjects).
@param callbackFunction The name of the callback function to call for each timer repetition.
@param timePeriod The period of time (in milliseconds) between each callback.
@param repeat The number of times the timer should repeat. If not specified or zero then it will run infinitely
As practicing01 mentioned, with any timer or the onUpdate callback, you need to be careful what kind of code is being regularly performed, how many objects have such a callback, and how often it is being performed. It's very easy to grind your game to a halt performance-wise this way.
04/02/2014 (9:52 pm)
1. Don't worry about having to run to the forums when you have a questions. We're here to help! Plus chances are someone else down the road will have the same question, so you've indirectly helped them as well if they find your thread.2. The best source of documentation is the Github wiki and this forum. 95% of the other stuff out on the internet is probably from the older commercial engine.
3. As Simon mentioned, either looking through each ScriptBinding file in the source, or looking at the TorqueScript reference guide on the wiki will help you understand what functions are available to you from script. Now, that won't clearly tell you that camera functions, for example, are found in the SceneWindow class - so until we have more tutorials that guide newcomers along - please ask here.
4. To one of your original questions, there isn't really any good documentation on callbacks at the moment. One of the weaker areas of the docs that needs to be addressed. SceneObjects, and all classes that inherit from it, have onUpdate, onCollision, onWake, and onSleep. You can even create your own callback with the startTimer/stopTimer methods (base function of SimObjects).
MySceneObject.startTimer(callbackFunction, timePeriod, repeat);
@param callbackFunction The name of the callback function to call for each timer repetition.
@param timePeriod The period of time (in milliseconds) between each callback.
@param repeat The number of times the timer should repeat. If not specified or zero then it will run infinitely
As practicing01 mentioned, with any timer or the onUpdate callback, you need to be careful what kind of code is being regularly performed, how many objects have such a callback, and how often it is being performed. It's very easy to grind your game to a halt performance-wise this way.
#6
I know this is moving well away from my original question now, but I'm finding that my character will eventually grind to a halt if I just hold the arrow key down, like there's friction hitting him. Is there a way to turn that off? I tried turning friction off for the object but it didn't seem to change anything. Is there something I'm missing?
04/03/2014 (12:25 pm)
Thanks for the help. I found that enabling physics caused my hero to rotate around crazily when he collided with anything, which produced some undesired results and was the prime reason I was avoiding physics. Then I found the %hero.FixedAngle = true; and that made it stop spinning while still colliding correctly. Problem solved!I know this is moving well away from my original question now, but I'm finding that my character will eventually grind to a halt if I just hold the arrow key down, like there's friction hitting him. Is there a way to turn that off? I tried turning friction off for the object but it didn't seem to change anything. Is there something I'm missing?
#7
04/03/2014 (9:54 pm)
What script method did you use exactly? There's two possible settings: LinearDamping -> if this value is greater than 0, then your object will slow down regardless of whether it is colliding with something, and DefaultFriction -> sets the general friction value between collision shapes.
#8
04/04/2014 (1:08 pm)
I used both LinearDamping and DefaultFriction. Neither changed the slowdown.
#9
04/04/2014 (3:18 pm)
It would probably help to see your movement code if you don't mind sharing it. Although objects losing velocity must be seeing some sort of damping or friction, very strange. The more you can show of your scripts, the better.
#10
Here's the behavior script I'm using for movement:
04/04/2014 (3:22 pm)
Sure thing! Yeah I should have just done that from the start.Here's the behavior script I'm using for movement:
//Platformer controls
if (!isObject(PlatformControlsBehavior))
{
%template = new BehaviorTemplate(PlatformControlsBehavior);
%template.friendlyName = "Platformer Controls";
%template.behaviorType = "Input";
%template.description = "Platformer style movement control";
%template.addBehaviorField(jumpKey, "Key to bind to jumping", keybind, "keyboard space");
%template.addBehaviorField(leftKey, "Key to bind to left movement", keybind, "keyboard left");
%template.addBehaviorField(rightKey, "Key to bind to right movement", keybind, "keyboard right");
//Speed setup
%speed = 10;
%template.addBehaviorField(verticalSpeed, "Speed when moving vertically", float, %speed);
%template.addBehaviorField(horizontalSpeed, "Speed when moving horizontally", float, %speed);
%template.addBehaviorField(jump, "whether or not we're jumping", bool, false);
}
function PlatformControlsBehavior::onBehaviorAdd(%this)
{
if (!isObject(GlobalActionMap))
return;
GlobalActionMap.bindObj(getWord(%this.jumpKey, 0), getWord(%this.jumpKey, 1), "jump", %this);
GlobalActionMap.bindObj(getWord(%this.leftKey, 0), getWord(%this.leftKey, 1), "moveLeft", %this);
GlobalActionMap.bindObj(getWord(%this.rightKey, 0), getWord(%this.rightKey, 1), "moveRight", %this);
%this.up = 0;
%this.down = 0;
%this.left = 0;
%this.right = 0;
}
function PlatformControlsBehavior::onBehaviorRemove(%this)
{
if (!isObject(GlobalActionMap))
return;
%this.owner.disableUpdateCallback();
GlobalActionMap.unbindObj(getWord(%this.upKey, 0), getWord(%this.upKey, 1), %this);
GlobalActionMap.unbindObj(getWord(%this.downKey, 0), getWord(%this.downKey, 1), %this);
GlobalActionMap.unbindObj(getWord(%this.leftKey, 0), getWord(%this.leftKey, 1), %this);
GlobalActionMap.unbindObj(getWord(%this.rightKey, 0), getWord(%this.rightKey, 1), %this);
%this.up = 0;
%this.down = 0;
%this.left = 0;
%this.right = 0;
}
function PlatformControlsBehavior::updateMovement(%this)
{
if(%this.override)
return;
//Move
%flip = %this.right - %this.left < 0;
%this.owner.setFlipX(%flip);
%this.owner.setLinearVelocityX((%this.right - %this.left) * %this.horizontalSpeed);
//update Animation
if(%this.right == %this.left)
%this.owner.anim = "ZombieAssets:zombie1Stand";
%this.owner.PlayAnimation(%this.owner.anim);
}
function PlatformControlsBehavior::jump(%this, %val)
{
if (%this.override)
return;
//If we're able to, jump!
%this.owner.setLinearVelocityY(10);
%this.jump = true;
%this.schedule(%this.jumpTimer, "stopJump");
%this.updateMovement();
%this.blockControls(true);
}
function PlatformControlsBehavior::moveLeft(%this, %val)
{
%this.left = %val;
%this.owner.anim = "ZombieAssets:zombie1Anim";
%this.updateMovement();
}
function PlatformControlsBehavior::moveRight(%this, %val)
{
%this.right = %val;
%this.owner.anim = "ZombieAssets:zombie1Anim";
%this.updateMovement();
}
function PlatformControlsBehavior::blockControls(%this, %val)
{
%this.override = %val;
}
function PlatformControlsBehavior::onCollision(%this, %object, %collisionDetails)
{
%this.blockControls(false);
%this.updateMovement();
}
#11
My objects (ignore the named frame stuff if you aren't using the development branch):
04/04/2014 (11:08 pm)
I tested your behavior and when I turned gravity on, I could get a slowdown between the moving object and the ground. I set the default friction of both the object and the ground to 0 and that got rid of the slowdown. As long as one of the 2 objects that are colliding have zero friction, then there will be no slowdown.My objects (ignore the named frame stuff if you aren't using the development branch):
<SceneObject
SceneLayer="5"
Size="100 2"
Position="0 -4"
BodyType="static"
DefaultFriction="0" >
<SceneObject.CollisionShapes>
<Polygon>
<Point>-50 -1</Point>
<Point>50 -1</Point>
<Point>50 1</Point>
<Point>-50 1</Point>
</Polygon>
</SceneObject.CollisionShapes>
</SceneObject><Sprite
SceneLayer="5"
Size="6 6"
Image="NamedFrameToy:Images"
NamedFrame="playerShip1_red"
DefaultFriction="0" >
<Sprite.Behaviors>
<PlatformControlsBehavior />
</Sprite.Behaviors>
<Sprite.CollisionShapes>
<Polygon>
<Point>-3 -3</Point>
<Point>3 -3</Point>
<Point>3 3</Point>
<Point>-3 3</Point>
</Polygon>
</Sprite.CollisionShapes>
</Sprite>
Torque Owner practicing01
MourningDoveSoft
%Sprite=new Sprite() { class="Class_Sprite"; }; %Sprite.setUpdateCallback(true); function Class_Sprite::onUpdate(%this) { echo(%this.class); }onUpdate will cause lag. Movement should be done through box2d physics and callbacks.