I have a node with a SCNTube as its physics body and another set of nodes that cover the tube on top and bottom with SCNPlanes. Whenever a ball collides with the tube they lose most of the energy they had. If they hit the top or bottom they bounce off no problem. The balls have friction, dampening, etc. set to 0 and restitution set to 1. I tried setting the different physics values(friction, restitution, etc.) of the tubes to no effect. The planes are using the default values.
Related
I have a physics body that is uneven but not dynamic (the terrain) and a physics body (character) that is dynamic and is on top of the terrain, and I want this character to move along the terrain simulating kind of a "walking" action where it will keep going up the terrain but it won't fall back (or move back) like a ball because of gravity, and to set a maximum tilt so that it does not tip over.
My attempt was to add a force in the direction I want the character to move but this is causing the character to fall back due to gravity, and I don't want to disable gravity because then character won't fall down when going down the terrain.
Thank you very much
this is why using a physics engine for a platforming game is very difficult and not always a great approach..
you can try sprite.physicsBody.allowsRotation = false
might help
Create SKAction to move your character to destination point or dx and dy. Run that SKAction from your character node with the runAction. Like
SKAction.moveByX(...
When the action is finished, gravity will bring the character down.
If the movement is slow, play with the character's physicsBody friction and/or mass.
You can also change the the character's physicsBody.velocity = CGVectorMake(
And your terrain will be better with edgeLoop physicsBody which won't be dynamic.
And with uneven you mean inclined but smooth? If not smooth and with edges, your character may get held up at an edge depending on center of gravity of character and if you are allowing rotation.
I use ball.frame.intersects(bar.frame), where ball = SKShapeNode(circleOfRadius: BALL_RADIUS) and bar = SKShapeNode(rectOfSize: <Some CGSize object>)
While this works, there is an invisible square in which the circle is inscribed. The diameter of the circle is the same as the side of the square. This square is what ball.frame is, so sometimes, the ball will act like it's intersecting the bar, but visually it's not.
In this screenshot you can see that the ball is stopped, and therefore the game is over because ball.frame.intersects(bar.frame) returned true, even though visually the ball isn't even touching the bar.
So how do I check if the ball is really intersecting the bar, and not if the ball's frame is intersecting?
SpriteKit has decently powerful collision detection in its physics subsystem — you don't have to roll your own.
Create SKPhysicsBody objects for the ball and the bars, using init(circleOfRadius:) for the former and init(rectangleOfSize: for the latter.
Then, you can either:
Drive all the movement yourself, and use SKPhysics only to test for collisions. In this case you need to set your scene's physicsWorld.gravity to the zero vector, and call allContactedBodies() on the ball when you want to see if it's contacting a bar.
Let SKPhysics drive the movement, by setting velocities or applying impulses. In this case you'll need to set a contact delegate for your physics world, and then you'll get a callback whenever a collision occurs.
For more details on either approach, see the docs.
After detecting that ball frame intersects box frame:
Determine the radius of the ball
Determine the point on the line that is the edge of the ball from the center of the ball to the edge of the box. (Hint: pythagorean theorem - hypotenuse = radius)
Is this point inside the box's rect?
Repeat for each point in the box.
for a test, i have created two SCNBox objects, and one SCNFLoor.
I now set scene.physicsWorld.gravity = SCNVector3Make(0,-9.8,0);
I have placed one cube on the floor, and one cube on the top of the other.
All three nodes have zero rotation, and physicsBody.friction values set to 1.0.
I measure the node velocity at 3 points, : didBeginContact, didUpdateContact, and didEndContact. If the linear or angular velocity is not zero i set it to zero, along with the velocityFactor, and AngularVelocityFactor properties of each dynamic node.
Regardless of any of these points, the objects continue to move, (albeit slowly) but the problem is there.
Can someone point me in the right direction, what am i missing ? the documentation states a friction value of 1 will prevent sliding. This is clearly not the case.
I am looking for some coding help where i can either zero the node velocity before its position is updated during each cycle, or prevent the sliding from occurring.
Solution was to ensure objects were not moving in the SCNSceneRendererDelegate method :
-(void)renderer:(id)aRenderer updateAtTime:(NSTimeInterval)time
This is pre-physics simulation and you can ensure stationary objects remain stationary this way. Its not ideal but no physics simulator is.
Here is my setup:
SKScene with a node called world
to this world, I attach another node: vehicle
to this vehicle, I attach three nodes that make up the vehicle; a body and two wheels
the wheels are attached to the body via SKPhysicsJointPin specifying their anchors
Now, everything is fine until I zoom out of my world:
[_world runAction:[SKAction scaleTo:0.5 duration:0.75]];
My vehicle suddenly lifts off the wheels. It appears as if the same distances as in the not-zoomed-in-world are kept. All parts of the vehicle are properly scaled- except the distances to its parts.
Do I have to apply the zoom to my joints as well? Or do I need to reset the anchor of my joints?
Thanks for your help!
Physics don't scale. Changing a node's scale is a purely visual effect, it does not alter physics in any way.
Even if you manually update physics positions synchronized with a node's scale you'll find that you can't scale each body's shape without removing the previous body and replacing it with a corresponding body of the same shape, just scaled. During a scale action you would have to through away and create new bodies every frame, which will probably cause a serious framerate issue.
I am creating a spritenode, setting its position and changing its anchorpoint to (0, .5) and then creating a phyicsbody.
The physicsbody thinks my anchorpoint is still at (.5, .5), stupidly.
The same problem is referenced here, but unsolved: Physicsbody doesn't adhere to node's anchor point
The order I am doing things in is correct, it's just my physicsbody is stubborn.
The anchorPoint determines where the node's texture is drawn relative to the node's position. It simply does not affect physics bodies because it's a purely visual property (a texture offset).
For physics-driven nodes it is actually counter-productive to change the anchorPoint from its default because that will change the point around which the texture will rotate. And the physics body will usually also change the node's rotation.
So even if you were to move the physics body shape's vertices to match the sprite with a modified anchorPoint, the physics shape will be misaligned with the image as soon as the body starts rotating. And it'll seem to behave weird.
Plus whatever you want to achieve using anchorPoint you can more flexibly achieve by using the node hierarchy to your advantage. Use a SKNode as the physics node, and add a non-physics sprite node as child to that node and offset it the way you wanted the image to be offset by changing the sprite's anchorPoint.
You end up having two nodes, one invisible representing the physics body and one (or more) sprite(s) representing the visuals for the body but not necessarily tied to the body's center position.