Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hitbox vs Circle collision issue #313

Closed
AbelToy opened this issue Sep 5, 2014 · 15 comments
Closed

Hitbox vs Circle collision issue #313

AbelToy opened this issue Sep 5, 2014 · 15 comments
Milestone

Comments

@AbelToy
Copy link
Contributor

AbelToy commented Sep 5, 2014

As detailed here, which includes a minimal code example, hitbox vs circle have weird collision issues.

I think it has to do with the origin, but I'm not really sure.

Here's the message I made: http://forum.haxepunk.com/index.php?topic=836.msg3200#msg3200

@sad-pixel
Copy link

Fixed.
I've changed Player.hx to use HXP values instead of hard-coded ones.
It works fine now. On both Neko and Flash targets.

Heres a Diff and the Code

@ibilon Please close issue

@dstrekelj
Copy link

I had no success fixing the issue with the solution @ishands provided. However, I set up a few test cases and came up with my own. The following code was successfully tested on Neko and Flash targets using Haxe 3.1.3 and HaxePunk 2.5.3. A complete list of library versions present on my machine, as well as a more detailed post, can be found on the relevant HaxePunk forum topic.

There seems to be an issue with the way offsets are handled for the default entity hitbox. While visually correct when in debug mode, the collision logic does not take into account any existing offset introduced to the hitbox through the setHitbox() method, or originX and originY parameters of the player-extended Entity class. At least not in the case presented by @Rolpege.

In order to mend this, I simply created a new Hitbox mask and set it as the player entity's mask. With this change, collision detection for this use case worked as expected. In short:

_sprite = Image.createRect(53, 33, 0xFFFFFF);
_sprite.originX = 27;
_sprite.originY = 33;
graphic = _sprite;
mask = new Hitbox(53, 33, -27, -33);

You can see the difference between my Player class and the original here.

@AbelToy
Copy link
Contributor Author

AbelToy commented Sep 6, 2014

Hey @ibilon! @ishands said to close the issue, but do not close it yet, as it's not solved.

@ishands - your code only fixes the demo itself. Not the issue. And in a wrong way. Changing the origin of the hitbox on the fly... why? That would break the code for my game in so many ways.

@dstrekelj 's code does work, but just for Hitbox vs Circle. Setting the mask this way will work for Circles, but Grids apparently use originX and originY reversed. So, -27 and -33 would have to be changed to 27 and 33. Which would not work

So... the collision system should have to be reworked in order for it to be consistent with all the masks available

@sad-pixel
Copy link

@Rolpege @ibilon @dstrekelj : This is an important issue, it seems. Disregard my previous comment, please.

It 100% agree that the collision system should be reworked. This is an easy fix, and should not take much time to do this.

We could just have code like this: (pseudo)

...
originX = (-1) * originX;
originY = (-1) * originY;
...

inside of the Grid's constructor.

@AbelToy
Copy link
Contributor Author

AbelToy commented Sep 6, 2014

This would break old code, though.

I think the issue is deeper and a fair amount of code restructuring needs to be done... :(

@sad-pixel
Copy link

@HaxePunk: Add to milestone? Preferably 3.0.0 or 2.6.x

@bendmorris
Copy link
Member

@MattTuttle or @ibilon may be able to comment on this more - but I'm pretty sure that a complete overhaul of the collision system is already planned for 3.0.0 and is going to be necessary due to the many other changes.

@ibilon
Copy link
Contributor

ibilon commented Sep 6, 2014

Yes a lot of change for the collision system are already planned for 3.0 so (and that's true for other subsystems) a restructuring will go to the version 3. I'll create an issue on that note in the next minutes.

If I understand the problem it's that different masks handle origin differently, correct?

@Rolpege did you manage to "fix it" in your code? or just some parts?
There's probably a reason you did it that way and it would probably be annoying to change but a solution would be to not use origin for a mask.

@ibilon
Copy link
Contributor

ibilon commented Sep 6, 2014

You can participate into the discussion on the next version of the collision system here: #314

@AbelToy
Copy link
Contributor Author

AbelToy commented Sep 6, 2014

@ibilon - yeah, I guess I will have to ditch the offset somehow. It's a bit annoying because it made calculations easier for the player, but as apparently there's no easy workaround I will have to do it.

I'm thinking I'll probably offset the boss' mask itself. Even if it's wrong when visualizing the mask, just offset it so it interacts correctly with the player... this would make stuff easier. I'll see!

Thanks though, really appreciate it :) - hopefully this is sort of a push to make the collision overhaul happen faster!

@AbelToy
Copy link
Contributor Author

AbelToy commented Sep 6, 2014

I ended up fixing the code by myself, because I had to change too many things in the game if not.

I just replaced Circle's collideMask with this one, which takes into account the parent's origin:

override function collideMask(other:Mask):Bool 
{
    var distanceX = Math.abs(_parent.x + _x - other._parent.x + other._parent.originX - other._parent.width * 0.5);
    var distanceY = Math.abs(_parent.y + _y - other._parent.y + other._parent.originY - other._parent.height * 0.5);

    if (distanceX > other._parent.width * 0.5 + radius || distanceY > other._parent.height * 0.5 + radius)
    {
        return false;
    }
    if (distanceX <= other._parent.width * 0.5 || distanceY <= other._parent.height * 0.5)
    {
        return true;
    }

    var distanceToCornerX = (distanceX - other._parent.width * 0.5);
    var distanceToCornerY = (distanceY - other._parent.height * 0.5);
    var distanceToCorner = distanceToCornerX * distanceToCornerX + distanceToCornerY * distanceToCornerY;

    return distanceToCorner <= _squaredRadius;
}

@azrafe7
Copy link
Member

azrafe7 commented Oct 2, 2014

@HaxePunk Can we merge @Rolpege fix for circle vs mask (it seems the right way to solve it for 2.5.4)?

Also @Rolpege... am I correct in saying that grid vs mask works fine but is rendered wrong (originX/Y aren't taken into account in Grid.debugDraw)?

We should probably add originX/Y to the calcs in Polygon mask too.

@AbelToy
Copy link
Contributor Author

AbelToy commented Oct 2, 2014

@azrafe7 - I think so, but haven't tested recently so I can't fully remember.

And yeah, Polygon mask also needs this :P

@ibilon
Copy link
Contributor

ibilon commented Oct 3, 2014

@azrafe7 Looks good so I guess yeah

@ibilon ibilon mentioned this issue Oct 3, 2014
3 tasks
@ibilon ibilon added this to the Version 2.5.4 milestone Oct 7, 2014
@ibilon
Copy link
Contributor

ibilon commented Oct 7, 2014

Closing this issue since it has been added to the #321 todo list.

@ibilon ibilon closed this as completed Oct 7, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants