I'm programming a small game in Swift and SpriteKit, which is made of a boxes (4 * 8).
Scene (1024 * 768)
boxes (964 * 452)
row1 (932 * 25)
col1 (24 * 116)
col2 (24 * 116)
col3 (24 * 116)
...
row2...
I want to give them a texture, but I don't know how big the image file should be. And the box node's size seems to be relative to its parent node. How can I get the absolute size of an SKNode, the size the node takes on the screen?
All SKNodes have a method called calculateAccumulatedFrame
Any texture will be scaled to fill the Node. Just make sure the aspect ratio of the texture and the node are the same (e.g. make them both square).
The "size" property of a Node works! For example:
let test = SKSpriteNode(color: .clear, size: CGSize(width: 100.0, height: 100.0))
print(test.size)
test.setScale(2.0)
print(test.size)
correctly prints:
(100.0, 100.0)
(200.0, 200.0)
Related
I'm trying to create a chain-like structure in SpriteKit and I'm having trouble understanding the behavior of SKPhysicsJointLimit's maxLength property. It seems not to do anything at all.
This question didn't solve my problem.
According to the documentation, maxLength is The maximum distance allowed between the two physics bodies connected by the limit joint.
However, my two nodes become oriented much farther apart than their maxLength value. It's true that I'm setting their initial positions to be farther apart than maxLength -- but I would expect the nodes to pull together during the simulation, as if tied together by a stretchy rope. Instead, the nodes remain far apart.
So, here's some code that sets a joint between two SKSpriteNodes.
let screen = UIScreen.main.bounds
let bodyA = SKSpriteNode(imageNamed: "box.png")
let bodyB = SKSpriteNode(imageNamed: "box.png")
bodyA.size = CGSize(width: 20, height: 20)
bodyB.size = CGSize(width: 20, height: 20)
bodyA.position = CGPoint(x: screen.width*0.4, y: screen.height*0.8)
bodyB.position = CGPoint(x: screen.width*0.6, y: screen.height*0.8)
bodyA.physicsBody = SKPhysicsBody(circleOfRadius: 20)
bodyB.physicsBody = SKPhysicsBody(circleOfRadius: 20)
addChild(bodyA)
addChild(bodyB)
let pinJoint = SKPhysicsJointLimit.joint(withBodyA: bodyA.physicsBody!, bodyB: bodyB.physicsBody!, anchorA: CGPoint(x: 0.5, y: 0.5), anchorB: CGPoint(x: 0.5, y: 0.5))
//This doesn't seem to do anything:
pinJoint.maxLength = 5.0
scene?.physicsWorld.add(pinJoint)
In the simulation, it's clear that there is a physics joint connecting the two nodes -- it's just that the nodes are much farther apart than they should be.
Why doesn't my maxLength value change the behavior of my two nodes, and how do I fix the problem? What am I not understanding?
Thanks for your input!
Be sure that the anchor points are in scene coordinates, as described in the documentation. The (0.5, 0.5) is likely intended to be "center of the sprite" or something like that, but that's not correct for a joint.
I'm trying to render objects further away than 1000.
let box = SCNBox(width: 500, height: 500, length: 500, chamferRadius: 0)
let boxNode = SCNNode(geometry: box)
boxNode.position = SCNVector3(0, 0, -2000)
sceneView.scene.rootNode.addChildNode(boxNode)
From this this answer I know that ARKit directly sets SCNCamera's projectionTransform. So is there anyway I change this projectionTransform in order to render objects further away?
In ARKit | SceneKit app, if a distance from ARCamera to 3D model is greater than 1000 meters SceneKit's shader violently begins flickering, and approximately at 1600 meters model disappears completely.
ARCamera doesn't render application's 3D content. This shader's artifact is SceneKit's rendering engine issue. So, you have nothing to do with that at the moment.
In my current project I create some node that I would like to create physics bodies for.
This creates the nodes:
let seg = SKShapeNode(ellipseOf: CGSize(width: 10 / xScale, height: 10 / yScale))
let offset = (seg.frame.height / 1.5) * CGFloat(i + 1)
seg.position = CGPoint(x: anchorPoint.x, y: ((size.height / 2) / yScale) + (10 / yScale) - offset)
segments.append(seg)
addChild(seg)
And this is how I currently try to create the bodies:
seg.physicsBody = SKPhysicsBody(circleOfRadius: 10 / xScale / yScale / 2)
I dont know how I would go about creating the correct one. It should function like a normal physics body(edge based bodies don't collide with stuff).
Currently when the circles roll down it looks like this although they are initially circles:
Also they look very pixelated. Do you have any idea why?
Thanks for your help!
Since Xcode 8.2.1 and iOS 10.2, I'm seeing (randomly) wrong area for SKPhysicsBody when constructed as circle. This is my code:
let boundingBox = (node.path)?.boundingBox
let radius = (boundingBox?.size.width)! / 2.0
node.physicsBody = SKPhysicsBody(circleOfRadius: radius)
print("bubbleRadius: \(radius), boundingBox: \(boundingBox), physicsArea: \(node.physicsBody?.area), physicsAreaShouldBe: \((CGFloat.pi * radius/100 * radius/100))")
Now random factor. I couldn't find any clue when this printed 'physicsArea' is correct and when it's wrong. Sometimes print shows this (where you will see that area of PhysicsBody is calculated differently?):
bubbleRadius: 50.0, boundingBox: Optional((-50.0, -50.0, 100.0,
100.0)), physicsArea: Optional(0.349065870046616), physicsAreaShouldBe: 0.785398163397448
And sometimes print shows this (where you can see that area is calculated normally - per my understanding of area of circle):
bubbleRadius: 50.0, boundingBox: Optional((-50.0, -50.0, 100.0,
100.0)), physicsArea: Optional(0.785398185253143), physicsAreaShouldBe: 0.785398163397448
radius is always the same, only area gets calculated differently sometimes. This makes my circles overlap each other in the scene because their body is smaler than it looks.
Any ideas what might this be? Thanks.
I have made an app that fits all my contents perfectly on Iphone 6, but when I run it on any other device, the positions are shifted. How do I fix this using UIKit on Xcode
make the size and position relevant to the screen size for example:
Image.position = CGPoint(x: (scene?.size.width)! * 0.1, y: (scene?.size.height)! * 0.2)
Image.size = CGSize(x: (scene?.size.width)! * 0.6, y: (scene?.size.height)! * 0.6)
i use scene as a reference majority of the time but frame size works as well by replacing the (scene.size.height)! portion with
(self.frame.size.width) or (self.frame.size.height)