cocos2d / cocos2d-objc

Cocos2d for iOS and OS X, built using Objective-C
http://www.cocos2d-objc.org
Other
4.07k stars 1.16k forks source link

Setting CCPhysicsBody velocity to a high value doesn't evaluate collisions #547

Closed tanis2000 closed 10 years ago

tanis2000 commented 10 years ago

I tried setting the velocity of a CCPhysicsBody to a high value and I noticed that the body goes through other bodies without triggering a collision.

Is this the expected behavior?

If so, is there a way to keep the body at a constant high speed without it accelerating (I need to keep it at a constant speed and able of flipping direction instantly without building a force against the current direction) and evaluating collision at the same time?

Ben-G commented 10 years ago

I'm not an expert on this and are waiting on some feedback from Scott. However, setting the velocity to a constant value in the update method is probably not the way to go.

A quick solution that works for me is applying a force in the update method, when the current velocity is below the target velocity. I apply a very large force and setup an initial velocity. This combined definitely makes the movement look authentic and collision detection work. Not sure how good this would work for instantly flipping directions. Here's the snippet (I know it feels hacky):

if (_hero.physicsBody.velocity.x < _baseSpeed) {
    [_hero.physicsBody applyForce:ccp(10000.f, _hero.physicsBody.force.y)];
}
tanis2000 commented 10 years ago

I tried that but it doesn't really do what I want. There still is a delay and the body still ends up inside polyline shapes due to the high force applied.

I might be mistaking but it looks like Chipmunk isn't doing continuos collision detection.. but I might be completely wrong. I suppose that the collision detection algorithm involves ray casting as well so that it knows if a body is going to go through another due to its velocity, but maybe it's not triggering the collision delegate.

Birkemose commented 10 years ago

Chipmunk is not doing continous collisions, as it is rather CPU heavy, so fast moving objects will move through other objects, without the physics knowing. If you throw one of the spheres in the newton cradle in helloworld, you will easily be able to throw it outside the screen.

Normally it is not that big a problem though. I personally create a "special" physics object in the games I have written, which does a ray cast based on object speed and frame interval. That way I can predict a collision within the next frame. If there is a collision, I trigger my own callback, which handles it. Very low overhead, as you rarely have that many fast moving objects.

Note: Questions which are not directly related to development, should be asked in the forum, otherwise it will clutter the discussions inhere. In the forum, many more will be able to learn from the answers. If in doubt, post in the forum first. If it turns up to be a development issue, it can always be added here.

tanis2000 commented 10 years ago

@birkemose interesting solution. Is there any function in CCPhysics to do ray casting or should I roll my own?

In the latter case, it would be awesome to add one for people like me :)

Valerio Santinelli

Inviato da iPhone

Birkemose commented 10 years ago

There is functionality in chipmunk to do i, but I havent had time to try to customize CCPhysics yet. I know it is possible, because Scott gave me a heads up on how to do it. The function I used to use was cpSpaceSegmentQueryFirst. This is the plain vanilla chipmunk version; I am sure there is an objective flavoured also.

tanis2000 commented 10 years ago

@birkemose I'll have a look at that later this evening. I need it for my game so I might as well contribute it back to the core if someone isn't quicker than me :)

tanis2000 commented 10 years ago

@slembcke I checked the CCPhysics code and I found that CCPhysicsNode has a rayQueryFirstFrom method, but it invokes a block for all of the shapes the ray collides with. Would it be possible to wrap up cpSpaceSegmentQueryFirst in a similar way?