SpriteKit collision angle of line and circle is odd - ios

Suppose a circle is enclosed in a diamond, and the circle heads due right. I would expect a series of continual 90 degree angles as the circle draws a square within the diamond.
What I'm seeing, however, is that the circle eventually gets pushed toward the center of the diamond after one or two collisions. What's going on?
The line is set to dynamic -> NO.

The ball gets reflected symmetrically to its angle of approach assuming it's a completely elastic collision. That means, to get the behavior you are looking for, the ball would need to approach exactly from one line mid-point to the next without any loss of energy.
Sprite Kit's physics engine will not be able to handle these exact values. The energy after an elastic collision in Sprite Kit is not guaranteed to be conserved. There will be small inaccuracies in the physics engine's floating point calculations. Also the collision itself may not be resolved as a perfect point-to-point reflection, which means the ball might "slide," which will result in the angle of reflection changing.
However I would still expect to see more collisions then just one or two. Make sure the restitution of both objects is set to 1.0 and make sure the ball's linear damping is set to 0. affectedByGravity should obviously be false. Friction should be set to 0. You can try setting usesPreciseCollisionDetection to true.
If you need the behavior you described in you picture to last indefinitely, you will need to set the position and velocity manually.

Related

SpriteKit - how do I apply a constant velocity and change on touch - swift

How do I make my player move left/right at a constant speed until the user touches the screen again, which will then make the player change direction right/left and run that way at a constant speed etc..
I have tried looking at other answers but can't figure out a working answer.
I've set linearDamping to 0 already.
There are two basic ways to apply velocity.
One is by applying forces to physics bodies, or giving them velocities.
Two is positional transformations, usually done with SKActions.
They're not compatible.
Since you're using physics, you need to either apply force or set a velocity.
I think you should probably take the time to read this entire page:
https://developer.apple.com/documentation/spritekit/skphysicsbody
Here's the setting velocity cherry from it:
First, you can control a physics body’s velocity directly, by setting
its velocity and angularVelocity properties. As with many other
properties, you often set these properties once when the physics body
is first created and then let the physics simulation adjust them as
necessary.
And here's the outline on forces:
You can apply a force to a body in one of three ways: A linear force
that only affects the body’s linear velocity. An angular force that
only affects the body’s angular velocity. A force applied to a point
on the body. The physics simulation calculates separate changes to the
body’s angular and linear velocity, based on the shape of the object
and the point where the force was applied.

Accelerate an SKSpriteNode

Is it possible to accelerate an SKSpriteNode?
I know the velocity can be set easily with node.physicsBody.velocity but how hard would it be to set it's acceleration?
Working backwards from newtons second law a motion : F = m.a
You can achieve a desired acceleration by using applyForce where the force is the acceleration multiplied by the mass.
[node.physicsBody applyForce:CGVectorMake(node.mass*acceleration.dx,
node.mass*acceleration.dy)];
applyImpulse instantly imparts a quantity of energy (in Newton.seconds). Your object doesn't accelerate so much as instantly reach the desired speed. This is unlikely to look very natural as it implies near-infinite power (energy divided by time) therefore is only really suitable for explosions (shooting bullets for example).
applyForce applies a force (in Newtons) for the time-interval the simulation runs in (i.e.: 1/60th of a second). This allows you to correctly accelerate an object and simulate many different forces being applied simultaneously (gravity, wind, rocket boost etc.) in different directions.
Also worthy of note is applyForce:atPoint: this allows you to specify at which point of the object the force is applied. For example if you were simulating a balloon with a string, the string would apply its weight to the bottom of the balloon, whereas the lift of the base in balloon would be applied to the centre of the ballon. Applying a force elsewhere than at the centre of gravity will cause the object to rotate.
Lastly, you have the corresponding applyAngularImpulse: and applyTorque: which allow you to influence an object's rotation speed. This is useful for example if you want to keep an object upright despite various bounces: you could apply a torque proportional to the angle (or square it if you want to avoid oscillations).
All this is very well documented here: SKPhysicsBody
But if you need more information about the physics themselves then have a look at Wikipedia:
Newtonian Physics and associated pages (angular momentum for example).
If you want it to accelerate, then you should change the direction of gravity for the object
self.physicsWorld.gravity = CGVectorMake(dx,dy)
but this would make everything accelerate, if that is okay

perfectly elastic collisions in sprite kit

I have two balls of equal mass that hit each other straight on. I can't seem to figure out why there is a rebound effect on the incoming ball. I am using sprite kit.
I thought it was the restitution property. I have it set to 1 (which is what I thought it should be), but have tried many.
The only way I can kill the rebound is to change the mass, which messes up other things.
If the speed is slow it pretty much stops as it should. But at higher speeds there is a bounce back. They should just exchange velocity as it is a head on collision. Is it possibly some numerical rounding at high speeds or something?
http://h2physics.org/?cat=4
actually restitution 0 should disable any bouncing effect, 1 means the body leaves the surface with the same velocity it impacted with

Surface Detection in 2d Game?

I'm working on a 2D Platform game, and I was wondering what's the best (performance-wise) way to implement Surface (Collision) Detection.
So far I'm thinking of constructing a list of level objects constructed of a list of lines, and I draw tiles along the lines.
alt text http://img375.imageshack.us/img375/1704/lines.png
I'm thinking every object holds the ID of the surface that he walks on, in order to easily manipulate his y position while walking up/downhill.
Something like this:
//Player/MovableObject class
MoveLeft()
{
this.Position.Y = Helper.GetSurfaceById(this.SurfaceId).GetYWhenXIs(this.Position.X)
}
So the logic I use to detect "droping/walking on surface" is a simple point (player's lower legs)-touches-line (surface) check
(with some safety approximation
- let`s say 1-2 pixels over the line).
Is this approach OK?
I`ve been having difficulty trying to find reading material for this problem, so feel free to drop links/advice.
Having worked with polygon-based 2D platformers for a long time, let me give you some advice:
Make a tile-based platformer.
Now, to directly answer your question about collision-detection:
You need to make your world geometry "solid" (you can get away with making your player object a point, but making it solid is better). By "solid" I mean - you need to detect if the player object is intersecting your world geometry.
I've tried "does the player cross the edge of this world geometry" and in practice is doesn't work (even though it might seem to work on paper - floating point precision issues will not be your only problem).
There are lots of instructions online on how to do intersection tests between various shapes. If you're just starting out I recommend using Axis-Aligned Bounding Boxes (AABBs).
It is much, much, much, much, much easier to make a tile-based platformer than one with arbitrary geometry. So start with tiles, detect intersections with AABBs, and then once you get that working you can add other shapes (such as slopes).
Once you detect an intersection, you have to perform collision response. Again a tile-based platformer is easiest - just move the player just outside the tile that was collided with (do you move above it, or to the side? - it will depend on the collision - I will leave how to do this is an exercise).
(PS: you can get terrific results with just square tiles - look at Knytt Stories, for example.)
Check out how it is done in the XNA's Platformer Starter Kit Project. Basically, the tiles have enum for determining if the tile is passable, impassable etc, then on your level you GetBounds of the tiles and then check for intersections with the player and determine what to do.
I've had wonderful fun times dealing with 2D collision detection. What seems like a simple problem can easily become a nightmare if you do not plan it out in advance.
The best way to do this in a OO-sense would be to make a generic object, e.g. classMapObject. This has a position coordinate and slope. From this, you can extend it to include other shapes, etc.
From that, let's work with collisions with a Solid object. Assuming just a block, say 32x32, you can hit it from the left, right, top and bottom. Or, depending on how you code, hit it from the top and from the left at the same time. So how do you determine which way the character should go? For instance, if the character hits the block from the top, to stand on, coded incorrectly you might inadvertently push the character off to the side instead.
So, what should you do? What I did for my 2D game, I looked at the person's prior positioning before deciding how to react to the collision. If the character's Y position + Height is above the block and moving west, then I would check for the top collision first and then the left collision. However, if the Character's Y position + height is below the top of the block, I would check the left collision.
Now let's say you have a block that has incline. The block is 32 pixels wide, 32 pixels tall at x=32, 0 pixels tall at x=0. With this, you MUST assume that the character can only hit and collide with this block from the top to stand on. With this block, you can return a FALSE collision if it is a left/right/bottom collision, but if it is a collision from the top, you can state that if the character is at X=0, return collision point Y=0. If X=16, Y=16 etc.
Of course, this is all relative. You'll be checking against multiple blocks, so what you should do is store all of the possible changes into the character's direction into a temporary variable. So, if the character overlaps a block by 5 in the X direction, subtract 5 from that variable. Accumulate all of the possible changes in the X and Y direction, apply them to the character's current position, and reset them to 0 for the next frame.
Good luck. I could provide more samples later, but I'm on my Mac (my code is on a WinPC) This is the same type of collision detection used in classic Mega Man games IIRC. Here's a video of this in action too : http://www.youtube.com/watch?v=uKQM8vCNUTM
You can try to use one of physics engines, like Box2D or Chipmunk. They have own advanced collision detection systems and a lot of different bonuses. Of course they don't accelerate your game, but they are suitable for most of games on any modern devices
It is not that easy to create your own collision detection algorithm. One easy example of a difficulty is: what if your character is moving at a high enough velocity that between two frames it will travel from one side of a line to the other? Then your algorithm won't have had time to run in between, and a collision will never be detected.
I would agree with Tiendil: use a library!
I'd recommend Farseer Physics. It's a great and powerful physics engine that should be able to take care of anything you need!
I would do it this way:
Strictly no lines for collision. Only solid shapes (boxes and triangles, maybe spheres)
2D BSP, 2D partitioning to store all level shapes, OR "sweep and prune" algorithm. Each of those will be very powerfull. Sweep and prune, combined with insertion sort, can easily thousands of potentially colliding objects (if not hundreds of thousands), and 2D space partitioning will allow to quickly get all nearby potentially colliding shapes on demand.
The easiest way to make objects walk on surfaces is to make then fall down few pixels every frame, then get the list of surfaces object collides with, and move object into direction of surface normal. In 2d it is a perpendicular. Such approach will cause objects to slide down on non-horizontal surfaces, but you can fix this by altering the normal slightly.
Also, you'll have to run collision detection and "push objects away" routine several times per frame, not just once. This is to handle situations if objects are in a heap, or if they contact multiple surfaces.
I have used a limited collision detection approach that worked on very different basis so I'll throw it out here in case it helps:
A secondary image that's black and white. Impassible pixels are white. Construct a mask of the character that's simply any pixels currently set. To evaluate a prospective move read the pixels of that mask from the secondary image and see if a white one comes back.
To detect collisions with other objects use the same sort of approach but instead of booleans use enough depth to cover all possible objects. Draw each object to the secondary entirely in the "color" of it's object number. When you read through the mask and get a non-zero pixel the "color" is the object number you hit.
This resolves all possible collisions in O(n) time rather than the O(n^2) of calculating interactions.

Collision Handling Between Circle and Line Segments

I'm implementing a small game and am having trouble getting the physics working properly.
In this game, there is one ball (a circle which moves from frame to frame, and may change radius) and several walls (line segments which also change and move from frame to frame). I can detect collisions properly, and making the ball bounce off in the correct direction is no problem.
Difficulties arise in situations where the ball intersects a line in one frame, then intersects it again in the subsequent frame, causing a double bounce. I could move the ball back along the normal of the line until it is in a valid position, but this causes really weird behaviour when the line in question is being hit along its axis (imagine a ping pong ball falling down on an upright toothpick and suddenly shifting aside so that it is on one side of the toothpick...). There are also a few issues when the ball intersects more than one line in a given frame (imagine four lines together making a rectangle and the ball intersecting the corner of said rectangle) -- which direction should it bounce off? In which direction should it shift?
I don't really have a specific question, but am looking for tips or some useful tutorials. All the 2D ones I've managed to find so far only cover rectangle intersections.
I'm using XNA if it makes any difference.
Thanks,
Cameron
This is an universal problem with most physics libraries. If you google for "penetration depth" (together with "physics", I suggest, or you might find something entirely different :D) you will find that even these libraries use tricks like yours.
There are two solutions to this:
The cheap one is to increase your update frequency. Move objects in 10 smaller steps instead of a single big one and you will have less penetration, so fixing it by offsetting the ball away from the wall will be less visible.
The expensive one is continuous collision detection. There are algorithms that can tell you, given a moving and a stationary object, the exact point in time both will will intersect. Google "swept sphere rectangle intersection" to find some of these.
You can then update like this: ball needs to move by 1.0 units. Check for collision. Collision occurs after 0.25 units, so move ball by 0.25 units, calculate reflection vector (so the ball bounces off the wall), repeat collision check with remaining 0.75 units (until you know the final position of the ball). This avoids penetrations entirely and even if your ball is moving so fast that it would normally skip over the wall in a single update, the collision will be detected.
It's generally accepted that, because of the timestep your collisions will intersect past an acceptable point in between updates.
Basically, you have to interpolate back to the point in between the last and current frame where the collision truly happened, move the object back to that point, and then calculate the forces, etc.

Resources