I have a Player Sprite which moves as the user drag their finger across the screen. I have implemented a power that the player sprite creates a magnetic repulsive force around it.
My dilemma is that when the power is turned on the player sprite itself gets affect my it when it shouldn't be.
I have set the correct fieldBitMask and categoryBitMask on the desired sprites and the field node but still doesn't work.
This is my players physicsBody configuration:
physics.affectedByGravity = false
physics.allowsRotation = false
physics.dynamic = true;
sprite.physicsBody?.fieldBitMask = 0
Set player node:
physics.dynamic = false
Related
I am trying to fix the camera to a sprite node “players.first!” and I managed to do so using SKConstraints as follows
func setupWorld(){
let playerCamera = SKCameraNode()
let background = SKSpriteNode(imageNamed: platformType + "BG")
var cameraFollow = [SKConstraint]()
cameraFollow.append(SKConstraint.distance(SKRange(constantValue: 0), to: players.first!))
playerCamera.constraints = cameraFollow
background.zPosition = layers().backgroundLayer
background.constraints = cameraFollow
background.size = self.size
self.addChild(playerCamera)
self.camera = playerCamera
self.addChild(background)
physicsWorld.contactDelegate = self
addEmitter()
}
But this keeps the camera fixed to the exact location of the node, I want the camera to be shifted to the right of the node “players.first!” (only in X dimension) and I couldn’t manage to do so with SKConstraints, note that the node is moving fast so updating the position of the camera in the update function makes the camera jitter.
This image is explaining my issue
Constrain the camera to an empty SKNode and make it a child node of the first player which is offset to the right in the frame of the player. This can be accomplished in the scene editor or programmatically by setting this dummy node's position to something like CGPoint(x: 100, y: 0). When the player moves, this node will also move, dragging the camera along with it; and since the camera is focused on this node, the nodes in the same 'world' of the player will appropriately appear to move in the opposite direction while maintaining the look you want for the player.
EDIT: If the player rotates
If the player needs to rotate, the above configuration will result in the entire node world revolving around the fixed empty node. To prevent this, instead place an empty SKNode that acts as the fixed camera point which will be called "cameraLocation" and the player node into another empty SKNode which will be called "pseudoPlayer". Constrain the camera to "cameraLocation". Moving the "pseudoPlayer" node will then move both the camera's fixed point (so that the camera moves) and the player node while only resulting in the rotation of the player and not the entire world.
NOTE: The only potential drawback is that in order to move the player correctly through the world, you must move the "pseudoPlayer" instead.
I am making a game with sprites that move and obstacles to learn SpriteKit. I want the sprites that move to collide with the obstacles and bounce off of them but I want the obstacles to stay fixed. How do I do this? I have tried the following with no success:
Setting obstacle.physicsBody?.isDynamic = true. This made the sprites go through the obstacle.
Fixing the movement and rotation of the object with SKConstraint. When I do this they just go through each other.
Setting the mass of the body to be really high as follows obstacle.physicsBody?.mass = CGPoint.maxFiniteMagnitude but this freezes the game. When I set it really high it doesn't seem to do anything.
Setting obstacle?.physicsBody.velocity = CGVector(dx: 0, dy: 0) when the objects collide. I know that the contact.bodyA and contact.bodyB are passed by value and not reference so I loop through an array with the obstacles and set the velocity this way. The obstacles are still pushed by the other sprites.
Update:
- Setting obstacle.physicsBody?.collisionBitMask = PhysicsCategory.none so the sprite collides with the obstacle but not the other way around.
The object is setup as follows, with fish being the other sprite:
obstacle.position = location
obstacle.physicsBody = SKPhysicsBody(rectangleOf: obstacle.size)
obstacle.physicsBody?.isDynamic = true
obstacle.physicsBody?.categoryBitMask = PhysicsCategory.obstacle
obstacle.physicsBody?.contactTestBitMask = PhysicsCategory.fish
obstacle.physicsBody?.collisionBitMask = PhysicsCategory.fish
obstacle.physicsBody?.usesPreciseCollisionDetection = true
self.obstacles.append(obstacle)
super.addChild(obstacle)
Please let me know if there is something I am doing wrong / misunderstanding. Thanks.
Found the answer here. One of the objects needs to have .physicsBody?.isDynamic = true. In this case I set the obstacle to false so it is stationary.
I have a Player SkSpriteNode that needs to pickup an Object. Once the Object is picked up, it should be attached to the player. I don't really care where the object is (to a side, above, center, etc), but it needs to stick to the player and not move from it's position.
With the code below I can get it to stick, but once the Player falls from a platform, the Object lags behind it, almost like it's lighter than the Player. I've tried pinning it, but that affects how high my Player jumps. Setting dynamic or gravity to false doesn't seem to help either.
The code below is in the Player Class.
func pickedUpObject(object: ObjectClass) {
object.removeFromParent()
object.position = CGPoint(x: -20, y: -5)
object.zPosition = 0
self.addChild(pollen)
}
In my game I have a body that flies across the screen, and is supposed to be affected by a radial gravity field that I have created. To do this, I needed to turn the
body.dynamic = true
But this results in the body colliding with other objects (with physics bodies) that are on the screen, when I just want it to be affected by the field and not by these objects. If I turn the
body.dynamic = false
then it doesn't get affected by the field.
What should I do to make the body stay on its path?
EDIT This is my code for the main body that flies across the screen, after a node has already been created
body.physicsBody = SKPhysicsBody(rectangleOfSize: rectangle)
body.physicsBody?.dynamic = true
body.physicsBody?.categoryBitMask = PhysicsCategory.body
body.physicsBody?.contactTestBitMask = PhysicsCategory.otherBody
body.physicsBody?.affectedByGravity = false
body.physicsBody?.fieldBitMask = PhysicsCategory.shield
body.physicsBody?.allowsRotation = false
The image shows the 2 possible ways I want the body to avoid colliding with the object. Either it can pass through it, or it can pass around it and return to the earlier path. How do I do that?
You should set
body.physicsBody?.collisionBitMask = 0
collisionBitMask - A mask that defines which categories of physics bodies can collide with this physics body. IF the value is not set your PhysicsBody collides with every other PhysicsBodies, If value is set to 0 your PhysicsBody do not collide with other PhysicsBodies
I you set collisionBitMask = 0 your body node will go through all other nodes, if you whant it to collide you need to set node physicsBody?.collisionBitMask (for example if you whant your node to collide only with ball and wall physicsBody?.collisionBitMask = kCategoryWall | kCategoryBall)
I hope it was helpfull
Hi I am making a endless scrolling game where the character basically avoids obstacles as they come and he can jump over them. I got everything to work pretty well but I see that the character texture will bounce slightly after hitting the ground. I want the sprite to stop immediately after touching down. I tried setting the .restitution property to 0 but i still see it bouncing. Here is the setup code for my stickman character and the edge physics category in question
stickman.physicsBody?.dynamic = true
stickman.physicsBody?.allowsRotation = false
stickman.physicsBody?.usesPreciseCollisionDetection = true
stickman.physicsBody?.categoryBitMask = PhysicsCategory.Stickman
stickman.physicsBody?.collisionBitMask = PhysicsCategory.Edge
stickman.physicsBody?.contactTestBitMask = PhysicsCategory.Obstacle | PhysicsCategory.Edge
stickman.physicsBody?.restitution = 0
self.physicsWorld.gravity = CGVector(dx: 0, dy: -9.8)
physicsBody = SKPhysicsBody(edgeLoopFromRect: playableRect)
physicsWorld.contactDelegate = self
physicsBody?.categoryBitMask = PhysicsCategory.Edge
Where playable rect is just the screen boundary for universal deployment purposes.
Has anyone run into this problem. I couldn't quite find the same issue in other posts.
Set the restitution of the physics body your sprite is running into to 0 as well. Both physics bodies in a physics collision need to have a restitution of 0 to result in no bounciness.