Fix joint with animations in SKScene - swift

I have two Sprites nodes in an SKScene. Both of them where declare as physics objects inside the SKScene editor. There are not Dynamic, they are not allow rotation, nor pinned or affected by gravity.
One of the objects is move with a method moveBy until it is close to the second object. When that happens, I create a fix joint like this:
let towChopiJointFix = SKPhysicsJointFixed.joint(
withBodyA: chopi.physicsBody!,
bodyB: towTruck.physicsBody!,
anchor: CGPoint(x: 300.0, y: 300.0 ) )
scene!.physicsWorld.add(towChopiJointFix)
After the fix joint is created, I move the chopi sprite using moveBy to other position. The problem is that the second sprite (towTruck) is not moving with it. I thought that if you create a fix joint, both bodies will move together even if you move just one.
Any help?

Related

Does collision work during animation for SceneKit?

I wanted to do a simple asteroids games where the asteroids go from far to bypass you (z>0) in SceneKit.
let moveAction = SCNAction.move(to: SCNVector3(0, -10, 10), duration: 2)
rockNode.runAction(moveAction)
Says I have a spaceship in Z axis 0, even though I can visually see the asteroids pass through the spaceship, the collision detection does not occurred. The collision only happened if the end point of the moveAction ends in Z axis 0 and in the same location as the spaceship.
Does detection only occurred after the moveAction ended (thus will not detect collision)? If yes, what solution do I have in detecting the collision during the asteroids movement?
did you set the isDynamic to true on both of your objects? and they both need to have different categoryBitmasks otherwise SceneKit will treat them as the same objects (can't comment don't have 50 rep yet) if not then do so collision should happen even when moving an object programmatically
Make the physics body as: kinematic. So it can detect collision even during SCNAction.
eg:
rockNode?.type = .kinematic
Or you can set it from Physics Inspector
Keep coding....... :)

having 2 physics bodies changes the behavior of the node

I have a rectangle shaped node, I want this node to behave like a pool ball when it hit the wall, meaning it bounce of the wall in a reverse angle, just like the pool ball, here is what I did:
1- Added physicsBody rectangleOfSize, the behavior is not as it supposed to, the node hit the wall then moves along it instead of bouncing in the correct angle.
2- Added physicsBody circleOfRadius, the behavior is perfect, but the node is not circle shaped, it's rectangle.
3- Finally found the most logical solution, I added two bodies circleOfRadius, one at the top of the node and one at the bottom,this way I should get the bouncing behavior I want with the top one, and still give the node a practical physics body for collisions with the bottom one, but the behavior is like the rectangle shaped physics body rather than the circle shaped one.
let circle = SKPhysicsBody(circleOfRadius: size.width / 2, center: CGPoint(x: 1, y: size.height / 2))
let circle2 = SKPhysicsBody(circleOfRadius: size.width / 2, center: CGPoint(x: 1, y: -size.height / 3))
physicsBody = SKPhysicsBody(bodies: [circle, circle2])
Seems like the bottom circle body is affecting the behavior, I tried playing with its properties(allowsRotation, mass, etc) but it changed nothing.
Any idea how to make a rectangle shaped node behave physically like a circle shaped one?
Check out the section for "Working with Collision and Contacts" in the Apple Docs for a SKPhysicsBody. Basically you have do define a collisionBitMask for your circle node to only collide with your walls and your rectangle node to only collide with whatever you want it to collide with.

Spritekit and swift 2 - overlapping sprites

I need to create a road(one simple horizontal line) using SpriteKit, so i have four obstacles to put anywhere position on the road. These obstacles will be in a "shelf" and I have to drag them to the road.
How can i do that using SpriteKit and the new Swift2 ?
PS: I'm beginner on spriteKit.
So you meant to make some SKSpriteNode (road) as you say and put another SKSpriteNode onto that road. (Further I assume that you already have sprite nodes of the road and one obstacle)
define the property of your gameScene:
let roadAndObstaclesLayer: SKNode!
then in didMoveToView you have to add the road SKSpriteNode and obstacle SKSpriteNode to that layer. Your have to make either spawn obstacle method or you have to make position of your obstacles by yourself.
In general it would be like:
roadAndObstaclesLayer = SKNode()
roadAndObstaclesLayer.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetHeight(frame) / 4) // position of your layer
roadAndObstaclesLayer.addChild(road) //child road is added
roadAndObstaclesLayer.zPosition = 0 //zPosition of the layer in the scene
road.zPosition = 0 //zPosition of the child (road) in the layer
roadAndObstaclesLayer.addChild(obstacle) //child obstacle is added
obstacle.zPosition = 1 //zPosition of the child (obstacle) in the layer above child rode
addChild(roadAndObstaclesLayer) //child of the scene is added
As you understand this is an example of single obstacle that is on the road. Your obstacle and road would be placed at the same place but if you want to make some difference of the positions so you have to describe the position of obstacle separately.
As well you can place road and obstacle in different layers or in scene itself separately so their position would be independent according to each other. So in other words it depends on what do you want see at the end.
Hope it helps.

Swift SpriteKit: How to make a sprite gain slight velocity when it collides with an object?

Im creating a game that where you tap to start the player to make him jump, and then as he goes up, more and more objects generate for you to collect to gain points (think of doodle jump). I have it set up so this will happen, but instead of being given a boost by the object, he just floats up out of the scene. Id also like to know how to remove the object from the scene when the player touches it. Thanks in advance(:
Here is my code for making him gain velocity when he touches the object:
func bounceOff() {
player.physicsBody?.affectedByGravity = false
player.physicsBody?.applyImpulse(CGVectorMake(0, 10))
let advance = SKAction.moveByX(0, y: 10, duration: 5)
runAction(advance)
}
Your object goes off the screen because you cancel gravity. The impulse you apply pushes up, but there is no force pulling down. As to removing node from the scene. You can use node's removeFromParent method.

SpriteKit Physics Bodies Collisions in Multiple Layers

Okay, so I'm writing code for a space blaster game, and all seems to be going well, minus these crucial issues.
First, I added a spaceship (with PhysicsBody) as a child of self (GameScene).
Then I added a background layer as a node also as a child of self, behind the spaceship, and simulated movement by moving the background around behind the spaceship via joystick control.
I added a node with a boundary physics Edge Loop body so the background wouldn't move beyond the ship, and added that node as a child of the bgLayer.
I have objects for the spaceship to shoot at, but I want them to move around as the background does, so I added them as children of the bgLayer.
Of course, I needed a laser when the spaceship fires, so I added this as well as a child of the bgLayer.
_spaceship.physicsBody = (custom physicsBody code);
[self addChild:_spaceship];
_bgLayer = [SKNode node];
[self addChild:_bgLayer];
_bounds = [SKNode node];
_bounds.physicsBody = (physicsBody edgeLoop code);
[_bgLayer addChild:_bounds];
_otherObjects.physicsBody = (custom physicsBody code);
[_bgLayer addChild:_otherObjects];
_laser.physicsBody = (custom physicsBody code);
[_bgLayer addChild:_laser];
All is well, the background doesn't move beyond the spaceship,the other objects move as the background moves, and the laser fires when called upon.
My first big dilemma is when my laser fires, it does not move as the background moves, but the background moves behind it. I could probably make do but it looks funny if the laser always moves in parallel with the ship. This seems odd to me since I added the laser as a child of _bgLayer.
Second, my laser's physicsBody doesn't seem to recognize the EdgeLoop body, and sails right on through it. Also, my spaceship's physicsBody seems to recognize the EdgeLoop body, but it does not recognize the other objects that are children of _bgLayer.
Do Physics Bodies that are not children of the same layer recognize each other?
And why doesn't my laser behave similarly to other children of the same layer?
Moving the world by changing its position will affect
Children with physics bodies
Children without physics bodies
Moving the world by applying a force/impulse or by settings its velocity will affect
Children without physics bodies
Instead of moving the world by setting its velocity, you can add a camera (an SKNode with a physics body) to the world, move the camera by setting its velocity, and then update the position of the world to center the camera. You can center the camera in the didFinishUpdate method.
-(void)fireLaser
{
_laser = [SKSpriteNode spriteNodeWithImageNamed: [NSString stringWithFormat:#"blueLaser"]];;
_laser.zRotation = _spaceShip.zRotation;
CGVector rotationVector = RadiansToVector(_spaceShip.zRotation);
_laser.position = (Custom code for positioning the laser just in front of the spaceship);
_laser.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_laser.size];
[_bgLayer addChild:_laser];
_laser.physicsBody.velocity = CGVectorMake(rotationVector.dx * LASER_SPEED, rotationVector.dy * LASER_SPEED);
}
[self fireLaser] is called in touchesBegan when a particular SpriteNode is touched.
The laser fires beautifully, but does not scroll with the background, but rather moves in relation to the spaceship. Background scrolls with a PhysicsBody and a setVelocity method is called when the joystick moves, thus simulating spaceship motion, when in reality the spaceship never leaves the center of the screen. Physics categories prevent the background physics body from colliding with anything. LASER_SPEED is simply a static const float.