A beat 'em up/platforming/fighting game hybrid with an electro style. You can smack guys, attach their parts and get their abilities!
This is a technical article. If you're looking to make your own little brawler or just interested in how exactly the combat in Megabyte Punch works, this is for you.
Posted by DionReptile on Jan 31st, 2013
As you may know, Megabyte Punch is a smash-like game. As in, similarly to Super Smash Bros. series, it uses a damage system that increases knockback instead of plain ol' health bars that kill you off when depleted. Despite being a lot fun and very dynamic, the system hasn't really seen much use beyond companies looking to cash in on their vast amount of franchises. They don't normally build upon the system and probably think the popularity of the featured characters will sell the game (and they probably do). But we're not looking for that today, we're looking to make a fun game first and foremost.
In this article I'll explain how I implemented combat (specifically hits) in Megabyte Punch. It doesn't really assume the reader to have any knowledge of making games. Feel free to use this approach, create your own variation or maybe even improve on it.
To start off, we have hurtboxes and hitboxes. Hurtboxes indicate the volume where a fighter can get hit. For a hit to happen, the hitbox spawned by an attack must intersect with the hurtbox of an opponent. Hurtboxes can be shapes fit around the limbs of a fighter or maybe just a single square around the whole character. Both types are invisible, however, the more it fits the visual layer of the game, the more clear and fair it is to players.
Hitboxes are spawned by attacks. Heavily simplified, attacks have these attributes:
- attack animation //which animation to use
- duration //how long the attack should take
- hitbox //which hitbox to spawn
- hitbox position //the position to spawn the hitbox relative to the fighter's center
- hitbox spawn time //when to spawn said hitbox
Now, why the duration? Doesn't the animation already have a duration? Yes, it's optional, but it's nice to be able to tweak the exact duration without messing with the animation itself. This is easily done by setting the playback speed of your animation to it's original duration divided by the new duration. If you use this, you should also scale the spawn time of the hitbox similarly of course.
PROTIP: Give the animation of a powerful attack a relatively longer ending. This means that if you happen to miss it, you can get punished more easily, thus creating something known as a risk-reward tradeoff. Basically, it's fair and more exciting.
So we've spawned a hitbox and, miraculously, we hit something! We'll want a hit that sends our opponent flying. We use two attributes for that:
- hit power //the speed of the knockback
- hit angle //the direction at which the knockback occurs in degrees
First, we need to convert the angle to a direction with x and y components using the functions Sine and Cosine. Most libraries and engines already have these, often abbreviated to Sin and Cos (otherwise look them up). Do check if the functions want degrees or radians, if the latter, convert them by multiplying your angle by 180/PI. Feed your angle to Sin to get x and to Cos to get y, multiply both by the hit power. If you happen to be facing the other way, you can flip the x direction by multiplying it with -1.
hitDirection.x = Sin(angle)
hitdirection.y = Cos(angle)
hitVelocity = hitDirection * hitPower
As you can see, I'm using hitDirection and hitVelocity as 2D points (vectors). How can a point in space be a direction? Don't we need two points for that? Yes, but we do in fact have two points if we count the zero position. Draw a line from (0, 0) to for example (0.5, 0.5) and we have a direction. Now, we set the victim's velocity to hitVelocity and watch him fly.
We're not there yet though. There is no damage given and the knockback doesn't scale up. So to the hitbox, we add some more attributes:
- damage //damage inflicted on hit
- hit scaling //how much the knockback scales up with damage
With these we can have different attacks scale up differently (like a small punch always giving the same knockback and a big punch have high scaling knockback). To get the velocity of the hit we can go:
hitVelocity = hitDirection * (hitPower + hitScaling * victimDamage)
Make sure to add the hitbox damage to the damage of the victim before calculating the velocity so the attack has maximum effect.
This is all very basic and there is a lot more to be looked into such as stun, hit freeze (also known as hit lag), projectiles, making sure hitboxes hit once and hitboxes that do knockback outward from their center. Nevertheless I hope you've enjoyed this and maybe even learned something new.