36

My scene has a bunch of rectangles with physics bodies that are the same size as the rectangle. I like to anchor all of my objects to CGPointZero, however I've noticed when I do that the physicsbody remains anchored in the middle. In other words, the position of my physics body is like 100 pixels lower and to the left of the visual representation.

Here is a simple snippet of code:

SKSpriteNode* square = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(width, height)];
square.anchorPoint = CGPointZero; //position based on bottom-left corner
square.position = CGPointMake(x, y);

square.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(width, height)];

Any ideas or advice to solving this problem would be appreciated. For example, if I could visualize the physics bodies, that might help, but I'm not sure how to.

UPDATE: So I've solved the problem by simply not setting the anchor point and repositioning my rectangles. So the problem still exists, but I have a work around in place and the work around is working well.

Sophie McCarrell
  • 2,831
  • 8
  • 31
  • 64
  • This is useful to find where your physics body actually is: http://stackoverflow.com/questions/20084968/draw-in-color-the-shape-of-your-skphysicsbody – bshirley Jan 31 '14 at 19:47
  • AnchorPoint slides the texture around the node's position. The anchorPoint has no effect on physics shapes/bodies simply because it only defines the texture's offset relative to the node's position. If you want your shapes further down the corner, leave anchorPoint at its default and change the position accordingly. Also changing anchorPoint will adversely affect rotation and position of child nodes. – CodeSmile Apr 02 '14 at 18:18
  • 1
    saying that changing the anchor point well adversely affect rotation and position of child node is naive. Maybe I want to rotate on 0,0. I definitely want to position that way, considering all low level graphics APIs work off of the bottom left corner, and web development works of the top right corner. Working from the centre is actually very unique in the grand scheme of graphics development. With that said, your first 2 sentences are clear and correct. I suppose, I wish I could change the physics body anchor point :\ – Sophie McCarrell Nov 24 '14 at 19:56

7 Answers7

13

I wrote this to fix Apple's lack thereof:

use pathForRectangleOfSize:withAnchorPoint: to replace your call to bodyWithRectangleOfSize: whose brief documentation tells us the problem: "Creates a rectangular physics body centered on the owning node’s origin."

@implementation SKPhysicsBody (CWAdditions)

+ (CGPathRef)pathForRectangleOfSize:(CGSize)size withAnchorPoint:(CGPoint)anchor {
  CGPathRef path = CGPathCreateWithRect( CGRectMake(-size.width * anchor.x, -size.height * anchor.y,
                                                    size.width,   size.height), nil);
  return path;
}

+ (SKPhysicsBody *)bodyWithRectangleOfSize:(CGSize)size withAnchorPoint:(CGPoint)anchor {
  CGPathRef path = [self pathForRectangleOfSize:size withAnchorPoint:anchor];
  return [self bodyWithPolygonFromPath:path];
}

@end

Edit: There is a new API in 7.1 to provide for this oversight.

+ (SKPhysicsBody *)bodyWithRectangleOfSize:(CGSize)s center:(CGPoint)center
bshirley
  • 8,217
  • 1
  • 37
  • 43
  • 1
    I'm using 7.1 and that still doesn't work :(, also the link doesn't show anything regarding a withAnchorPoint method. [I cmd+f'd the page for withAnchorPoint] I did find [SKPhysicsBody bodyWithRectangleOfSize:square.size center: CGPointZero]; – Sophie McCarrell Mar 30 '14 at 21:25
  • 2
    The `center:` are the apple initializer additions in 7.1. Center should be the anchor point in a [0-1, 0-1] range. – bshirley Apr 02 '14 at 17:29
  • The new API 7.1 `center:` method... +1 – itnAAnti Jul 14 '16 at 23:19
8

You can use

      [SKPhysicsBody bodyWithRectangleOfSize:size center: center];


       CGPoint center = CGPointMake(size.width*(anchorPoint.x-0.5f), size.height*(0.5f-anchorPoint.y))

should transform the bounding box according to the anchorPoint of the parents node

  • Of all the answers posted here, this was the only one that solved my issue with the physicsBody anchor point misaligned with the node anchor point. Thanks! – Solsma Dev May 28 '15 at 21:49
6

I am using Swift but the SKPhysicsBody was kind of half width and height wrong. I am using anchor point(0,0). Then I used the method with rectangleOfSize, center :

var cc = SKSpriteNode(color: UIColor.greenColor(), size: CGSizeMake(32, 64))
cc.physicsBody = SKPhysicsBody(rectangleOfSize: cc.size, center: CGPointMake(32/2, 64/2))

I hope it works for you too guys...thanks !

chiwangc
  • 3,566
  • 16
  • 26
  • 32
5

You need the anchorPoint only when you set your spriteNode's position. I don't quite understand why would you need to move physicsBody (which is the same size of node, I presume) to a corner... But you might find useful this class method [SKPhysicsBody bodyWithPolygonFromPath:path].

Here is a nice generator for that: http://dazchong.com/spritekit/

Maxiller
  • 166
  • 4
  • 3
    Neat tool, but it doesn't solve my problem. The problem is, the anchorPoint of the physics body appears to be the default width/2, height/2, even though I've set the anchorPoint of it's node to 0,0. – Sophie McCarrell Nov 18 '13 at 13:37
  • The physics body (via the call being made above) is created centered on the {0, 0} point of the sprite. If your {0, 0} point is not at the center of the sprite, the call is not useful. So, he wants to move the physics not *back from* the corner, not *too* it. You're call on the `bodyWithPolygonFromPath:` method is right on. – bshirley Jan 31 '14 at 19:54
2

I have run in to this myself when using SpriteKit. Unfortunately there appears to be issues based on the timing of creating a physics body and actually adding the node to the scene. If you swap the order from your code and ensure you don't do ANY physics changes until the node is actually in the render tree, that should resolve the 'weirdness' and everything will be all gravy.

Sam
  • 2,579
  • 17
  • 27
  • Thanks bro - my head was seriously wrecked with a similar issue, node was being added at origin until I moved the physics allocation until after the position allocation – AndyOS Apr 14 '14 at 22:55
1

Swift 4.1

let centerPoint = CGPoint(x: house1.size.width / 2 - (house1.size.width * house1.anchorPoint.x), y: house1.size.height / 2 - (house1.size.height * house1.anchorPoint.y))

house1.physicsBody = SKPhysicsBody(rectangleOf: house1.size, center: centerPoint)

uplearned.com
  • 3,393
  • 5
  • 44
  • 59
0

Use default anchor point and it should solve your problem. I had the same problem and I had to programmatically set anchor point to x: 0.5 and y: 0.5 for every physics body in scene. This solved my problems.