Game Development Community

Suction/Pump -- Best Way to Do?

by Chris Jorgensen · in Torque Game Builder · 10/16/2006 (2:33 pm) · 9 replies

I'm working on a level for one of my levels in my space game. I've got this large "satellite" (for lack of better word) that I'd like to have floating around. Periodically, I'd like it to suck in from 2 of its pipes or pump out some green smoke out of its other 2 pipes. This much works. But my goal is to have the smoke push ships that run into it. And when the suction is on, have it so ships can get sucked into the satellite. What's the best way to do this?

There are really two issues here that I haven't found the idea solution for:

1- realistic suction/pump effect on the ships
2- finding ther ships to apply this effect to

For the latter case, I tried pickrect. But how could I repeatedly pick that area within a timespan? The satellite sucks/pumps alternating from anywhere between 5 to 15 seconds. So if it's sucking for 7 seconds, how to I constantly pickrect for this time without calling additional schedules of shorter intervals? Or would collision with an invisible sprite work better?

For the former case, in general i'm not sure what the best way to apply an external force to one of my ships is. For their thrusters, I use impulseForce. Is there something more ideal for these external forces?

Thanks!

#1
10/16/2006 (5:27 pm)
Ideally you would use triggers for the collison area, though I think they are somewhat broken for interacting with multiple objects right now. So some sort of hack with an invisible collision mesh would probably work, assuming you want an area more precise than pickRect gives.

As for the math, just do a t2dVectorSub between the point of suction/emission and the objects in the collision area. Normalise that vector and scale it however you want (based on distance?), and then add that vector into the physics for your object. You need to have a central area where your object's physics are being calculated to do that, like an onTimer or somesuch. So you could do something like
//In an onCollision callback after getting the vector you want.
%myShip.externalForce = t2dVectorAdd(%myShip.externalForce, %externalForceVector);

//And then in the onTimer
%linearVelocity = %this.getLinearVelocity();
%linearVelocity = t2dVectorAdd(%linearVelocity, %this.externalForce);
%this.setLinearVelocity(%linearVelocity);
%this.externalForce = "0 0";
And you'll want to centralize your normal input for the ship movement into the onTimer as well, so it can be mixed with the external forces.
#2
10/17/2006 (12:49 pm)
Oh, haha. For some reason I was thinking backwards on the timer. So that part works now, thanks to your comments. I'm using pickrect still at the moment, but I naively forgot that it won't rotate with the satellite that's pumping out gas. I guess the next step is to either get that to rotate, or try some invisible sprites for collision. Thanks!
#3
10/17/2006 (2:50 pm)
There is also a pickRadius that would probably be more suitable for your needs (with rect you get longer range from the corners).
#4
10/18/2006 (1:14 pm)
@Thomas

I've used pickradius before on a cheesey sort of "tractor ring" for a ship's special ability. As a weapon, it's not so hot. The thing with this satellite, however, is that it's basically a plus sign made out of pipes. My goal is to get the suction/pumping to go directly in/out of those pipes.

The satellite pipes are all as wide as the ships. My idea is that people can use the pumped gas to blow them away from the satellite very fast. But if the suction is on, then there's a danger of being sucked in and destroyed. So this thing increases the interactivity of the level by offering players a shield to hide behind, a way to get a temporary speed boost, and a place to avoid and/or put the opponent in danger.

The big thing I don't like about pick* is that I can't see where it's picking. It makes it slightly hard to debug. But I don't know of a better alternative. :)
#5
10/20/2006 (10:59 am)
I was just suggesting that if you need to pick an area around a point, pickRadius is probably a better sollution. I can't concieve why you would say pickRadius is not so hot if you're using pickRect as they both return the same thing.

As for visual representation, just use a scene object. Name the object and give it a low alpha so you can see through it and just resize and reposition it when you do a pick. The downside with this is that you will need a scene object for each pick and if youre doing multiple picks per frame it might become a pain.

Alternatively you could create a debug draw function that you optionally call every time you do a pick that just created and positioned/scaled/set blend on the scene objects for you and scheduled them each to be deleted after a certain time. That way you dont have to worry about keeping track of any of the objects and you will be able to see all the picks that you do.
#6
10/20/2006 (1:31 pm)
Oh I just meant the special tractor-ring didn't work so hot, not the pickradius function itself. I was just saying that I've used it before. Pickradius actually is pretty handy. I use it for some homing missile code as well. In that case, the missile goes toward whatever is closest within what it sees from pickradius.

Your last comment there has inspired me though. I think I'll put little red dots wherever the corners of the pickrect are, and use that to help me debug. That should be simple/fast. Your suggestions have inspired me -- Thanks!
#7
10/23/2006 (5:45 pm)
Okay, here's a quick update so people know what I did. This is very similar to a trick I use for weapons ports on my ships. Basically, I mounted a couple sprites (that I can toggle visibility on) onto the satellite. So, of course, they rotate properly with it. Then i just create a pickrect using those sprites' coordinates as the corners of the pick region.

Works pretty well thus far. :D
#8
10/23/2006 (6:48 pm)
You can't rotate a pick (meaning that your visual representation of where your pick actually is would be innacurate unless your ship is at 0 or 180 degrees, because it's only given the top left and bottom right corners). That's exactly why I was suggesting using pickRadius - because you wouldn't have to rotate it to get the same effect.

To give you an idea of whats happening wth pickRect when you rotate your object, here's a little diagram:
[Straight]
Corners:
*     *

*     *

Pick:
-------
|     |
|     |
-------

[Rotated ~45 degrees clockwise]
Corners:
    *

*       *

    *

Pick:
   --
   ||
   ||
   ||
   --

I hope this made sense.

Edit: Put the diagram in a [ code ] block so it formats properly.
#9
10/24/2006 (8:54 am)
@Thomas

I see what you're saying. That makes sense, actually. At times it seemed like my pick was too wide, despite my careful positioning of those points. I hadn't connected that scenario to certain angles yet. (Though last night I had a vague suspicion about the exact shape of my pickrect.) I think you're right in switching to pickradius. I'll just put 2 or three pickradius center points along the exhaust range of each pipe. That should still give me the line of suction/pumping. Actually, I could even do a step-wise amount of force applied depending on which point's radius is hit, which would be simpler than a little distance::force formula.

Thanks for the suggestion! Once this works, I can use a similar setup to give a ship a tractor beam instead of ring, which would be a lot more effective as well! :D