I have two sprite nodes where I have made sure both self.size and the size of their respective physics bodies is the same, but I still get a very odd behavior like this:
The photo is taken as the collision has been detected and i paused the scene. Why does this happen?
Here is the code for setting the different sizes:
Inside init() of my Player class (circular node):
super.init(texture: texture, color: color, size: CGSize(width: 100, height: 100))
then:
self.physicsBody = SKPhysicsBody(circleOfRadius: self.size.width/2, center: self.position)
Turn on physics visual representation in you GameViewController.swift, like this:
skView.showsPhysics = true
self.size in your case probably referring to the scene. What you need is to set physics body's size like this:
yourNode.physicsBody = SKPhysicsBody(rectangleOfSize: yourNode.size)
Also keep in mind that if you are altering node's anchor point,you may end up with unexpected results. Anchor point defines how texture is drawn relative to the node. It has no effect on node's physics body.
Related
If I wanted to draw a simple red rectangle, should I use an SKShapeNode or an SKSpriteNode? What is the performance (speed to render) difference?
Are there any exceptions (like applying transparency, or maybe creating a physicsBody)?
I know what the primary purpose of both are, but I'm not sure which is better on performance for drawing a simple red square.
Code:
// Shape
let myShape = SKShapeNode(rectOf: CGSize(width: 100, height: 100))
myShape.fillColor = .red
myShape.strokeColor = .clear
// Sprite
let mySprite = SKSpriteNode(color: .red, size: CGSize(width: 100, height: 100))
SKSpriteNode offers higher performance than SKShapeNode class. See documentation here
If you want to add physicsbody to SKShapeNode, you should be aligned with shapenode points. For more sophisticated performance use SKSpriteNode. SKShapeNodes are useful when it is difficult to use a texture(may be a custom shape) and for building or displaying debugging information.
Furthermore, drawing/displaying a red rectangle is OK with SKShapeNode.
In this scene:
let rectangle = SKShapeNode(rectangleOfSize: CGSize(300, 400))
rectangle.fillColor = UIColor.clearColor()
rectangle.strokeColor = UIColor.grayColor()
rectangle.strokeWidth = 10
self.addChild(rectangle)
I want to put a ball inside this rectangle, trapped inside, with some velocity and restitution, that will be bouncing and changing the vector direction when collides with one of the walls.
I am not 100% sure if you can do that with SKShapeNodes and physics bodies because the physics body will apply to the whole shape node (with center).
Since you want to make the rectangle visible you can could either make a SKSpriteNode subclass with 4 SKSpriteNodes sides and than shape them as a rectangle.
Alternatively you could just draw a rectangle border in your program of choice, just make sure the centre is nothing basically, and export as PNG. Than just create a SKSpriteNode with the image.
let rectangle = SKSpriteNode(imageNamed: "Rectangle")
let texture = SKTexture(imageNamed: "Rectangle")
rectangle.physicsBody = SKPhysicsBody(texture: texture, size: texture.size())
rectangle.physicsBody?.collisionBitMask = 1
Now if you have drawn the rectangle correctly it will only have a physics body on the 4 sides since you did not draw a centre.
Than you simply create your ball and give it a physics body like above, with the same collision bitMask. Position it in the centre of the rectangle and give it an impulse or something. It should bounce around as you wish without leaving the rectangle.
If you are unsure about physics bodies than you need to read a bit about it, e.g
http://www.techotopia.com/index.php/A_Swift_iOS_8_Sprite_Kit_Collision_Handling_Tutorial
I simply have put a square shape node onto a scene, and made the physicsBody for the scene be the edge of the screen. I turned on the physics view so you can see all of the physics stuff. The square has a physics body around it, as does the border of the scene. However, when the square runs into the border, nothing happens. The square just passes straight through. Here is how I initialize the square:
let rect1 = CGRect(x: 100, y: 100, width: 50, height: 50)
let square = Square(rect: rect1)
square.fillColor = UIColor.blackColor()
square.zPosition = 200
square.physicsBody = SKPhysicsBody(edgeLoopFromRect: rect1)
square.physicsBody?.allowsRotation = false
square.physicsBody?.affectedByGravity = false
square.physicsBody?.restitution = 0.4
self.addChild(square)
Here is how I initialize the physics body for the scene:
let physicsBody = SKPhysicsBody(edgeLoopFromRect: view.bounds)
self.physicsBody = physicsBody
Very similar code has worked for me on other games, so I am not sure why no collisions happen. Any help is greatly appreciated thanks!
The movement of the balls must be caused by physics rather than just setting the position. The issue was fixed through using impulses to move the balls which then made them collide with the various objects.
I am using the following code to put a floor in my SpriteKit based game:
var floorNode = SKSpriteNode()
var floorBody = SKPhysicsBody(edgeFromPoint: CGPointMake(self.frame.minX, self.frame.minY), toPoint: CGPointMake(self.frame.maxX, self.frame.minY))
floorNode.physicsBody = floorBody
addChild(floorNode)
This places a floor at the bottom of the screen as expected. However as I add more things to the scene, one end of the floor eventually sinks down and everything in the scene that is resting on it slides off into the abyss.
I am at a complete loss here since Apple's documentation says that "an edge-based body does not have mass or volume, and is unaffected by forces or impulses in the system. Edge-based bodies are used to represent volume-less boundaries or hollow spaces in your physics simulation."
Anyone else seen this kind of behavior?
The easiest way to define floor for your scene, without adding any nodes to it:
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
where self is your SKScene.
If you don't want ceiling on the scene, define physicsBody as this:
[SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
self.frame.size.height*5)];
I have created a world using SpriteKit, containing a SKShapeNode. I'd like to tie it into the ceiling. The gravity and other stuff still have their effect on this shape, but it should hang from the ceiling. Like a lamp, or a rope.
My shape:
let shape = SKShapeNode(rectOfSize: CGSize(width: self.tamanhoQuadrado, height: self.tamanhoQuadrado))
When I add this:
shape.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: self.tamanhoQuadrado, height: self.tamanhoQuadrado))
It falls to the ground. I haven't found a property that can ignore gravity.
Found it!
//no gravity
shape.physicsBody!.affectedByGravity=false
//make it stay on it's place
shape.physicsBody!.dynamic=false