SKPhysicsBody not lining up with SKShapeNode
If you want to move physics body do not set the shape's body. Create a SKNode which is attached to the shape, then set the SKNode's physicsBody. To move the body, play around with the position of the SKNode that you created on the shape.
let shape = SKShapeNode(initialize here)
let bodyNode = SKNode()
shape.addChild(bodyNode)
bodyNode.physicsBody = SKPhysicsBody(initialize here)
// To move the body;
bodyNode.position = CGPoint(point you wish)
Use PhysicsBody with SKShapenode line. Swift, iOS, SpriteKit
Used edgeChainFrom instead of polygonFrom, and it works!
testShape.physicsBody = SKPhysicsBody(edgeChainFrom: testPath.cgPath)
SpriteKit; How to add a physicsbody to CGMutablePath/SKShapeNode (drawn line)?
There are different types of physics body (circular, rectanglular, polygonal, alpha mask, edge based). For CGMutablePath, you want to create a chain from a path.
To implement it, replace this line:
line.physicsBody? = SKPhysicsBody()
With this:
line.physicsBody = SKPhysicsBody(edgeChainFrom: path)
How to align SKPhysicsBody and SKShapeNode?
This is for other people who may have trouble understanding:
The anchor point of a sprite, is where the local coordinate system of children of that sprite begins. So if the anchor point is the center of a sprite, then (0,0) of child nodes corresponds to the center of the parent sprite.
In the case of a CGRect
, you normally specify the origin of the CGRect
(as the lower left corner of the rect), and then specify the dimensions.
Since you may be creating an SKShapeNode
or SKPhysicsBody
ellipse or rectangle using CGRect
, you should offset it, so the center of the rect matches the center of the sprite, so that the shape and the physics body are in the expected position.
Frame of SKShapeNode is offset
The position of an Edge Loop is relative to the node it's attached to. In general, for an edgeLoopFromRect
, the position is given by
edge_loop_position = node.position + rect.frame.origin
In this case, your physics body is offset by the position of myShape
. One way to fix this issue is to attach the edge loop to the scene instead of the shape node:
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: myShape.frame )
Alternatively, you can subtract the node's position from the frame's position with
let rect = CGRect(origin:CGPoint(x:myShape.frame.origin.x-myShape.position.x, y:myShape.frame.origin.y-myShape.position.y), size:myShape.frame.size)
myShape.physicsBody = SKPhysicsBody(edgeLoopFromRect:rect)
Swift 3 (SpriteKit): Aligning SKPhysicsBody to SKShapeNode
If you want to make a physics body from one point to the other, you may use something like this:
class GameScene:SKScene {
override func didMove(to view: SKView) {
var points = [CGPoint(x: 22, y: 22), CGPoint(x: 155, y: 155)]
let line = SKShapeNode(points: &points, count: points.count)
print(line.frame.size)
line.physicsBody = SKPhysicsBody(edgeFrom: points[0], to: points[1])
addChild(line)
}
}
This will create an edge based physics body using two points. An edge physics body is static by default so keep that in mind. To register a contact (or make a collision with this body) the other body has to be dynamic.
If you want to have this body dynamic, then look for volume based initializers.
Related Topics
How to Change Its Own Button Image on Tap in Swift
Trying to Add a Protocol to a Class Signature in Swift
Menu Items Disabled in MACos Menubar App
Avaudiosinknode with Non-Default, But Still Device-Native Sample Rates
How to Read Id3 Tags/Other Metadata from an Hls Stream in Swift/Avkit
Read Static Property from Object
How to Convert Bytes to Nsstring After Aes Cryptoswift Cipher
Using Nil-Coalescing Operator with Try? for Function That Throws and Returns Optional
Swiftui - Unwrap Optional Image Data to Create Image Based on Uiimage(Data)
Are Built-In Intrinsic Functions Available in Swift 3
How to Implement a Billboard Effect (Lookat Camera) in Realitykit
Gmail API: How to Send Attachments to The Drafts on Swift
Dynamically Call a Function in Swift
Custom Uitabbar Unselected Item's Color
Swift Protocol as Generic Parameter
How to Make Deinit Take Effect in Swift
Swift Enumerate Functions. How Does It Work Behind
How to Cast Up to Super Class When There Is an Override Function in the Sub Class