carson

Separate hitboxes for attack animations

6 posts in this topic

I am creating a platformer game where the player can attack enemies. I am currently using arcade physics, but would be willing to switch physics engines if need be. I would like to create hitboxes for my attacks that are separate from my player's hitbox (the player's sprite.body).

 

The following gif (taken from Super Smash Bros: Melee) shows what I am trying to achieve. In this image, Jigglypuff is performing an upwards attack. The yellow hitboxes (surrounding Jigglypuff's body), are Jigglypuff's hitbox. If any of these intersect with a hitbox from an enemy's attack, Jigglypuff will be hurt by that enemy's attack. The red oval(s) is the hitbox of Jigglypuff's attack. If it intersects with an enemy's body hitbox, they will be hit by her attack. (note: the yellow hitboxes are always on Jigglypuff's body. The red hitbox only appears briefly during this attack)

 

 

 lWnwC.gif

 

I have been able to make do so far with a single hitbox that changes during an attack by using:

sprite.body.setSize()

However, then I have to make the player invincible during attacks (so he doesn't take damage when his attack collides with an enemy). This strategy also causes problems when colliding with terrain.

 

Another important part about creating separate hitboxes would be creating multiple hitboxes for a single attack. Each hitbox could store information like damage dealt, knockback amount, knockback direction, etc. This would allow attacks to perform differently depending on which part connects with an enemy. For example, if a player did a sword swing, one hitbox could be on the sword hilt, and only do small damage and knockback, while another hitbox could be on the sword blade, and have higher damage and knockback. 

 

This image shows another character performing an attack with separate hitboxes for the hilt and blade area of his sword as described above:

vTa14.gif

 

I have seen some similar questions, and the obvious solution (having multiple physics bodies for one sprite) seems out of the question. Having seen a description of what I am trying to achieve, can anyone shed light on a way I could implement this? Create a group of empty sprites and use their bodies as the hitboxes? 

 

Thank you in advance.

 

 

Tom Atom and drhayes like this

Share this post


Link to post
Share on other sites

For anyone that comes across this same issue, here is the solution I came up with:

 

(this code is untested and somewhere between pseudo code and my actual implementation)

function create() {     // make the player     player = game.add.sprite(0,0,'mario');     // create a group for all the player's hitboxes     hitboxes = game.add.group();     // give all the hitboxes a physics body (I'm using arcade physics btw)     hitboxes.enableBody = true;     // make the hitboxes children of the player. They will now move with the player     player.addChild(hitboxes);     // create a "hitbox" (really just an empty sprite with a physics body)     var hitbox1 = hitboxes.create(0,0,null);     // set the size of the hitbox, and its position relative to the player     hitbox1.body.setSize(50, 50, player.width, player.height / 2);     // add some properties to the hitbox. These can be accessed later for use in calculations     hitbox1.name = "punch";     hitbox1.damage = 50;     hitbox1.knockbackDirection = 0.5;     hitbox1.knockbackAmt = 600;}// activate a hitbox by namefunction enableHitbox(hitboxName) {     // search all the hitboxes     for(var i = 0; i < hitboxes.children.length; i++){          // if we find the hitbox with the "name" specified          if(hitboxes.children[i].name === hitboxName){               // reset it               hitboxes.children[i].reset(0,0);          }     }}// disable all active hitboxesfunction disableAllHitboxes() {     hitboxes.forEachExists(function(hitbox) {          hitbox.kill();     });}

This implementation "deactivates" the hitboxes when they aren't in use by setting their "exists" property to false. (this is done with the hitbox.kill() function). When their "exists" property is false, their physics bodies are not included in the physics update loop, so any collision/overlap with them will not be possible. (This could also be beneficial to performance for 2 reasons: 1) you reuse hitboxes, so you aren't creating and destroying sprites every time you use an attack and 2) your game won't have to move them all and test them for collision/overlap every single frame)

 

I'm not sure if it's efficient or a good solution, but it seems to work. 

Sanju, drhayes, zazazayou and 1 other like this

Share this post


Link to post
Share on other sites

I see you posted this a few months ago.  Are you still using it or have you found something else to work better?  I'm going to give this a try on my own game and I will let you know how it goes for me and if I end up doing anything different.

Share this post


Link to post
Share on other sites

I got this to work.  I am pretty much using your code exactly and it does the job.  I'll tweak it later on to make it fit my games needs a bit better but for now this'll do while I figure out some other stuff.  Thanks for sharing this example!

Share this post


Link to post
Share on other sites

I know this is an old post, but I was wondering if I could get some info on this as well. I am working on a similar type game in my free time, and I can see how adding hitboxes would be a great thing, but do I need to add a collision or overlap event to the hitboxes in my update method, or do they automatically get added when you add a collision or update with the player? Also, how would I check to see which hitbox got activated during a hit? I am assuming something like this would work?

 

update: function() {
    this.game.physics.arcade.overlap(this.player.hitbox1, this.enemies, this.hitPlayer, null, this);
    this.game.physics.arcade.overlay(this.player.hitbox2, this.enemies, this.hitplayer, null, this);
}

hitPlayer: function(player, enemy) {
    this.player.damage(player.damage); //since you set hitbox1.damage = 50; when creating hitbox1
    //...
}

 Or am I way off? I could really use any help you can give. Thank you for the code snippets in previous replies here, I appreciate all the help.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.