9th July Update
Can you believe we’ve been doing these for two months? Crazy. To celebrate I’m going to be doing a rather technical update, which several people have told me that they wanted. So you’ll get everything, including badly drawn diagrams using my trackball, and my oddly disjoint ramblings.
Today, I finally got the grappling hook in the game, as in you spawn it and equip it and doesn’t crash or break or anything. But there’s many different glitches I need to fix before I can show you off. So for today’s update I thought I’d talk you guys through the logic of how it’s (already should, but doesn’t quite yet) operate.
As I mentioned before in various places, but many of you may not have yet seen. I’m basing the behavior against an old SNES game that very few people have heard of called “Umihara Kawase,” a game which I was introduced to back in 2004 by a TASVideos run.
So let’s talk about grappling hooks and the properties thereof. First off, let’s talk about how the stretch mechanics works. If you remember back to your physics class, we’re going to be using pretty much just the spring equation to calculate this. This is simply F = kx, where k is a constant that we’re going to define in a config file, and x is how far the rope is stretched from “rest.” Of course, you can make the rope’s rest length longer and shorter while you swing around. So all we need to do is calculate how long the rope is. Well… how do we do that? Especially considering that the rope might wind up going around blocks.
Well, we need to keep track of where the rope has bent around something, of course. So, let’s talk about what defines a corner point. Well, first it needs to be anchored to the block it’s curving around somehow, so it needs an anchor point, which is typically one of the corners of a specific block. But blocks share corners in a tile based world, so we need to know which block it’s curving around. Which means we need to keep track of a list of these pairs of values, one tile coordinate, and one spacial coordinate.
But the real source of complexity in this problem is the ability to add and remove blocks. Most other games that I’m aware of with an interesting and complicated grappling hook (Umihara Kawase, Worms, Hedgewars, I’m sure there are more than a few others), don’t have to worry about mutable terrain. We do. This means that at any time one of the blocks that an anchor point is sitting against can simply disappear. What happens then? Or what happens if a block is placed over the line?
Well, in the case of a block disappearing, we want to detect that and then move the anchor point toward the midpoint of the line formed by the previous and next anchor points. Unless the anchor point that disappeared was the hook. In that case we just want to break the connection and watch the poor sap plummet to his doom. Actually, I’m probably going to change that up a bit and just make gravity nom the hook, rather than making the line disappear, but right now I just want it good enough to get on the screen and start testing so I didn’t implement it.
After we flag the anchor point as moving (over the course of several frames) towards the midpoint, we also need to check the lines before and after to make sure that we didn’t accidentally drag the line into the wall as a result of the move. We also need to check to see if we’re close enough to the middle to remove the anchor point entirely and treat it as a straight shot through.
How about for the case where a block appears in our path? Well! That’s actually similar to (but not the same as) the case where you’re moving around and the line runs into the wall. So I can just write one set of rules to handle that.
If the path between point A and point B is blocked, we first must determine all of the tiles that it’s colliding with. Then figure out which one is the closest. This will be our working block. Now there’s two cases here. The first case is when you’re looking at the block face on, in which case you’re going to need to consider the two corners that you can see. The second case is looking at the tile edge on, which means you need to consider the two opposite corners.
We consider one side, then the other, which means that I eventually need to introduce a randomness element so it doesn’t consistently favor one path over the other. Anyway in the first case we try the left corner, and check to see if we can actually go around this way (by checking the tiles adjacent to the corner), then if that works, we repeat the algorithm until it returns that we made it (so we try to draw another line between the corner and the far point, discover that we’re travelling through the block again, and then aim at the other corner.) Additionally, there are some checks that prevent doubling back or doing otherwise impossible things. This is a rather crude depth first search through sort of an impromptu graph. I don’t even keep a visited list, those I might need to in future iterations of the code for reasons of not having infinite loops.
There also are other cases, for instance you’re swinging around a wall and your grapple pulls away from the wall, we need to detect that (by detecting that the angle formed is greater than 180 degrees.)
There are some more complicated bits, but it’s now 5AM in my part of the world, and I have to get up at 9AM to start work again on this stuff. Hopefully, we’ll be able to show this off in the next few days. Sorry, I jumped the gun a bit and promised Tiy that I was going to make a video on it when I got it done in a day or two (which was like 4 days ago…), I had some code problems that slowed me down dealing with unimplemented areas of C++11 that I expected to be there (specifically the function I wanted was std::deque::insert(DestInterator locationToInsert, SourceIterator begin, SourceIterator end); I expected it to return an iterator, because when you call insert on deques it invalidates all current iterators to the deque, but it didn’t, because it hadn’t been implemented yet.)
As far as what everyone else has been doing, I honestly have no clue. I’ve managed to wall myself off to work on this for a few days, and it’s been a bit stressful, but ultimately rewarding. This was really fun to work on, and thank you so much for your indulgence. And I hope this wasn’t too boring or frankly terrible oh my god I can’t believe you call that drawing what is wrong with you.