Sensors and Triggers
by Kyle Harrison · in Torque 2D Beginner · 08/04/2014 (11:56 pm) · 39 replies
Ok, I've been spending way too much time on this and im reaching out for some help on this issue.
I'm using Torque2D 3.0, and I'm developing an Android game right this second.
I'm trying to setup a standard Trigger (or Sensor) that has the behaviour of when an object (Sprite ScenObject with a PolygonBoxCollisionShape) enters the Trigger object's space (or a ShapeVector SceneObject with a Sensor collision flag):
1. Physics do NOT happen
2. Callbacks are triggered on collision
The problem I have here is one of two scenarios:
1. With %myTrigger.Active set to true AND/OR CollisionShapeIsSensor set to false (or both properties ignored entirely), my Sprite SceneObject is being "pushed away" by the Trigger SceneObject as if it were a solid thing, BUT the Trigger or standard Collision callbacks (depending on the type of object) get triggered, and therefore allows my game to continue normally, but looks extremely awkward and horrible
(Demonstration of this effect: https://www.youtube.com/watch?v=W68IO6szjJw [placeholder graphics])
or
2. With %myTrigger.Active set to false AND/OR CollisionShapeIsSensor set to true, my Sprite and Trigger SceneObjects no longer push eachother away, but NONE of the collision callbacks ever get called. Therefore the game just ends immediately.
The gameplay is super simple at play: stay within the Trigger zone until a certain moment, as you enter or leave the trigger/sensor zone a global flag is set whether your safe or not. when that moment arrives to evaluate that flag and determins that you are safe, the Trigger/Sensor object and some visual elements are removed and respawned somewhere else, else end the game.
Everything I try, I get one of those two results. Either the game plays correctly (can enter the trigger zone with no resistance) but collisions never get triggered, OR the game has physics enabled and works against each-other but the collisions "kinda" work
Not sure how to proceed
I'm using Torque2D 3.0, and I'm developing an Android game right this second.
I'm trying to setup a standard Trigger (or Sensor) that has the behaviour of when an object (Sprite ScenObject with a PolygonBoxCollisionShape) enters the Trigger object's space (or a ShapeVector SceneObject with a Sensor collision flag):
1. Physics do NOT happen
2. Callbacks are triggered on collision
The problem I have here is one of two scenarios:
1. With %myTrigger.Active set to true AND/OR CollisionShapeIsSensor set to false (or both properties ignored entirely), my Sprite SceneObject is being "pushed away" by the Trigger SceneObject as if it were a solid thing, BUT the Trigger or standard Collision callbacks (depending on the type of object) get triggered, and therefore allows my game to continue normally, but looks extremely awkward and horrible
(Demonstration of this effect: https://www.youtube.com/watch?v=W68IO6szjJw [placeholder graphics])
or
2. With %myTrigger.Active set to false AND/OR CollisionShapeIsSensor set to true, my Sprite and Trigger SceneObjects no longer push eachother away, but NONE of the collision callbacks ever get called. Therefore the game just ends immediately.
The gameplay is super simple at play: stay within the Trigger zone until a certain moment, as you enter or leave the trigger/sensor zone a global flag is set whether your safe or not. when that moment arrives to evaluate that flag and determins that you are safe, the Trigger/Sensor object and some visual elements are removed and respawned somewhere else, else end the game.
Everything I try, I get one of those two results. Either the game plays correctly (can enter the trigger zone with no resistance) but collisions never get triggered, OR the game has physics enabled and works against each-other but the collisions "kinda" work
Not sure how to proceed
function spawnBird(%x, %y)
{
%sprBird = new Sprite(BirdPawn);
%sprBird.Position = %x SPC %y;
//%sprBird.setBodyType( static );
%sprBird.Image = "Bird:Bird";
%sprBird.Size = "7 8";
%sprBird.createPolygonBoxCollisionShape();
%sprBird.SceneGroup = 10;
myScene.add(%sprBird);
$birdObj = %sprBird;
}
function spawnWindow()
{
$SceneObjects[0] = null;
$SceneObjects[1] = null;
$windowActive = true;
// Purely aesthetic, a clear "window" is drawn, to be able to "fly through"
%window = new ShapeVector(Window);
%randomX = getRandom(-30, 30);
%randomY = getRandom(-30, 30);
%window.setPosition(%randomX SPC %randomY);
%window.setSize(0.1);
%window.setLineColor("0.5 1 1 1");
%window.setFillColor("0.5 1 1 0.5");
%window.setFillMode(true);
%window.setPolyPrimitive(4);
%window.setSceneGroup(4);
$SceneObjects[0] = %window;
myScene.add(%window);
// This should act as the implicit shape that the window ends up being at the time of the
// evaluation (size 20)
%trigger = new Trigger(WindowTrigger);
%trigger.setEnterCallback(true);
%trigger.setLeaveCallback(true);
%trigger.setPosition(%randomX SPC %randomY);
%trigger.setSize(20);
%index2 = %trigger.createPolygonBoxCollisionShape();
%trigger.setCollisionShapeDensity(%index2, 0);
%trigger.setCollisionShapeFriction(%index2, 0);
$SceneObjects[1] = %trigger;
myScene.add(%trigger);
}
/////////////////
//// This works only when the Trigger acts as a physics object.
//// That should not be...
/////////////////
function WindowTrigger::onEnter(%this, %object)
{
echo("================= OH EM GEE IT WORKS");
$inWindow = true;
}
function WindowTrigger::onLeave(%this, %object)
{
echo("================= HEY NO GET BACK HERE!");
$inWindow = false;
}
function Window::update(%this)
{
//echo("IN Window:" SPC $inWindow);
if(%this.getSize() < 20) {
%this.setSize(%this.getSize() + $speed);
} else {
// do evaluation check
if($inWindow) {
$windowActive = false;
$inWindow = false;
$score++;
echo("Score:" SPC $score);
if($score <= 3) {
$speed = 0.2;
} else if($score <= 6) {
$speed = 0.4;
} else if($score <= 8) {
$speed = 0.7;
} else if($score <= 10) {
$speed = 1.0;
} else if($score > 10) {
$speed = 2.0;
}
$SceneObjects0.safedelete();
$SceneObjects1.safedelete();
} else {
$gameState = "death";
}
}
}
#22
Next, the reason why the sensor was not registering a collision is because you setup a custom movement function for the bird using setPosition. For whatever reason, this is not cool in the Box2D physics simulation. I killed the bird update function and changed the onTouchDown callback to use:
To be honest (and no offense intended), I recoiled a bit in horror when I saw you implemented a 60ms game update loop in script. I personally prefer to drive things event-based. The engine does have callback hooks for tickable objects, onSceneUpdate for the Scene and onUpdate for SceneObjects. They have to be explicitly turned on though. As long as you are happy with the performance, how you script your game is up to you.
08/06/2014 (3:10 am)
Ok, I figured out the issue. First, the WindowTrigger object needs to be made a sensor. You had the setCollisionShapeIsSensor line commented out. The crazy physics studdering was because you were trying to move two solid objects on top of each other.Next, the reason why the sensor was not registering a collision is because you setup a custom movement function for the bird using setPosition. For whatever reason, this is not cool in the Box2D physics simulation. I killed the bird update function and changed the onTouchDown callback to use:
$birdObj.moveTo(%worldposition, 50);where 50 is the speed you want. Objects need to have a velocity for any type of collision response. That fixed everything.
To be honest (and no offense intended), I recoiled a bit in horror when I saw you implemented a 60ms game update loop in script. I personally prefer to drive things event-based. The engine does have callback hooks for tickable objects, onSceneUpdate for the Scene and onUpdate for SceneObjects. They have to be explicitly turned on though. As long as you are happy with the performance, how you script your game is up to you.
#23
And it's there - way down in the core of the engine. There is generally no reason to mess with it. Objects take care of themselves. Just tell them what to do and they'll be on their way....
If you really need a process to be monitored you can use a ScriptObject like so:
Technically, any SimObject child can be used like this since it is part of SimObject.
08/06/2014 (7:08 am)
Note - this looking for the "main loop" thing is pretty common with newcomers to Torque in general. I did it, too - 10 years ago. Mostly with people who have played with engine programming a little or are accustomed to much slimmer engines.And it's there - way down in the core of the engine. There is generally no reason to mess with it. Objects take care of themselves. Just tell them what to do and they'll be on their way....
If you really need a process to be monitored you can use a ScriptObject like so:
function myTimerFunc()
{
// do stuff
}
$TimerPeriod = 100; // ms
$TimerObj = new ScriptObject();
$TimerObj.startTimer("myTimerFunc", $TimerPeriod); // fire it up
...
$TimerObj.stopTimer(); // done
$TimerObj.safeDelete(); // clean upTechnically, any SimObject child can be used like this since it is part of SimObject.
#24
That said, why in hell does an interpolation animation (like I had) get ignored? Seems to me if two objects collide, they should collide, no?
Ya that's pretty much where I come from, working with a bunch of other engines, not seeing a loop kind of scared me and I had no idea what to do lol
Also, I understand the sensor was commented out, I left it in there to demonstrate that I had also tried that and it also failed ;)
But anyways, I can't wait to implement this. I can't wait to finally be rid of this bug!
08/06/2014 (7:54 am)
Oh geez no offense taken my friend! I'll be the first to admit how much of a greenhorn I am to Torque.That said, why in hell does an interpolation animation (like I had) get ignored? Seems to me if two objects collide, they should collide, no?
Ya that's pretty much where I come from, working with a bunch of other engines, not seeing a loop kind of scared me and I had no idea what to do lol
Also, I understand the sensor was commented out, I left it in there to demonstrate that I had also tried that and it also failed ;)
But anyways, I can't wait to implement this. I can't wait to finally be rid of this bug!
#25
Since T2D is open-sourced, users can implement this if they want to, even in TorqueScript!
08/06/2014 (8:05 am)
In the Box2D documentation, it states that collision shapes cannot shrink or grow. If that behavior is required, you have to kill/recreate the collision shape every step of the way.Since T2D is open-sourced, users can implement this if they want to, even in TorqueScript!
#26
Kyle, it is strange but I'm not sure if this is a bug or simply not following the route the Box2D library expects. In any case, T2D provides you with an interpolation animation in the form of the moveTo method. It's always good to use what the engine has built-in - saves time scripting it yourself! But I know as a new user to Torque it can be difficult to grasp just how much the engine can do for you at first, no worries! Feel free to post any questions here if you are wondering how to implement something for a game. The community here is happy to assist.
08/06/2014 (8:38 am)
Simon, I don't think this is a case of the trigger needing to shrink or grow - that stays at a constant size. What is curious here is that changing the position of an object does not cause a collision response if the new position is inside the collision shape of another object. I can see how that is non-intuitive.Kyle, it is strange but I'm not sure if this is a bug or simply not following the route the Box2D library expects. In any case, T2D provides you with an interpolation animation in the form of the moveTo method. It's always good to use what the engine has built-in - saves time scripting it yourself! But I know as a new user to Torque it can be difficult to grasp just how much the engine can do for you at first, no worries! Feel free to post any questions here if you are wondering how to implement something for a game. The community here is happy to assist.
#27
I have been quite successful "warping" objects about, but those objects don't collide with other objects - just react to mouse/touch interaction (my daughter's Nyan Cat game from my downloads page - below the picture, all script is provided). The thing that tripped me up is that particle emitters are scene objects and have mass too - and when you use joints to attach them to your object they cause Box2D to throw a tantrum. So I break the joints, move all objects, set their new velocities, and then recreate the joints (which I really probably don't need). Fortunately, it's a small number of operations and it's not very frequent so it causes no problems.
08/06/2014 (9:27 am)
And it's not just about what the engine can do for you, it's also about what the engine expects to do for you. This is what is weird about the movement thing. Box2D has expectations on how things will be done. Perhaps adding some code in setPosition() to force Box2D to update its world info could correct this?I have been quite successful "warping" objects about, but those objects don't collide with other objects - just react to mouse/touch interaction (my daughter's Nyan Cat game from my downloads page - below the picture, all script is provided). The thing that tripped me up is that particle emitters are scene objects and have mass too - and when you use joints to attach them to your object they cause Box2D to throw a tantrum. So I break the joints, move all objects, set their new velocities, and then recreate the joints (which I really probably don't need). Fortunately, it's a small number of operations and it's not very frequent so it causes no problems.
#28
Exactly. I mean, how was I to know setPosition would be the cause of the problem? It's not like I was trying my best to hit the lowest level functions to adjust coordinates, this is an engine provided function exposed to TorqueScript, and not unlike what other engines have allowed me to do in the past (even Flash)
@Mike
The only thing im missing with the moveTo, and the reason I did my own movement code, was the Easing and the need to allow constant touch to move the bird icon around the screen, followed in a "lazy" manner. What can I do to re-enable that and still allow collisions?
08/06/2014 (9:57 am)
@Richard "it's also about what the engine expects to do for you."Exactly. I mean, how was I to know setPosition would be the cause of the problem? It's not like I was trying my best to hit the lowest level functions to adjust coordinates, this is an engine provided function exposed to TorqueScript, and not unlike what other engines have allowed me to do in the past (even Flash)
@Mike
The only thing im missing with the moveTo, and the reason I did my own movement code, was the Easing and the need to allow constant touch to move the bird icon around the screen, followed in a "lazy" manner. What can I do to re-enable that and still allow collisions?
#29
08/06/2014 (11:54 am)
Yeah, and it is how it was done before the Box2D integration. Maybe it should be modified to perform the expected operation within Box2D's framework. Essentially, it would be nice if setPosition() did moveTo() but right now and then told Box2D to reconsider its reality.... lol
#30
08/06/2014 (1:23 pm)
@Kyle - constant touch is no problem, in addition to onTouchDown, put the same movement code in onTouchDragged. Easing is a bit more difficult since that would require source changes (barring something rigged up in script changing the velocity of the object). The SceneWindow camera has linear and sigmoid interpolation modes, might be possible to borrow that code...
#31
I've had a super busy 24 hours, but I wanted to quickly chime in and say Thank You. I got the Collisions working with constant touch, it works beautifully (and with a nice framerate of course)
I can now concentrate on the game itself, instead of this one bug. I should have come here sooner, this thing was a couple months of torment to me :\
Thank you all for your patience and help!
I Think despite this, Torque2D and I are going to be doing a few more projects together
08/07/2014 (8:15 am)
Hi guys,I've had a super busy 24 hours, but I wanted to quickly chime in and say Thank You. I got the Collisions working with constant touch, it works beautifully (and with a nice framerate of course)
I can now concentrate on the game itself, instead of this one bug. I should have come here sooner, this thing was a couple months of torment to me :\
Thank you all for your patience and help!
I Think despite this, Torque2D and I are going to be doing a few more projects together
#32
08/07/2014 (8:53 am)
The more familiar you become with it the more of what it has to offer you will see. T2D is a very powerful 2D engine and it's very nice to be able to leverage that power instead of building it all from scratch.
#33
I'll make a branch and drop this in there - probably doesn't really need to be part of the engine, but it is pretty handy and intuitive.
EDIT
And here it is.
The SimpleTrigger is a copy of Trigger. I added stuff to make it do things! The files are in engine/source/2d/sceneobject/ and there is a MoveToTriggerToy in modules to show it. Note that the onEnter() callback is called if the trigger recreates its shape while there is a collidable object within it. The toy echos to the console when the onEnter() is called so you'll have to watch it (or just trust me).
08/08/2014 (10:10 am)
Ok, I've got a "SimpleTrigger" object working. It creates its own collision shape automatically as a sensor, circle by default with a radius equal to the greater of width or height. On resize it recreates its shape to match. It has only two "shapes" - circle and box. Box matches the collision shape to the trigger size. Changing shape at run-time recreates the shape in its newly chosen type.I'll make a branch and drop this in there - probably doesn't really need to be part of the engine, but it is pretty handy and intuitive.
EDIT
And here it is.
The SimpleTrigger is a copy of Trigger. I added stuff to make it do things! The files are in engine/source/2d/sceneobject/ and there is a MoveToTriggerToy in modules to show it. Note that the onEnter() callback is called if the trigger recreates its shape while there is a collidable object within it. The toy echos to the console when the onEnter() is called so you'll have to watch it (or just trust me).
#34
I'll have to play with this....
08/10/2014 (9:59 am)
This morning it occurred to me that if I get the list of collision shapes (types, dimensions, etc) instead of clearing them I could make this support resizing of all attached collision shapes pretty easily. Local position is normalized so that doesn't need to change, but the weird thing would be figuring out how to pick scaling for circles (largest dimension? smallest? average?) or other non-box shapes.I'll have to play with this....
#35
08/13/2014 (2:07 am)
The daily graph shows last week's near above the level of resistance in the $33 place, variety aThe working variety, lines a and b, which has been in effect since delayed 2011, has benefit objectives in the $36 areaThe major 50% Fibonacci retracement level of resistance from the 2005 excellent at $56.77 is now at $38.06The long-term downtrend in the comparative efficiency, variety c, was damaged in early MayVolume on the large a couple weeks ago was very heavy and the OBV has shifted well above level of resistance at variety dWeekly OBV (not shown) is positive and above its calculated moving averageWhat It Means: For those looking for RS 3 Gold generate, the resources market is a natural position to convert, and the technological action in these two application shares indicates they have admiration potential that enhances their eye-catching results in.
#36
I am happy that my plight might in some way benefit the Engine in some small or large way. Thank you Richard for taking the time and inspiration to make the SimpleTrigger branch. I can't wait to check it out :) And thank you to everyone to helped me. Been difficult getting back to it, but it's nice to know I can concentrate on other aspects now.
Now to get the easing back...
08/20/2014 (12:18 am)
yay for spam @jiejiechu123 I am happy that my plight might in some way benefit the Engine in some small or large way. Thank you Richard for taking the time and inspiration to make the SimpleTrigger branch. I can't wait to check it out :) And thank you to everyone to helped me. Been difficult getting back to it, but it's nice to know I can concentrate on other aspects now.
Now to get the easing back...
#37
There's also an old TorqueScript resource for tweening - but this was made for the legacy engine, it would need some work to get it running under T2D MIT.
www.garagegames.com/community/resources/view/21480
08/20/2014 (1:53 am)
It shouldn't be too difficult to expand upon the MoveTo and RotateTo methods to add easing. Finding the time is always the hard part. :)There's also an old TorqueScript resource for tweening - but this was made for the legacy engine, it would need some work to get it running under T2D MIT.
www.garagegames.com/community/resources/view/21480
#38
08/20/2014 (7:41 am)
Twillex worked pretty much out of the box in T3D (minor tweaks), so it shouldn't take much to get it working in T2D MIT (if anything needs to be changed at all).
#39
08/27/2014 (2:07 pm)
Has anyone had a chance to run the SimpleTrigger through some tests? Like I said, it seemed to work for me but just because I didn't find a case to crash it doesn't mean there isn't one....
Kyle Harrison
I would absolutely appreciate that :D I'll be watching this thread like a hawk :)
Cheers!