Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm building a 2D space game where the player uses a chain to grab on to nearby asteroids. The asteroids move along a specific path with a constant velocity.

The chain has a maximum length L and doesn't break.

The player has an update function where it checks if the chain is attached to a asteroid. If it is attached it should make sure that the distance between the player and the specific asteroid should never exceed the maximum length L.

This is what the function looks like:

Player.prototype.update = function() {
    // ...

    if (this.grabbed) {
        var asteroid = this.grabbedAsteroid();
        if (this.distance(asteroid) > this.chain.length) {
            // Pull player
            // ...
        } else {
            this.position += this.velocity;
        }
    }
}

My question is how do I (realistically) simulate the chain pulling on the player?

The game uses the Euler method to calculate the velocity and position of the player. The velocity and position of the asteroid are given by an arbitrary function.

share|improve this question
1  
Usually chains don't stretch, unless they're made out of elastic material, which I don't suppose is the case. When a non-stretching chain is pulled, and the scenery is space, I bet it should look like a straight line. –  user1306322 Mar 2 '13 at 23:30
    
Is the chain simulated as a bunch of links or as a single object? –  sarahm Mar 3 '13 at 1:10
    
At the moment it's only 1 object, but after reading the answers from Cameron Fredman and Nathhan Goings, I will split the chain into 10 objects. –  Renamed Mark Mar 3 '13 at 2:00
    
Mark, assuming the chain doesn't collide with the asteroid, you only need one "segment" As long as you don't reach the maximum length, you can ignore the chain. edit see my comment on my answer. –  Nathan Goings Mar 3 '13 at 2:20

2 Answers 2

The easiest solution would be to utilize a 2D physics engine that supports chains (like Box2D), rather than rolling your own. Your question is tagged , so I suspect you might be interested in Box2dJS, a javascript implementation of Box2D. If you truly plan to roll your own 2D physics, however, I recommend you nonetheless take a look at the Box2D source code to see how chains/ropes are handled in that project.

Chains

A chain is a series of two or more connected links. The smaller and closer the links, the more flexible the chain. Box2D creates chains by treating them as a series of solid rectangles with each linked to the previous using a "revolute joint." A revolute joint attaches two objects by “pinning” them together at an anchor point which they may revolve around. Obviously, the more links in the chain, the more CPU intensive and the more rope-like the resulting behavior.

How to implement a physics engine that will simulate the behavior of revolute joints is non-trivial (hence the original suggestion to just use an existing 2D physics engine). (Here's a discussion on SE, "How do I build a 2D physics engine?") In any event, here's the revolute-joint code and their implementation of ropes to give you an idea.

share|improve this answer
    
Thanks! I will do some additional research into revolute joints. I'm mostly interested in how chains work, so I will try to replicate the physics within Box2D. It is mostly the impulse of the movement of one segment of the chain and then correcting all other segments of the chain, such that the length of all segments stay constant, which I didn't understand. –  Renamed Mark Mar 3 '13 at 1:52

There are several ways to solve this, easy and hard. The information you want to learn is tension physics. 1 2 3

I've drawn a diagram of the expected forces.

Tension Diagram

There are couple issues:

  • First, we're using a rigid system while conserving the energy, assuming the asteroid has infinite mass (meaning we don't affect it by moving it).
  • Second, position is always updated by velocity. (I removed your your else statement and moved the code down)

When your player reaches the edge of the chain, in this case, it is similar to a collision. I usually rotate the system so the Y axis/component is along the tension vector and the X axis/component is the remaining component.

Collision reaction

Some Pseudocode based on yours:

Player.prototype.update = function()
{
    // ...

    if (this.grabbed)
    {
        var asteroid = this.grabbedAsteroid();
        if (this.distance(asteroid) > this.chain.length)
        {
            // Begin pseudocode
            var chainVector:Vector = asteroid.position - this.position;  // Vector pointing to asteroid
            var playerRelativeVector:Vector = this.velocity; // Temporary vector that we are going to rotate forward and backward.

            // align component vectors along the tangent of the tension (i.e., remove rotation and align components to axis)
            playerRelativeVector.angle -= chainVector.angle; // (2)

            // Reverse Y component because chain is 'pulling' on it
            playerRelativeVector.Y *= -1;

            // Rotate the vector back into world coordinates
            playerRelativeVector.angle += chainVector.angle; // (3)

            // Update our velocity to reflect changes to system
            this.velocity = playerRelativeVector;
        }
    }
    this.position += this.velocity;
}

Note, this method will not work in high-energy or precision simulations as you are calculating the position after you have traveled past the length of the chain. If you were to anticipate the position, you would be calculating the position prior to reaching the length of the chain. The only way to perform this precisely is to use a sweep-test and calculate the moment the player reaches the maximum length, and modify the vector at that moment. (Extremely high energy systems would require a recursive sweep test >.<)

Finally, I've implemented one recursive sweep-test physics collision system and I absolutely despise it. I would suggest using Box2D as Cameron Fredman suggested.

share|improve this answer
    
I can now correctly spell ast e roid! –  Nathan Goings Mar 3 '13 at 1:45
    
There is a fundamental problem with this solution, because the player keeps all energy, it acts like it's inside a sphere bouncing around. In a real system the chain, asteroid, and player would absorb energies to swing about as well as rotate back and forth. At highly tangential velocities, it might look okay, but directly against the line of tension will cause a large "bounce" –  Nathan Goings Mar 3 '13 at 2:23
    
+1 for "I've implemented one recursive sweep-test physics collision system and I absolutely despise it." :) –  Cameron Fredman Mar 3 '13 at 2:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.