Swinging ropes? [More importantly, additional hitboxes]


(John Andersson) #1

So, I want to implement swinging ropes. I get that if the player collides with the rope, then he should be in a “stuck” state which can only be changed by jumping. While he’s “stuck”, his x and y will depend on the rope and on what contact point he is on.

However, how the hell should I

a) Make swinging ropes without having to animate it, a.k.a make them swing dynamically? b) determine the contact point and make the hero follow it?

I basically want a good rope system, any ideas?


(JP Mortiboys) #2

Have the rope represented as a chain of line segments. For animation use verlet integration. Rope should maintain an array (or linked list, whatever) of “attached” entities, each with its corresponding linear position. When the Rope is updated, it should automatically move its attached entities to their new position.

For collision - keep the bounding box of the rope updated to make things quicker. Iterate each segment, test collision - if it collides then calculate the exact offset (or just just the midpoint of the segment - see if that looks good enough). Store the overall linear position (e.g. if each segment is 5 pixels long and the collision is the midpoint of the 3rd segment, the offset is 5*(0.5+3-1).

Dammit… I want to program this now. Shame I’m at work.


(John Andersson) #3

Interesting. I hope I was pro enough to take your advice and do something of it, but I don’t even know how to do verlet integration (had to google it :P). Here are some questions:

  1. How do I do verlet integration in flashpunk?

  2. How do I see what entities are “attached”? I had this problem with water tiles before (I wanted to detect the top tiles of an ocean) but never got to a solution.

I tried understanding the collision logic, but I couldn’t. So maybe I can do something like this:

If the player collides with segment 5, then segment 5 moves more than the other segments. Segment 4 and 6 move a bit slower, 3 and 7 even slower etc. So the rope has its wavy animation depending on where the player is colliding. Unless my approach is worse than yours.


(Zachary Lewis) #4

You can greatly reduce the problem if you copy the way swinging ropes were handled in Donkey Kong Country.

Notice how when the player collides with the rope (starting at 4:00), they slide down to a “lock point” on the rope regardless of where they touch it. Doing something like this will greatly reduce the complexity of the calculations needed, since the player’s original distance from the anchor point of the rope is a constant.

If you want to accurately model the way ropes hang, you’ll also want to do some reading on catenary curves.

If you just want to fake it, a simple line segment would provide a believable rope swing (since applying enough force to one end of an anchored catenary would effectively pull it taught). Think about a kid on a swing. When he’s swinging, the chains look straight, but after he leaps off, the chains arc.

Let me know if any of these approaches and shortcuts sound helpful, and I may be able to provide additional help.


(John Andersson) #5

Good advice. I’m gonna try to do the advanced rope first (to learn more advanced programming), but if that doesn’t work out all that well, then I’ll try your approach! I’ll update the thread when I get something going :smile:


(John Andersson) #6

Okay, so I tried to do the advanced one, and I failed miserably.

I’ll try to do the donkey kong country ropes, but one question: How should I go about rotating the rope when the player collides on it? I am using pixel graphics and it will probably look really bad if I rotate it… Don’t tell me I have to manually animate the ropes and then set the hitboxes for every frame.

Also, how should I go about adding an anchor point? An additional hitbox? How do I add another hitbox? I’ve seen some threads but I didn’t understand how to do it


(John Andersson) #7

Pretty please, help me add addtitional hitboxes. I’ve wanted to know for long. Many parts of my game will be improved if I know this.


(John Andersson) #8

Anyone? Additional hitboxes? please?


(JP Mortiboys) #9

Set the entity’s mask to an instance of Masklist, and call add to add more hitboxes to it.


(John Andersson) #10

how do I do that? not sure what I should type before add


(Jacob Albano) #11

http://useflashpunk.net/docs/net/flashpunk/masks/Masklist.html


(John Andersson) #12

I can’t really understand those types of documents,

add	()	method
public function add(mask:Mask):Mask
Adds a Mask to the list.

Parameters

mask:Mask — The Mask to add.
Returns
Mask — The added Mask.

should I just type add? or masklist.add? I’m confused


(Zachary Lewis) #13

This is the documentation for the Masklist class.

Here you can see that the class is called Masklist and it inherrits from the Mask class. That means a Masklist can be used wherever you’d use a Mask.

Under the Public Methods section, it describes all the public methods available to the Masklist class. With the add() function, it shows that it takes a Mask as an argument and returns that Mask.

So, we know the following so far:

  1. we can use a Masklist wherever we’d use a Mask.
  2. We can use the add() function to add a Mask to the Masklist.

So, if we have a character with a weird shape, we want to use a few hitboxes.

We know from the documentation for Hitbox, we know that a Hitbox is a Mask, so we can add a Hitbox to a Masklist.

public class StrangeShape extends Entity
{
  function StrangeShape(x:int, y:int)
  {
    // Create the hitboxes for collision.
    var h1:Hitbox = new Hitbox(10, 6, 0, 0);
    var h2:Hitbox = new Hitbox(20, 10, 0, 6);
    var h3:Hitbox = new Hitbox(4, 12, 8, 16);

    // Add the hitboxes to a masklist.

    // Hitboxes can be added in the constructor if you wish.
    var m:Masklist = new Masklist(h1, h2);

    // Or, you could add them manually.
    m.add(h3);

    type = "strange";

    // Now, we can pass the Masklist to the parent Entity to assign it.
    super(x, y, STRANGE_SHAPE, m);
  }
}

At this point, we can create one of these guys and check collision against the type strange. A collision will only occur if it collides with any Hitbox contained in the Masklist.

Make sense?


(John Andersson) #14

I love you zach, however, to make me in love with you, how do I check for collisions with one of the many hitboxes only? :slight_smile:


(Zachary Lewis) #15

You gotta’ make a few changes to the class to expose the hitboxes. Check it.

public class StrangeShape extends Entity
{

  public var h1:Hitbox;
  public var h2:Hitbox;
  public var h3:Hitbox;

  function StrangeShape(x:int, y:int)
  {
    // Create the hitboxes for collision.
    h1 = new Hitbox(10, 6, 0, 0);
    h2 = new Hitbox(20, 10, 0, 6);
    h3 = new Hitbox(4, 12, 8, 16);

    // Add the hitboxes to a masklist.

    // Hitboxes can be added in the constructor if you wish.
    var m:Masklist = new Masklist(h1, h2);

    // Or, you could add them manually.
    m.add(h3);

    type = "strange";

    // Now, we can pass the Masklist to the parent Entity to assign it.
    super(x, y, STRANGE_SHAPE, m);
  }
}

Now, to check collision against just the bottom “column” part of a StrangeShape, you can run a collision check from the hitbox of an entity against the corresponding hitbox.

if (player.mask.collide(myStrangeShape.h3))
{
  // There has been a collision. Handle it.
}

(John Andersson) #16

Interesting, but I can’t seem to get “if (player.mask.collide(myStrangeShape.h3))” to work,

my class is called manBob, but if I type manBob.h3, then it doesn’t even come up. I tried

if (player.mask.collide(h3)) trace("test");

but it never traces even when it’s inside the hitbox!