Swift 3 (SpriteKit): x-axis lock for SKSpriteNode and its physics

I really need to know how to lock the x axis of the SKSpriteNode and its physical device. I need to keep SKSpriteNode dynamic and affectedByGravity . node is on a slope, which is why the x axis moves due to gravity. However, I do not want the x axis of this SKSpriteNode to move due to gravity. Is there a way to lock the x axis to achieve this? Thanks for any help :D

Edit: I tried applying the constraint to the x value as follows:

 let xConstraint = SKConstraint.positionX(SKRange(constantValue: 195)) node.constraints?.append(xConstraint) 

However, this does not work, and I'm not sure why and how to fix it. Does anyone know of a solution?

Edit 2: SKPhysicsJointPin actually looks more promising. In the comments of the first answer / answer to this question, I try to understand how to use it correctly in my situation.

An example of my code:

 let node = SKSpriteNode(imageNamed: "node") enum collisionType: UInt32 { case node = 1 case ground = 2 case other = 4 //the other node is unrelated to the ground and node } class GameScene: SKScene, SKPhysicsContactDelegate { override func didMove(to view: SKView) { //Setup node physicsBody node.physicsBody = SKPhysicsBody(rectangleOf: node.size) node.physicsBody?.categoryBitMask = collisionType.node.rawValue node.physicsBody?.collisionBitMask = //[other node that isn't the ground or the node] node.physicsBody?.contactTestBitMask = //[other node that isn't the ground or the node] node.physicsBody?.isDynamic = true node.physicsBody?.affectedByGravity = true addChild(node) //Physics Setup physicsWorld.contactDelegate = self } 

The node is on top of the earth, and the earth consists of various SKSpriteNode lines that have a physical device based on volume. The earth continues to add new lines in front and delete them in the back, and also change the x value of each line negative (so that the earth seems moving - this process is performed in SKAction). These lines (parts of the earth) are at an angle, so the node x axis moves. I want the node to always be in front of the earth (for example, always on top of a line just created). Currently setting the node position is similar to locking the x axis (solving my problem):

 override func didSimulatePhysics() { //Manage node position node.position.x = 195 node.position.y = CGFloat([yPosition of the first line of the ground - the yPosition keeps changing]) } 

Note: ^ This function is inside the GameScene class.

The x axis actually remains the same. However , the problem is that now the physical body of the node is smaller than the center of the node (which was not there before).

+6
source share
2 answers

A node constraints is the default nil property. You need to create an array of one or more constraints and assign it to a property. for instance

 let xConstraint = SKConstraint.positionX(SKRange(constantValue: 195)) node.constraints = [xConstraint] 

Update

You might want to use the node camera instead of moving the ground in the scene. With the node camera, you move the main character and camera instead of the ground.

enter image description here

+4
source

I think you can set the linearDamping property to 0.0

linearDamping is a property that reduces the linear velocity of the body.

This property is used to simulate the friction forces of fluids or air on the body. The property must be a value from 0.0 to 1.0. The default value is 0.1. If the value is 0.0, linear damping does not apply to the object.

You should also pay attention to other forces applied to your SKSpriteNode . The gravitational force used by the physical world, for example, where dx value, as you ask, should be set to 0.0:

 CGVector(dx:0.0, dy:-4.9) 

Remember also that when applying other force vectors, such as velocity , you must save the dx 0.0 property as a constant if you want to block the x axis.

You can find more information on the official docs

Refresh (after your comments on the comments below):

You can also snap your sprite to the ground using SKPhysicsJoint (I don't know your project, so this is just for example)

 var myJoint = SKPhysicsJointPin.joint(withBodyA: yourSprite.physicsBody!, bodyB: yourGround.physicsBody!, anchor: CGPoint(x: yourSprite.frame.minX, y: yourGround.frame.minY)) self.physicsWorld.add(myJoint) 

You can work with the anchor property to create a good joint as you wish or add more joints.

+3
source

Source: https://habr.com/ru/post/1013695/


All Articles