How does the rope collision work in Umihara Kawase?

Started by nesrocks, October 25, 2017, 11:14:43 AM

Previous topic - Next topic

nesrocks

I'm looking into implementing rope physics in my game, like in the DOS game Worms, or like Umihara Kawase (SNES), sans the elasticity. So the rope is always straight, and bends around corners. But I'm baffled at how hard this is. Does anyone know how they did it in Umihara? Since my game is tile based it should be a good example. I'm not looking for a detailed technical analisys, I'm looking to know the concept behind it.

I've tried this approach that didn't work very well:
- Each frame I check several points of the rope for collision with tiles.
- Whenever a point is inside a tile I do a series of checks to find out which direction it was coming from so I can determine where to place the bend relative to the tile it is in.
- I check if the rope's pivot's X coordinate is smaller, the same or greater than the tile that had a collision. Then I check the angular velocity to see if it was clockwise or counter-clockwise, and based on that info I place the pivot on one of the four corners of the tile.
This caused several problems, first one is that sometimes it would collide with a wall of more than 1 tile and it would place the bend in the middle of the wall.
Another problem is that sometimes the angular velocity couldn't be trusted.



So, I thought of another approach:
- Check for collision on several points of the rope on every frame, but store their positions on a list. If it doesn't collide, this was the last good position for the rope.
- If the rope collides with a tile, I check the same point (based on array index) for its previous position to find out where it was coming from and expell it from the tile and create the bend on the closest tile corner to that point.

Just thinking about it this approach it seems better but it may also be problematic. Any ideas?

edit: forgot to mention, I'm making the game in game maker (full code mode). I'm not using physics. Not that it should matter, I'm just looking for how it was done in Umihara Kawase, in concept.

FAST6191

If you can find a book on mechanics that they teach to 16 year olds through first year engineering/physics students and go through the wire/rope parts, at least as far as pendulums (I don't know how many will have such a thing but it was common enough at one point in time) it will probably help you here.

In your case you have a light, inextensible wire connected to a fixed point and being acted upon by a. Any interaction only changes the length and the location of the fixed point (or more likely generates a new fixed point; were this programming school I would probably look at a doubly linked list, however if you reckon an array works and you can guarantee you are not going to overflow -- if rope has a max length or even a fixed length and then you can only interact ? times a tile you have a limit and can declare a fixed size array). Whether you do sticky rope (each new fixed point remains, or maybe remains until momentum vector passes normal to it and then gets deleted from the list/array and possibly generated anew if you are swinging back). Air resistance could also be one to consider, but I kind of like the worms model of a decay and ability to bring it all back in reverse by holding a direction. Equally if you want a more "one way" approach then you can take away total momentum/energy available as a function of rope length, any problems this causes for your game difficulty can usually be solved by also having a climb up rope function.

"- Whenever a point is inside a tile I do a series of checks to find out which direction it was coming from so I can determine where to place the bend relative to the tile it is in."

That seems like an odd way to set about it. I would probably combine the two concepts from the get go so you always have a momentum vector (mass * gravity which could be a fixed value and all tempered by initial direction (left is positive, right is negative) and a length value. Stick a frame counter since generation of fixed point and you can always calculate the expected location, reset said counter if the direction changes or if a new point needs to be generated and that sorts that part)

Something also to consider. Design your levels/puzzles accordingly. Many years ago I was playing with the duke nukem 3d level editors. The help/release notes said no mirrors facing each other, so I of course did just that immediately and got a crash. So you can have mirrors in the game, just not facing each other. In your case maybe rather than having a jagged rock have everything be 90 degrees, 0 degrees and 45 (and maybe 30 and 60 if you want a bit of variation) to save having to do multiple calculations. You might even be able to reduce that to a lookup table or simple enough for a run of if-else multiplication (albeit likely floating point). Similarly you can use level/game design to restrict silliness -- I would bounce on a worms ninja rope for hours just for fun but if my turns are 90 seconds then it changes what I might do.

Why a collision check? Surely this is the almost textbook situation for a hitbox or world model approach.

nesrocks

Quite a lengthy post, I'll give it a better read later, but I already have a pendulum movement going. I even have the rope bending and unbending, and at first glance it would even seem to be fully working as intended, but quickly a bug happens in the logic and the rope bends very weirdly. So I knew I had to be doing something wrong on the concept level, as it was hard to debug.

jonk

I'm assuming you are talking about a situation after the hookshot has grabbed something and now a swing-event has started. I'm also assuming you don't need a discussion about what happens before the hookshot has formed at attachment point at its end and also don't need a discussion about controls that may vary the length of the rope. You've already got all that handled and are just looking for what to do once the opposite end attachment point is set and the rope is now in motion along the arc of a swing. I'm also going to assume that the rope starts out moving through tiles that are "air," because you've already done all those checks in the first place.

It seems to me that if you merely kept a list of vertical line segments only (or horizontal line segments only) for all tile edges where the edges are a border between a solid and air tile, that finding the intercept between the current rope "line" and any of these edge lines should be quite easy. Sorting will help a great deal here in the "search" to save time. The closest intercept tells you which segment to care about and the highest endpoint of that segment tells you exactly where the rope makes a vertex and from this you can tell how much time would have passed (how much of a frame as a %.) With that vertex now as the current "attachment point" you can now subtract the hypotenuse from the original length of the rope and begin the process again finishing up with the remaining % of the frame time to add more swing angle and see if there are new intercepts from there.

I've never considered this before and that just pops out as an approach, perhaps not fully considered.

I'm thinking that you could easily combine multiple tile edges into a single segment, where possible, to reduce the number of segments in memory to manage. Also, there may be a need to keep separate vertical and horizontal segment lists.

Some other ideas are to "sweep out" tiles between the starting point rope (which must obviously pass through tiles that are "air") and the ending point rope (after a frame advance.) You'd leave the times that the starting point rope passed through as unmarked but mark all the others in the area between the two positions (including the tiles penetrated by the ending rope in the frame.) Then examine just those tiles.

Another way is to consider all the vertices of your solid tile areas (and there are lots of ways of arranging this) to see if they are present inside the swept area of the rope swing, frame to frame (which must be a triangle.) If any vertices are inside the triangle, then you know that there was an "event" you need to solve. If not, fine.

But I don't really know what your game structures look like, so it's hard to make specific suggestions. Hopefully, the above provides some starting thoughts to discuss, though.
An equal right to an opinion isn't a right to an equal opinion. -- 1995, me
Saying religion is the source of morality is like saying a squirrel is the source of acorns.  -- 2002, me

tvtoon

If you pay attention to the game, you will see that the sprite is relocated often while plunging the walls. As a puzzle game, you can also conceive that most enemies won't give a collision trouble to the environment: they move slowly, often trough the same plane.

I don't know the internal working but I doubt you would have to build something state intensive. ;)