Does anyone have any guidance how to create a SpriteKit object that looks like a circle with circular physics properties? I've considered using SKShapeNode, yet after reading comments in documentation like this one "the SKSpriteNode class offers higher performance than this class, so use shape nodes sparingly" here https://developer.apple.com/documentation/spritekit/skshapenode, I'm reluctant to use SKShapeNode.
I have code to create an SKSpriteNode from image that makes it look like a circle...
sprite = SKSpriteNode(imageNamed:spriteImage)
...and I've applied a circular physics body...
sprite.physicsBody = SKPhysicsBody(circleOfRadius: (width / 2))
I've set properties such as allowrotation, affectedbygravity and isDynamic to true in the physics body...
physics = sprite.physicsBody
physics.affectedByGravity = true
physics.allowsRotation = true
physics.isDynamic = true
The circle SKSpriteNode still behaves like a square. Instead of rolling like a wheel, the object flops like a square.
cc was right. The original physics body was set to a circle, then at some point in the code the physics body was changed back into a square. I fixed that part of the code and it is working now. Thanks!
Related
I have a SKSpriteNode which has a PNG texture, partly transparent.
I want to make a logical split line on this sprite and then measure the volume or opaque pixel count in each part. The object of the exercise is to tell what percentage total sprite volume exists in each part.
I have done some research and came empty. Seems there are no built in methods to do so. Can you guide me in the right direction here?
you could create a "pixel perfect" SKPhysicsBody like this:
let sprite = SKSpriteNode(imageNamed: "Spaceship")
sprite.physicsBody = SKPhysicsBody(texture: sprite.texture!,
size: sprite.texture!.size())
And then access the property sprite.physicsBody.area which gives you the area of the body in square meters (you can convert it to points, here is the documentation)
I'm reasonably sure I've previously seen code somewhere that scales a SKPhysicsBody, but google and the docs aren't helping, making me more confused than normal.
Is there a way to scale a physic's body in SpriteKit?
The docs, here, don't mention anything about it: https://developer.apple.com/reference/spritekit/skphysicsbody
If you assign a physics body to a sprite and scale that sprite, the physics body will scale with it.
So the answer I think to your question is a solid "no"; at least not in anything I've seen before.
If you care to dabble in a workaround:
Create a new physics body that is larger than what you currently have. Make a method or two to accomplish this.
node.physicsBody = scaledPhysicsBody(bodyToScale: xxxx)
2.
I would just make a blank SKNode and child it to whatever it is that you want to be hit-detectable. Then get rid of the parent's physics body and just use the child's. Now, you can scale the child node (and thus the PB) without affecting the graphics of the main sprite.
just updating this in 2023:
if you create you physics body from the sprites texture, you can use the SKPhysicsBody initialiser with texture and size property like this:
let scale: CGFloat = 0.9
self.physicsBody = SKPhysicsBody(
texture: self.texture!,
size: CGSize(
width: self.size.width * scale,
height:self.size.height * scale
)
)
The sprite I use for my character looks something like this (pink = transparent part):
After I set physicsBody to my node with self.physicsBody = SKPhysicsBody(texture: self.texture!, size: self.size), and set my SKView to show physics, I get an outline like this:
Which is, basically, the right mask, stretched to fit the size of the image.
Is there any way to get a physicsBody exactly around my character?
After playing around for quite a while, I've found the solution:
It's weird, but giving the SKPhysicsBody initializer a new SKTexture made from the same image, used for creating the SKTexture of SKSpriteNode initializer, worked perfectly well for me.
It should work. It works in my code with this line:
self.physicsBody = SKPhysicsBody.init(texture: self.texture!, size: self.frame.size)
Are you sure you do not scale the sprite after the creation of the physics body?
I'm using an SKTexture with an image and set the SKPhysicsBody. Like that:
var moleTexture = SKTexture(imageNamed: "moleTop1")
leftPlayer = SKSpriteNode(texture: moleTexture)
leftPlayer.physicsBody = SKPhysicsBody(texture: moleTexture, size: leftPlayer.texture!.size())
Now after I start my game, I noticed that the physicsBody is set wrong. I've activated the showPhysics property and my image looks like that:
As you see, the only thing which is used by SKPhysicsBody is the little part on the middle left(blue border).
How can I change that so that the whole image will be used?
That looks interesting. I believe it will only create an outline (or one shape) and it appears to be starting from the left and because there are no other pixels near enough it calls it done.
I wonder if you get a different result if those pixels are touching. I would try and validate that first. If that is the case you may have to change the texture or use a different variation of the texture for the physical body.
I hope that helps =)
I am creating a game where user controls a cube (50x50px) and can collect more cubes while exploring and collected cubes added to a random side of the users current cubes.
User starting cube
http://s7.postimg.org/id95wms7r/cube.png
After user collected some more cubes
http://s13.postimg.org/oo9v4c9bb/morecubes.png
As you can already see from the second image, my problem is when I generate the body from texture, it has some offset with the original picture. Cube adding is random so you can get really weird shapes and those offsets are always different. My question is, is there a way to align that body with the parent sprite? Also I don't want to move the sprite because sprite is in the right place, I actually want to move the body.
This is how my code looks like. Both player and cubes are at CGPointZero in their own coordinate systems.
Player: SKNode
-- Cubes: SKSpriteNode
physicsBody = SKPhysicsBody(texture: cubes.texture, size: accumulatedSize)
physicsBody?.dynamic = true
physicsBody?.mass = 2.0
physicsBody?.allowsRotation = false
Instead of creating the SKPhysicsBody from the texture, create an SKPhysicsBody for each individual cube, then put all those individual bodies into an array, and then create the SKPhysicsBody from the bodies in that array using:
(SKPhysicsBody *)bodyWithBodies:(NSArray *)bodies
That will get you a more accurate body with the sprite.
"The shapes of the physics bodies passed into this method are used to create a new physics body whose covered area is the union of the areas of its children" (from the SKPhysicsBody Class Reference).