Wednesday, April 13, 2011

Grapple Hook Revisited

There was a request to go into some more detail for the grapple hook. Original Post



So what I've done is taken a fresh copy of the Platformer 4.0 solution and added only the Grapple Hook stuff. The ZIP of the solution is attached below.

Basically, there are 3 new classes and some changes to Player.cs

The three new classes are in the GrappleHook Folder:

Collision.cs - This contains the core functions used "under the hood".
DrawPrimitives.cs - This class contains some functions used to draw various shapes. The main method used is DrawLine2.
Grapple.cs - This class contains the guts of the grapple hook logic outlined in the initial blog post

Changes to Player.cs:
There are some new member variables and a few methods. I tried to comment everything that was new with "GRAPPLE HOOK"

I also added WhitePixel.bmp to the Content/Sprites/Test folder. This is used to draw the line. (Also removed the music to cut down the size of the zip)

A few changes to the logic and style of the Grapple Hook:
1. The grapple hook "rope" will now shoot out 500 pixels at a rate of 2000, which is pretty much instant.

2. The grapple hook will stay extended as long as you hold the button (instead of collapsing back to 0). This makes it easier to attach.

3. You can't shoot the grapple hook if isOnGround = true. This makes use a little more natural and prevents the odd bug where you would attach and then the grapple curve would force you under the world or the tile below you.

4. The swing itself is slightly slower (using 2000 as the gravity constant).

Places for Improvement:
1. Some games have the grapple hook continually "shrink" while it is attached (Hook Champ, etc). This gives the player the feel that the grapple is "elastic". You could implement this by moving the player slighly "up" the rope every tick, and then re-calculating the Swing Curve. The hard part is getting the velocities right so the swing is smooth, since we're not using actual angular velocities / momentum, but the path of the pendulum curve.

2. Prevent the Grapple hook from attaching to horizontal walls. This would require a change to the GrappleCollision function (and the getLineCollision function), to only attach if the Grapple "hook" is colliding through the lower X plane, instead of the Y plane.

3. Better formulas for angular velocities entering and exiting the swing. Right now I'm using some cheap hacks (delta position -> velocity) to determine the initial and launch velocities when starting or exiting the grapple swing. Some real physics might make it feel a little smoother.

Download: GrappleExample.zip