How can I detect a permanent collision with the Chipmunk Physics engine - cocoa-touch

I'm trying to play a "boing" sound when a ball shape hit's any other kind of shape. Which works. But works a little too well....
When the ball comes to rest, or starts to roll, it's in a permanent collision with whatever it's touching, so the "boing" sound fires constantly.
I can't find anything in the chipmunk documentation to tell me when two things are permanently colliding. So I'm thinking I will have to somehow figure it out myself, probably with some sort of timer that compare the last collision against the current collision. But that sounds hacky to me.
Has anyone tackled this issue? How did you solve it?

Couldn't you just play your "boing" sound when contact is BROKEN?
There is a callback for that in chipmunk, typedef void (*cpCollisionSeparateFunc)(cpArbiter *arb, struct cpSpace *space, void *data)
That way you get boings whenever it bounces, but not when it's just rolling along. 'course, you'll also get one when it rolls off of your shape, but that could be a feature depending on how you look at it.

I don't think that what I'm about to say is a good practice, but I'm sure it will solve your problem:
For each object, keep two state variables: (1) The last object collided with, (2) The last collision time.
Upon collision, only play a sound if the collided object is different (and a ball) OR a certain "delta time" has elapsed since the last collision. Then record the last collision stats.
This is pretty simple and very effective:
// In your ball interface
id lastCollisionObject;
double lastCollisionTime;
// When a collision occurs...
double now = GetTime();
id other = GetCollisionObject();
if ((now - lastCollisionTime) > 0.3 || other != lastCollisionObject) {
PlaySound(kBoingSound);
}
lastCollisionObject = other;
lastCollisionTime = now;

Shapes don't have velocity in chipmunk. The bodies they are attached to have it. You can access velocity like this: "myShape.body->v". I agree that you should just be able to check if the velocity is over a certain threshold to know when an 'impact' occurs. You can also check the rotational velocity to see if the ball is rolling.

Related

could someone tell me why everything vibrates when the camera in my game moves?

I'm not sure why, but for some reason whenever the camera in my game moves, everything but the character it's focusing on does this weird thing where they move like they should, but they almost vibrate and you can see a little trail of the back of the object, although it's very small. can someone tell me why this is happening? here's the code:
x+= (xTo-x)/camera_speed_width;
y+= (yTo-y)/camera_speed_height;
x=clamp(x, CAMERA_WIDTH/2, room_width-CAMERA_WIDTH/2);
y=clamp(y, CAMERA_HEIGHT/2, room_height-CAMERA_HEIGHT/2);
if (follow != noone)
{
xTo=follow.x;
yTo=follow.y;
}
var _view_matrix = matrix_build_lookat(x,y,-10,x,y,0,0,1,0);
var _projection_matrix = matrix_build_projection_ortho(CAMERA_WIDTH,CAMERA_HEIGHT,-10000,10000)
camera_set_view_mat(camera,_view_matrix);
camera_set_proj_mat(camera,_projection_matrix);
I can think of 2 options:
Your game runs on a low Frames Per Second (30 or lower), a higher FPS will render moving graphics smoother (60 FPS been the usual minimum)
another possibility is that your camera is been set to a target multiple times, perhaps one part (or block code) follows the player earlier than the other. I think you could also let a viewport follow an object in the room editor, perhaps that's set as well.
Try and see if these options will help you out.
If your camera is low-resolution, you should consider rounding/flooring your camera coordinates - otherwise the instances are (relative to camera) at fractional coordinates, at which point you are at mercy of GPU as to how they will be rendered. If the instances themselves also use fractional coordinates, you are going to get wobble as combined fractions round to one or other number.

Make rectangle fall when being hit by ball (different outcomes depending on properties)

I've just got started with physics. I'm using Java, though language does not matter obviously. Now I though I'd do something like this:
A ball with a certain speed, radius and mass hits a rectangle with a certain mass, width and height. Depending on where the ball hits the rectangle (how high up), and all the properties the ball and the rectangle have that i just mentioned, there will be different outcomes of the situation.
These are the four possible outcomes:
The ball bounces back because the rectangle was too heavy
The rectangle starts to wobble, but then goes back to normal
The rectangle falls to the right
The ball strikes through making the rectangle fall to the left
Please note, I don't expect you to write a program for me. I understand it is a lot to think off. But I have no idea how to start. I would really appreciated some guide lines and links to further reading about this (I was not sure what to google to find info about this.)
And also, I'm doing this to learn, so don't tell me to use an engine or anything like that.
You are trying to build a simple physics simulator. This is a pretty involved problem, and you'll have to learn a certain amount of physics along the way.
I suggest you develop the simulator to handle these situations, roughly in this order:
An object moves through space (constant velocity, no gravity).
An object moves under the influence of a constant force (such as gravity).
An object moves with a constraint (e.g. a pendulum, a rolling square).
An object slides across a surface, with friction (both static and kinetic).
Two objects collide inelastically (they stick).
Two objects collide elastically (they bounce).
Once you have all of these, you will be able to simulate your ball and rectangle.

How to code a random movement in limited area

I have a limited area (screen) populated with a few moving objects (3-20 of them, so it's not like 10.000 :). Those objects should be moving with a constant speed and into random direction. But, there are a few limitation to it:
objects shouldn't exit the area - so if it's close to the edge, it should move away from it
objects shouldn't bump onto each other - so when one is close to another one it should move away (but not get too close to different one).
On the image below I have marked the allowed moves in this situation - for example object D shouldn't move straight up, as it would bring it to the "wall".
What I would like to have is a way to move them (one by one). Is there any simple way to achieve it, without too much calculations?
The density of objects in the area would be rather low.
There are a number of ways you might programmatically enforce your desired behavior, given that you have such a small number of objects. However, I'm going to suggest something slightly different.
What if you ran the whole thing as a physics simulation? For instance, you could set up a Box2D world with no gravity, no friction, and perfectly elastic collisions. You could model your enclosed region and populate it with objects that are proportionally larger than their on-screen counterparts so that the on-screen versions never get too close to each other (because the underlying objects in the physics simulation will collide and change direction before that can happen), and assign each object a random initial position and velocity.
Then all you have to do is step the physics simulation, and map its current state into your UI. All the tricky stuff is handled for you, and the result will probably be more believable/realistic than what you would get by trying to come up with your own movement algorithm (or if you wanted it to appear more random and less believable, you could also just periodically apply a random impulse to a random object to keep things changing unpredictably).
You can use the hitTest: method of UIView
UIView* touchedView=[self.superview hitTest:currentOrigin withEvent:nil];
In This method you have to pass the current origin of the ball and in second argument you can pass nil.
that method will return the view with which the ball is hited.
If there is any hit view you just change the direction of the ball.
for border you can set the condition for the frame of the ball if the ball go out of the boundary just change the direction of the ball.

cocoa collision detection question

I get the concept of the NSIntersectionRect for collision detection but I can't seem to think of how to implement it for my project. It's nothing fancy, click a button and a view subclass is called and places a circle in the window at a random location. Click within the that view and the circle pulses (this makes it the active view). If you have an active view, clicking anywhere outside it (but not on another circle) will move that view to the click point.
I'm using [activeView animator setFrame: NSMakeRect(x, y, w, h)] to move the active view. Can I use this for collision detection or do I have to go with CABasicAnimation? Basically what I am looking to do is detect collisions with other circles (no physics needed at this point, just stop the movement) and/or with the bounds of the app window.
If someone could nudge me in the right direction (tutorial link, code snippet) I'd appreciate it.
Edit: Based on the well detailed answer below I need to be a bit more clear. I'm confused on where to implement the collision detection. The animator method of a view class is one line of code. How would I iterate through every static circle on the screen to run a collision check? Which is why I am wondering first, if I need to go with CoreAnimation, OpenGL or something like Chipmunk and then if I could get a nudge or assist that would be great.
Later .. in answer to your recent questions:
Which is why I am wondering first, if I need to go with CoreAnimation, OpenGL or something like Chipmunk and then if I could get a nudge or assist that would be great.
Answer - you absolutely definitely do not need OpenGL :) Next, you definitely do not need a physics library like Box2D or Chipmunk ... you could go that way if you wanted to, but, it would be a huge amount of unnecessary work. To be clear: until you are totally familiar with using DrawRect, things like Chipmunk are useless for you anyway, so just forget that.
Core Animation will not really help you. To be clear, you possibly want to interrupt an animation as it is happening. Is that correct?
I'm confused on where to implement the collision detection. The animator method of a view class is one line of code. How would I iterate through every static circle on the screen to run a collision check?
Bad news... if you actually want to interrupt the animation, if there is a collision, forget about Core Animation. Core Animation will let you send it from A to B as "one unit" of animation. It will NOT let you stop it in the middle (in case of a collision). So, that's that.
To be clear, that is what you want to do right? You set the circle in motion, and IF it hits something along the way, you want it to stop. Is this correct? if so, completely forget about Core Animation and throw away any work you've done so far.
You are going to have to dive in to "real" programming (whatever that means) and start using drawRect. Are you up for it?!
At this point I might just mention: consider buying a copy of Corona (it's like $100 -- I'm sure the demo is free). You can do everything you are describing in, literally, five minutes using Corona. (1/10th the time taken to write this post??) I always recommend this to people who are iPhone Curious. If you don't really want to spend 6 to 18 months becoming a gun iPhone programmer - just click to Corona for iPhone and in a fraction of the time it's taken you to use Stack Overflow, you can have your circles bouncing wildly on the iPhone screen.
So, failing that, you're gonna have to get to work and learn how to launch a timer (NSTimer) and use drawRect in a UIView.
Craate a new class called MyFirstView (.h and .m file) that is a subclass of UIView (not UIViewController, which is for wimps!). You'll need a drawRect method in MyFirstView and proceed from there!
Original answer..
I'm not sure I understand what you are saying, but to be clear:
You want to detect a collision between two circles. In your case, all the circles are the same diameter. Is that correct?
If so, fortunately it is very easy to do.
Write a routine that gets the distance between two CGPoints. (If you don't know how to do that I included it below.)
Next step, you must know the DIAMETER of your circles. Let's say it is 50.0 for the example.
Next, here is a routine that checks if two circles are colliding:
static inline bool areTwoCirclesColliding( CGPoint aa, CGPoint bb )
{
return ( distanceBetweenTwoCGPoints(aa,bb) < 50.0 );
}
(Note... if you are new to Objective C, note that the above is totally valid code. Simply paste it in at the top of your file. OK?)
Finally, you just have to check all your circles, one against the other, to see if any are colliding.
If you have a simple fixed number of circles, let's say three or so, just write out all the lines of code to check if any of the combinations are colliding, hence:
areTwoCirclesColliding(a,b)
areTwoCirclesColliding(a,c)
areTwoCirclesColliding(b,c)
If you have an array or some sort of list of circles, you just have to go through them all and check that each one is not touching any other. In pseudocode it might be something like this...
for n in 1 to numberCircles
oneCircle = circles[n]
for m in n+1 to numberCircles
anotherCircle = circles[m]
if ( areTwoCirclesColliding(oneCircle,anotherCircle) )
.. break, you found a collision
Alternately you could write it like this, makes no difference..
for each aa in circles
for each bb in circles
if (aa != bb) if (areTwoCirclesColliding(aa,bb)) .. break, found collision
{Aside - For the record it is utterly unimportant that you check each pair twice in that pseudocode, no problem.}
It is impossible for me to write the actual code for you as i have no idea what structure you are using, sorry.
Of course if your circle is an object, you could sensibly make it test itself against all the other circles, same idea. If you have an SQL database of circles, test them all against each other.
So fortunately you can see it is one (1) line of code to check if two circles are colliding. And it's about 3 or 4 lines of code to check all your circles for collisions. So fortunately about 5 lines in total!
So, that is an incredibly simple tutorial on video game physics, part 1.1.1.1 !!!! Hope it helps! If that is not what you were trying to achieve, it was a complete waste of typing! :)
For the record here's a routine to get the distance between two CGPoints:
static inline float rawDistance(float x, float y, float p, float q)
{
return sqrt( ((x-p)*(x-p)) + ((y-q)*(y-q)) );
}
static inline float distanceBetweenTwoCGPoints( CGPoint a, CGPoint b )
{
return rawDistance( a.x, a.y, b.x, b.y );
}
(Note... if you are new to Objective C, note that the above is totally valid code. Simply paste it in at the top of your file. OK? It's exactly like using any everyday function supplied by Apple such as x=CGLayerGetContext(), for example. Enjoy!)
Later .. and by popular demand, for an object, Circle...
-(bool)isTouchingOtherCircle:(circle)c
{
return areTwoCirclesColliding(self.center, c.center);
}
-(bool)isTouchingAnyOtherCircle
{
for oc in yourCircles
if (oc != self)
if ( [self isTouchingOtherCircle:oc] )
return false;
return true;
}

Bullet physics engine, how to freeze an object?

Using Bullet 2.76 I'm trying to freeze an object (rigid body) so that it instantly stops moving, but still responds to collisions.
I tried setting it's activation state to DISABLE_SIMULATION, but then it's virtually nonexistent to other objects. Furthermore, if objects "collide" with it when it's disabled, strange things begin to happen (object's falling through static bodies, etc.)
I suppose, temporarily converting it to a static rigid body could work, but is there an existing "native" way to achieve this on Bullet's side?
Edit: Is there a way to turn off gravity for a specific object?
The documentation is a bit lacking but one would assume that the method below could be used to disable gravity on a specific body:
void btRigidBody::setGravity(const btVector3 &acceleration)
Just set rigid body's mass to 0, then it become static...
http://bullet.googlecode.com/svn/trunk/Demos/HelloWorld/HelloWorld.cpp
There are functions for btRigidBody called setLinearFactor(x,y,z) and setAngularFactor(x,y,z) that allow you to limit motion along a specific axis and rotation about a specific axis respectively. Calling both functions with all 0's as arguments should stop all motion. Calling them again with all 1's will allow motion again.
Set the activation state to zero. This is what happens when the object sleeps naturally. Gravity and so forth will not take effect until it is woken again.
rigidBody->setActivationState(0);
Then just like any sleeping object, it will be woken on a collision or if you apply a force to it.
For this method to stop your actor you must call this every update frame.
void StopActor()
{
m_pRigidBody->setLinearVelocity(btVector3(0,0,0));
}
set the velocity and momentum to zero and set the mass to a really, really large number.