Thursday, April 7, 2011

It's a Trap!

Traps are essential for 2D games. They present a challenge for a player that can only be defeated by timing and patience, rather than reliance on gunpower.

I decided to build 3 different types of traps for Platform Hack. Moving Blocks, Spinning Blades, and Flame Turrets. Each of these uses slightly different technology to work, but since they were similar enough I crammed all the functionality into a single class, called Trap.



The Moving Block is the simplest type. Its basically just a moving tile that hurts the player on collision. Some games have blocks that "crush" the player, and can also provide solid collision from the other directions (top, sides). I decided against this type of falling block, since it would require implement a "crushing" system of player damage. Instead, if you touch the block from any direction, the player will be damaged. Good level design (encasing the falling block inside Impassible tiles) can be used in conjunction with the trap type to good effect.

The Collision is pretty simple:



The Update function contains the only interesting piece of logic, using Linear Interpolation to smoothly move up and then slam down as a funtion of the entire TrapTimer



The Spinning Blade is the next type of trap.

This uses slightly more advanced collision and update logic. Given the same TrapTimer, we do a full rotation of both the texture, and the Rotation Matrix thats use for pixel-based collision detection:

Update:



Collision:





Draw:



One of the "gotchas" of Translation matrices in XNA (or I guess any graphics framework), is being sure to multiple by a translation of the negative origin. Matrix.CreateTranslation(new Vector3(-p.Origin, 0.0f)) This is needed whenever the texture is rendered using an origin. You need to adjust the Translation Matrix in the same way, so that the collision detection is "synched" with the drawn texture.

The collision detection with rotation is right out of the XNA tutorial found here

Lastly, the most complex type of trap is the Flame Turret.

The Flame Turret is using both Beam collision and the particle system for effect.

Beam Collision:

The benefit of using beam collision is if you have something like bullets that travel quickly. If the bullet moves 30 pixels in a single update, is has the chance to pass right through an enemy without causing collision. a Beam object can be used to represent a "line segment" in order to do collision. Of course, you can always Draw the single dot as the bullet, it just uses the Beam object to do the collision.

Here's my Beam struct:



There are two vectors, A and B. There is also a list of coordinates between the beams, which can be calculated with the following method. Note: this may not be an optimal method, comments welcome.



A beam can represent either a bullet moving quickly across the screen, or a burst of flame shooting out of a trap turret.

We can determine if the beam hits a player (or enemy) using the following collision detection method (again, possibly not optimal):



The last piece of the puzzle is a method to get a bounding rectangle around the beam. You *always* need to do bounding rectangle collision before pixel-based collision.



We can check for collision between the player and the beam in the following way:



Finally, we want our Flame Turret to look cool. This can be done using Particle Effects.

The particle engine I've used is heavily modified from the Particle Sample. The details are a topic for another post.

But briefly, we spawn fire particles along the length of the beam:



That's pretty much it for simple traps. With good art and creative level design, you can turn these three features into some pretty dastardly challenges for the player.