Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

As mentioned by others, this is an excellent example. Three things though:

1. I tried attaching the last vertex of rope1 to an instance of oDrag, just like how the example attaches the first vertex of rope1 to an oDrag intances. While this works, I note the last vertex is not able to properly connect to the other oDrag instance - there is always a gap, unless both oDrag instances are very close to each other:



I tried fixing this by changing the stiffness, segments, and segments length, but I keep getting a gap. What I was hoping for was that the last vertex of the rope is connected to oDrag exactly like the first vertex. You can see this below, where green is for the first vertex, and red is for the last vertex: 



Is this just default behavior, or is it possible to make the last vertex's connection be just like the first vertex's?

2. Any stiffness under 1 (0.9 for example), causes the rope to droop drastically. Not sure if this is a bug (interestingly, when the rope droops like this, the last vertex seems to attach the way I want it to as I mentioned in point 1)?



3. Lets say I wanted to make something like a fishing line where the user is able to reel-in/retract the rope. Is there a way to do this? My assumption was that the rope properties, namely the number of segments and stiffness, would need to be changed, but those properties are called for creating the rope only, not to update it. Do you have a recommended approach? 

Thanks for any input you can provide!

(4 edits) (+1)

(Seems like I can't upload screenshots for some reason.. :c)

Problem 1:

The verlet system works by having a list of vertices and a list of sticks. Every update, we iterate through the list of vertices from the start, forcing the sticks to their original length. Since we're starting at the first vertex, its position will always be correct, but the rope will drag away from the last point as a result. One way to solve that might be to rewrite how we iterate through the list every update. So update the first vertex, then the last, then the second, second from last, etc. until we reach the center. I'm not sure if this will result in other unwanted behaviour though.

I'd manipulate this for loop and see what happens:

verletFunctions line 299:
for (var i = 0; i < stickAmount; i++) {
    currentStick = stickList[| i]; 

A simple and dirty "fix" would be to rewrite the draw function and draw another line from the last vertex to the point where it is supposed to be attached. It won't be perfect but it will look like it's attached.

verletFunctions line 497:
draw_vertex(currentStick.v2.x + lengthdir_x(wHalf, stickDir - 90), currentStick.v2.y + lengthdir_y(wHalf, stickDir - 90));
draw_vertex(currentStick.v2.x + lengthdir_x(wHalf, stickDir + 90), currentStick.v2.y + lengthdir_y(wHalf, stickDir + 90));
// Draw another line here
draw_primitive_end(); 

Problem 2:

When the verlet system updates, the "stiffness" is simply the amount of times we do the update. The more updates per frame, the more correct the simulation will be, but the more performace we draw.

verletFunctions line 294:
repeat (stiffness) {
    #region Update sticks
    #region Update vertices
} 

A stiffness value below 1 would therefore result in errors.

Problem 3:

That will be a difficult one.. I didn't think of a use case like this.

The sticks already have an individual length value. To retract the rope, you probably want to create some function that retracts the rope by one pixel. It would decrease the length of the first stick by 1 as long as the stick's length is greater than 1. A length of 0 would probably create errors. Otherwise delete the first stick and the first vertex, then continue with the next stick until the rope is gone.

New function for the rope group:
function retractRopeByOnePixel() {
    if (<amount of vertices> > 2 AND <amount of sticks> > 1) {
        var currentStick = <first stick>
        if (currentStick.length > 1) {
            currentStick.length --;
        } else {
            <delete first stick>
            <delete first vertex>
        }
    } else {
        return false;
    }
    return true;
} 

Something like that maybe. You'll need to figure out where to get the amount of ropes/sticks and where to delete them. Call the function until it returns false, then delete the rope.

Hope I could help :)

Thanks for the reply! I'll have to keep working with it to get a better grasp of it, but the info you've provided is much appreciated!