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

Shape based collision layer #538

Closed
obiot opened this issue Jul 23, 2014 · 19 comments
Closed

Shape based collision layer #538

obiot opened this issue Jul 23, 2014 · 19 comments
Milestone

Comments

@obiot
Copy link
Member

obiot commented Jul 23, 2014

Now that we have shapes object implementation, a spatial grid (quadtree) and a working SAT based collision detection algorithm, it should be quite straightforward to replace the current Tile based collision layer with a shape based one.

Allowing to directly "draw" the collision layer in Tiled using the shape tools, or to more easily manually modify the collision layer programmatically.

This will also automatically address the following tickets (that I will then close to gather everything here) :

Few points to consider :

  • collision shapes would be fully solid by default
  • it should be possible to define a one-way collision in any axis (to simulate the current platform property)

Targeting this for 1.2.0 !

@parasyte
Copy link
Collaborator

Literally just need to draw rectangles in Tiled for the ground an so on to get solid shapes. They just need to have zero gravity and infinite mass (cannot be moved by forces applied to it) The tricky part is defining the special shapes like platform, ladder, etc.

@obiot
Copy link
Member Author

obiot commented Jul 24, 2014

exactly ! For platform that's what I was having in mind when talking about a 1-way collision,as we could add some property to disable collision from the bottom for example to simulate a platform.

for ladder however, i'm not sure i will make it back, as it might be a better idea to implement it through an entity ?

anyway for all this, we need a better body physic that properly implement bounciness, mass, etc...

@obiot
Copy link
Member Author

obiot commented Sep 2, 2014

little brainstorming :)

in version 1.1.x and lower, we could add some property to a tile to specify the type of collision we wanted (solid, platform, etc...).

With 1.2.0 we will have a different collision system for the collision layer, and it's time to also rethink the way we manager this, and allow to define the same behaviour (like a "one-way" collision properties and/or specifying maybe only "authorised" collision angle ?).

so if you have any brilliant and simple idea, here is your opportunity to shine :):):)

@parasyte
Copy link
Collaborator

parasyte commented Sep 2, 2014

Tiled has a special "Poly Line" object type that could be used for special collision types like platforms. Collision angle seems like a good idea; it's just going to be a little math to make it happen. (The exact function, I don't know, yet. But it's for sure possible. Seems like it will be a unit vector that gets smaller (toward zero) as it angles away from its "origin" angle. Then multiply velocity by this collision angle... Or maybe just a half-circle...)

We could offer a few (?) named collision shapes, which simply resolve to the collision response vectors behind the scenes. That will simplify collision management greatly.

@obiot
Copy link
Member Author

obiot commented Sep 4, 2014

yes, and offering a few default collision shapes is yes probably a good idea (although I'm not sure how to specify custom shape in Tiled), specially to "solve" the platform one for example, and we could even add a rotation angle to it to offer the same as a one way door for example.

I'm still also unclear on my side on how to properly manage the collision shape layer, do we just add additional entities (tagged with the WORLD_SHAPE type, and maybe defining or enforcing special property like the mass to make them solid), or do we use a separate collision object group that would only define shape objects ? (as a reminder, the current implementation only check collision between object containing a body child)

Last but not least , found this blog entry full of very "must-read" links :
http://brm.io/game-physics-for-beginners/

@parasyte
Copy link
Collaborator

parasyte commented Sep 4, 2014

Well, that's kind of what I was describing when I mentioned "collision angle" ... it doesn't need to be defined as a unit vector; just an angle is enough, because we can convert that to the unit vector we need.

Collision layer should probably use the same convention we do today with the collision tile layer: create an object layer named "collision" and call it a day. Anything added to this layer will have a shape, which is enforced by the TMX spec.

And yes, the current collision checking is troublesome because it requires a body. I know Chipmunk-js has a "fake" body for static objects. We could just use the same kind of thing.

@obiot
Copy link
Member Author

obiot commented Sep 4, 2014

another bonus question : do we provide backward compatibility with the previous implementation (as it was done in ticket #103 i think), by converting the tiled collision into shape collision, or do we just drop it ?

@parasyte
Copy link
Collaborator

parasyte commented Sep 4, 2014

We can ... but I would rather drop it entirely. I don't want to keep a bunch of code around to maintain backward compatibility for deprecated features. I think it's a lot harder to do now that we are in a v1.x release version... It would be easily justifiable to drop it cold-turkey if we do major breaking changes in major version numbers.

@obiot
Copy link
Member Author

obiot commented Sep 4, 2014

good, we both agree then :)

@obiot
Copy link
Member Author

obiot commented Sep 4, 2014

I'm wondering if we should not release 1.2.0 as soon as this is one is done actually, as this is in my opinion, the big missing change on the 1.1.0 branch :)

@agmcleod
Copy link
Collaborator

agmcleod commented Sep 4, 2014

I think a quicker 1.2.0 to improve that kind of stuff is a good call. Keeps
people excited as well :)

On Thu, Sep 4, 2014 at 2:18 AM, Olivier Biot notifications@github.com
wrote:

I'm wondering if we should not release 1.2.0 as soon as this is one is
done actually, as this is in my opinion, the big missing change on the
1.1.0 branch :)


Reply to this email directly or view it on GitHub
#538 (comment).

Aaron McLeod
http://agmprojects.com

obiot added a commit that referenced this issue Sep 7, 2014
obiot added a commit that referenced this issue Sep 7, 2014
@obiot
Copy link
Member Author

obiot commented Sep 7, 2014

@agmcleod @parasyte

hi guys, this is ready for a first experimentation !

For Aaron, although we do not have yet something equivalent to the previous platform tile, as far as I saw you don't use it your LD entry. Also i added clearing of the jumping and falling flags (i'm not sure though we should keep them in the engine)

For parasyte, you can define collision area using polyline, and it's just working perfectly, which is exactly what is need for neverwell moor, no excuse not to upgrade:)

obiot added a commit that referenced this issue Sep 8, 2014
this fixes movements/walking on slopes (or non rectangular shapes)
obiot referenced this issue Sep 8, 2014
@agmcleod
Copy link
Collaborator

agmcleod commented Sep 8, 2014

Think I'll play with this tonight. Maybe it will help me get some bugs
sorted out :)

On Sun, Sep 7, 2014 at 1:59 AM, Olivier Biot notifications@github.com
wrote:

@agmcleod https://github.com/agmcleod @parasyte
https://github.com/parasyte

hi guys, this is ready for a first experimentation !

For Aaron, although we do not have yet something equivalent to the
previous platform tile, as far as I saw you don't use it your LD entry.
Also i added clearing of the jumping and falling flags (i'm not sure though
we should keep them in the engine)

For parasyte, you can define collision area using polyline, and it's just
working perfectly, which is exactly what is need for neverwell moor, no
excuse not to upgrade:)


Reply to this email directly or view it on GitHub
#538 (comment).

Aaron McLeod
http://agmprojects.com

@obiot
Copy link
Member Author

obiot commented Sep 9, 2014

Hi guys,

I was giving more thought on this collision angle idea, and I’m wondering if this would not create a bit too much complexity compared to what we want to achieve ? The example I had in mind was the one of a platform collision shape, and where only an angle of 0” is allowed on this one. What happened then if the player is coming form a 15” angle (and the end of a jumping curve) ?

My point being that this is not just as easy as it seems, and I would like to suggest an easier approach. Today we already have properties in rect object like top, bottom, left, and right (that people are familiar with), and I was wondering if we could not just use the same kind of approach. All directions would be true by default, and then it eases any calculation (like if up is disabled, do nothing if response.overlap.y <0 )

What do you think ?

@parasyte
Copy link
Collaborator

parasyte commented Sep 9, 2014

Hahaha! That's why I tried to describe "a unit vector that gets smaller ... or just a half-circle." The half-circle is definitely easier to implement. In other words, the shape only allows penetration if the angle of motion is within the range of "collision_angle +/- 90 degrees".

@parasyte
Copy link
Collaborator

parasyte commented Sep 9, 2014

And note that I only used "degrees" for illustration, since "90 degrees" is easier to visualize than "Pi/2 radians". It's the same value, but we need to use radians when working with angles in JavaScript.

@obiot
Copy link
Member Author

obiot commented Sep 9, 2014

hmm... I do not know why I overcomplicated it actually, and then yes an unit vector with a corresponding +-90 degrees range is simple enough 

Bonus question : in the context of providing a way to the end user to specify this directly in Tiled, how do we present that ? Shall we add some property shortuct like we had before (“platform=true”) , on top of a json formatted collisionAngle ? (anyway, with slope being managed through polygon, the main missing one compared to <1.1.0 is that one)

obiot added a commit that referenced this issue Sep 11, 2014
NOT WORKING, but that's all I will be able to do for today, so I prefer
to commit it as it for now.
obiot added a commit that referenced this issue Sep 21, 2014
also fixed the `angleTo` and `angleToPoint` functions
obiot added a commit that referenced this issue Sep 26, 2014
obiot added a commit that referenced this issue Sep 29, 2014
following discussion here :
d5dc2aa
8ea37733db
parasyte added a commit that referenced this issue Sep 29, 2014
- It is easier to subclass me.Entity, so let's put callbacks there.
parasyte added a commit that referenced this issue Sep 30, 2014
- No need to separate these two methods
- Also fixed the platform bounce with a more intelligent platform collision test
- And fixed the pushable spikes by removing the isSolid/isHeavy flags (pushable blocks can be implemented in the callback until we implement mass)
- TODO: There's a slight "bounce" when running into a wall head-on. It appears to be caused by the overlap calculation getting confused...
- TODO: Investigate a "fall through the world" bug that may be related to the overlap confusion; disable the velocity correction in respondToCollision (zero the velocity instead of calculate the delta) then after jumping into the pit, running straight into the first wall will almost always drop you through the floor.
parasyte added a commit that referenced this issue Sep 30, 2014
- This is why allowing collision response decisions in user code is awesome.
obiot added a commit that referenced this issue Oct 3, 2014
@parasyte
Copy link
Collaborator

parasyte commented Oct 5, 2014

@obiot This one looks done to me, now! On a side-note, there is a little "bounciness" in the sprite drawing when the player is standing on the highest platform in the second map! This is strictly within the drawing because it FLOORS the coordinates:

var x = ~~(_bounds.pos.x + (
this.anchorPoint.x * (_bounds.width - this.renderable.width)
));
var y = ~~(_bounds.pos.y + (
this.anchorPoint.y * (_bounds.height - this.renderable.height)
));
Change these to Math.round and it draws correctly as expected.

The cause is sub-pixel velocity from gravity applied every frame. At that specific Y-coordinate, the entity position jumps around between 16.999999999997 and 17.00000000007. The floor will obviously increase the magnitude of the "jumps" to 16 and 17; a whole pixel. Math.round will keep it at 17.

Closing this. We'll finish up in #574.

@parasyte parasyte closed this as completed Oct 5, 2014
@obiot
Copy link
Member Author

obiot commented Oct 5, 2014

i don't see any reason why we could not use Math.round then, except performances, as ~~ is faster... but with the performance improvements brought by the quadtree, I suppose that we could lose tiny bit of speed here

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

3 participants