I have basic rectangle node with physics body, I want to find middle pint of it, because, I want to both ends of rectangle react different to collision with another objects.I was looking for answer on the Internet, I find that I can use CGGeometry, but I don't have knowledge how to do it. How can I do that?
Why not just add a physics body on each end of your rectangle as a child. Then you can just detect if the child physics bodies collided without any complicated math
Related
My goal is to create a single physics body out of several of SceneKit's SCNBox geometries.
My understanding is that when I pass an SCNPhysicsShape(shapes:transforms:) to an SCNPhysicsBody(type:shape:), it should create a single physics body.
However, I end up with something that seems suspiciously like it's not a single physics body at all, but rather several separate physics bodies -- one for each shape I passed into SCNPhysicsShape(shapes:transforms:).
When I turn on scnView.debugOptions = .showPhysicsShapes, I can clearly see red lines defining the separate bodies in question. On its own, this isn't very convincing evidence (it's conceivable that those lines could be shown for whatever reason while still being a single physics body).
But there's another piece of data, here: The project in which I'm encountering this issue features a small ball that rolls around the scene -- and when that ball rolls over the red lines in question, the ball bounces up into the air a bit. So, it's quite obvious that, whatever is actually going on, there are edges where I would expect to see none.
This behavior is clearly visible in the following GIF. In it, each colored block is a separate SCNBox geometry with its own physics body. Each block has the exact same position.z. The ball bounces considerably as it crosses the point where one geometry meets another.
Here's some code illustrating the issue. parent is an SCNNode that holds the child nodes, and is the node to which I assign the physics body. Please assume that all properties are defined; I'm omitting things that aren't terribly relevant.
let childShape1 = SCNBox(width: 6, height: 2, length: 6, chamferRadius: 0.0)
//Other child shapes defined here...
//Set up the positional translation relative to the child node's parent:
let translateMatrixShape1 = SCNMatrix4MakeTranslation(childShape1.position.x, childShape1.position.y, childShape1.position.z)
//Other child translations defined here...
let parentShape = SCNPhysicsShape(shapes: [childShape1, childShape2, childShape3, childShape4], transforms: [translateMatrixShape1, translateMatrixShape2, translateMatrixShape3, translateMatrixShape4])
parent.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.static, shape: parentShape)
Now, parentShape is four rectangular boxes arranged around a central point, creating a sort of picture-frame-shaped object.
The ball is an SCNNode with an SCNSphere geometry and a dynamic physics body.
Question: Does anyone have any idea what might be going on, here? Have I somehow misunderstood how this whole thing works, or is this a limitation of SceneKit?
Usually you can create one single PhysicsBody from several geometry objects by making a flattenendClone from out of your (i.Ex.) parent node. This new node will have one single geometry then. For the PhysicsBody you can then use the geometry element of the new node. In Addition I recoommend to use a concavePolyhedron for the static body type. (I hope I understood you correctly)
I am currently working on a 2D endless runner, written in Swift3 and using Spritekit.
Short question:
Is there a way to only check for collisions on the right side of my character's rectangular physics body?
More info:
The platform on which the character runs is made of puzzle pieces and the user builds upon it as the game progresses. The character progresses left to right, in respect to the background (which goes right to left).
I want the character to automatically jump when he collides with a piece on his right side. However, any pieces that the player puts to the right of him (same Y value as the character) is of the same class as the pieces underneath him.
So the same code that checks for collision between the character and pieces to his right, and make him jump, will also make him jump as long as the game detects collision between the character and the pieces under him.
I have not been able to find another problem like mine, since usually others' characters are colliding with objects of different classes from their ground class.
Thanks!
P.S. I have tried to make my character a SKSpriteNode with two physics bodies, but I could not find any helpful documentation. If it helps any, my character also performs a looping running animation--though I can't imagine that would harm anything.
You could achieve that by detecting collisions with your rectangle and then deciding whether the collision was with the side of your interest or not. Here is a discussion about how to do that. Good luck!
Have you tried adding a non visible sub node (e.g. feetNode) to your character's sprite node and giving that sub node the physics body (class) for floor contact ?
Depending on the rest of your logic, it may allow you to use a different physics class for your character have more flexibility in collision detection.
In fact, you could probably use that approach with several sub nodes in your character's sprite node and have multiple collision behaviours for the character depending on what hits it.
Once you obtain the contact point of the 2 bodies that are colliding, determine which body is the one that is colliding by checking the categorymasks and then check its CGPoints x position. This x position can be compared to the other body's x position to know exactly which side it is colliding from.
if Body A's x position > Body B's x position, Body A is on the right and if not, its on the left.
As simple as that.
Hope this helps!
I'm trying to understand SKPhysicsJointPin a bit better, specifically the anchor point parameter.
I understand that the anchor point is the position in the parent node of the two physics bodies concerned. What I don't understand at which point in the participating bodies does the pin go through and if there is a way to control that.
To make myself clear, say I'm making a clock with hands so the pin should go in the middle of the circle but for the hands is should go through the edge. So how can you control that.
Thanks a bunch.
Documentation is pretty lacking for these. To use the clock reference, and since you obviously know the code, I'll give you the English breakdown:
add 2 clock hand sprites to the scene
set both anchor points on the clock hand sprites to (.5,0)
position both sprites at (100,100)
create 2 physics bodies, add them to each clock hand
create the SKPhysicsJointPin, use anchor point (100,100)
add the joint to the scene
You should in theory, now have 2 clock hands, able to spin via their own anchor points around the point in the scene at (100,100).
I'm working on a game in which the user should be able to trigger 'rods' that come out from the edge of the screen to displace elements on screen (balls). These projectiles roughly resemble pool-cues. Or perhaps pinball plungers, except that they start from the 'loaded' position (mostly offscreen), and when triggered, they eject out, then quickly retreat.
I'm unclear how I should build these with Sprite Kit.
The game uses the PhysicsEngine, and the onscreen balls should be effected both by gravity AND they should be displaced when they collide with the rods. However the rods should neither be effected by gravity, not displaced when they collide with the balls -- they should simply retreat regardless of whether they've made contact with the balls.
I realize I can set the affectedByGravity property for the rods. However because they will still displace slightly when they collide with the balls. How can I 'fix' or 'peg' them in place? Do I need to use an SKPhysicsSlidingJoint? If so, has anyone encountered any examples online? Is there a simpler way to do this?
A related physics engine, Box2D distinguishes static, kinematic, and dynamic bodies.
Kinematic bodies can move and will collide with other objects, but they are themselves not affected by dynamic bodies or forces like gravity. Thus, consider setting rod.dynamic = NO; but animate it with actions. See also here in the reference for SKPhysicsBody.
I'm pretty new to Box2D and cocos2d. I'm trying to do something which I thought would be pretty simple, but it is turning out to be more difficult than I had expected and I cannot find a working answer anywhere.
Basically, I want to move a b2body and rotate it to a certain point with animation.
I can get it to the correct position and rotation with:
targetBody->SetTransform(b2Vec2(10.0f,1.0f),10);
But I have no idea how to animate it there over time. I tried using cocos2d animation on the sprite used for the body, but that doesn't do anything. Any ideas?
There are a couple of ways you could do this.
You could use SetTransform every time step to update the position of the body gradually over time, in effect performing the animation yourself. The drawback with this method is that the body is 'teleporting' to the new position rather than moving, so it has no momentum, which means you can get odd results if it hits anything along the way. Still, if you know it will not hit anything or does not need to react to a collision this would be ok.
The other way is to SetLinearVelocity and SetAngularVelocity to give the body proper movement. This will keep the results of a collision realistic, and you don't need to keep updating anything every timestep. On the other hand, you will need to detect when the body has arrived at the desired position and then set the velocities back to zero, otherwise it will just keep moving. For dynamic bodies you will also need to counter gravity somehow, either by setting the gravity scale of the body to zero, or by applying an upwards force to balance gravity, or by changing the body type to kinematic during the move.
In general, you use Box2D to simulate the physical behavior of objects in relation to each other. The rules of mechanics implemented by Box2D dictate how your cocos2d CCSprites move if you continuously update the translation and rotation of your sprites according to their corresponding Box2d b2Body. You will have some kind of repeatedly invoked tick: method in which you step your Box2d world along in time, and in which you update your sprite positions according to simulation results of Box2d.
This pattern corresponds to b2Bodys of type b2_dynamicBody. Physical laws dictate the motion of the body in this case, and your sprites will follow these simulation results. This is why setting a conflicting position of a sprite by means of a CCAction or even directly will be undone almost instantaneously with the next tick:.
Solution 1: kinematic body type
However, there do exist other modes for a b2Body, and one of these is b2_kinematicBody in which the translation is no longer governed by the world but by the velocities or angular speeds you dictate through setters. So it would be one solution to work with body type b2_kinematicBody as in:
b2BodyDef bdef;
bdef.type = b2_kinematicBody;
With this you would manipulate the velocity and angular speed of a b2Body explicitly. In this case, Box2d is still responsible for moving bodies around, but according the velocities you dictate, and without any force effects of collision or gravity applied to this particular body. Also with this strategy, your CCSprites will follow b2Bodys. Setting conflicting positions for your sprites directly or by applying a CCAction would not make sense for the same reason as described above.
Solution 2: decouple sprites from Box2d
An alternative way to animating sprites would be to fully decouple those sprites from Box2d. In this case, you would simply not have any b2Body that governs the position of the sprite you are going to animate. Now, in this case, only you will dictate the position and rotation of your CCSprite, i.e. directly either through its position property or by applying a CCAction.