Outline path of a image/silhouette in Swift - ios

I'm working on a game in Xcode/Swift for iPad/iPhone.
What I need to do is to get the outline path of an image/silhouette, so that I can animate along the outline of the image/silhouette. This to create a laser cutting like effect, the one you see in movies when they break through a door/window with a lasercutter.
Just drawing it as a Beizer path won't work since I need to do this for a bunch of images/silhouettes. If possible I would prefer just to add images to my project and do the outlining in code, that way I can easily expand with more shapes and sizes.
In SpriteKit I've tried to use a SKPhysicsBody and then use the Alpha to create the outline. This gives me that outline but not as a path, so I can't animate along that line.
Actually when enabling ".showsPhysics" I get the line I need, but still not a line I can use for animations.
Is there a way to get to use/modify the ".showsPhysics" method or to reverse the PhysicsBody to a path?
I'm coding in Swift, and any advice would be appreciated.
This is an example of what I need, I need the blue line as a path for animation.

SpriteKit has a method to create a physics body from the contents of a texture. Read bodyWithTexture:size: for more information, especially the Discussion session. You should consider the balance between the performance and the accuracy.
Given an image below, here's a simple example to use bodyWithTexture:size:,
let texture = SKTexture(imageNamed: "rex")
let rex = SKSpriteNode(imageNamed: "rex")
rex.physicsBody = SKPhysicsBody(texture: texture, size: texture.size())
rex.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));
rex.physicsBody?.dynamic = false // This line is just for demo
self.addChild(rex)
Image:
Result:

Related

Most efficient way to change color of part of a skspritenode

So I know how to change the color of the entire sprite node but is there a way to say change the color of only the arms of a character or is the only way to do this through assigning the sprite a new image with the appropriate color? Thanks for the help in advance.
The only way to change the color of only a part of a SKSpriteNode can only be done with other nodes involved. But I only recommend this if the area you are changing color of is simple, such as a rect or circle. To do this, I also recommend you use a SKNode to wrap its child nodes.
For example:
var character = SKNode()
var characterImage = SKSpriteNode(imageNamed:"yourImage.png")
//Set sizes, anchor points, what not
character.addChild(characterImage)
var colorChanger = SKSpriteNode(color: yourColor, size: size of arms or whatever)
//Set position -> (colorChange.position)
colorChanger.name = "colorizer"
character.addChild(colorChanger )
With this, you can also change the color of the arms whenever you want, using childNode(withName:) to access colorChanger.
But, if the arms are to complicated, you do have to use separate images. Using a SKNode to then wrap these images is recommended as well.
PS: If you're new to Swift and Spritekit, the reason it's better to use SKNodes as wrappers is because it makes it much easier to move them, rotate them, etc, because you just need to change the location, rotation, etc, of one node instead of many.
I'm not aware of any way to change the color property of a specific part of the same SKSpriteNode. Something you could do is to make textures of the colors you need the sprite to be and change the texture property instead of the color.

Swift Spritekit - Problems adding the same sprite to the scene if one is already added

My SKScene uses the following code to add sprites to the screen at certain time intervals, but if there is already a sprite on the screen when the next one is added my application freezes. Is there a way to add the same sprite to the screen without the application freezing?
let timer = SKAction.waitForDuration(1.00)
let addSpriteNode = SKAction.runBlock{
self.addSprite()
}
let sequence = SKAction.sequence([timer, addSpriteNode])
self.runAction(SKAction.repeatActionForever(sequence), withKey: "Sprites")
Note: I am not currently at a computer that is capable of running Xcode, so I'm going off of memory.
Note 2: If I could comment, I would ask you to include the code located in the addSprite function. However, due to a lack of reputation, I am unable to do so. You could get a much faster and accurate answer by including that code, since that is the code that creates and adds the sprite.
Answer:
You mention that you are attempting to add the same sprite to the screen - possibly like this:
let sprite = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(50,50))
func addSprite() {
addChild(sprite)
}
You can not have the same sprite on the screen multiple times. Instead, each time you want a new sprite to be added to the screen, you have to create a new sprite. In your addSprite function, your code should create a new sprite, set it's properties, and then add it to the main view, as so:
fun addSprite() {
let sprite = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(50,50)) // Creates a new sprite. You can customize this as needed.
addChild(sprite) // Adds newly created sprite to screen.
}
I hope this helps. If you post your code, I could provide an answer more tuned to your question.

Fit borders to "real" image, cut of white borders SpriteKit objective c

I am learning Spritekit right now and I want to detect a collision between two images.
Just a fun picture as an example :
The image is still a rectangle. How can I fit it that this rectangle will fit to the original face? I don't want the collision early when it hits the rectangle of the Image, I want it to collide when it actually hits the black lines of the face.
I hope you can understand my problem.
Thanks for any help.
EDIT:
There are two issues here:
You probably want to set up your SKPhysicsBody to be a path around your SKSpriteNode. For example, something like the following is close:
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-40, -22, 80, 39)];
node.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path.CGPath];
That's probably not quite right, so feel free to tweak those values, but hopefully it illustrates the idea: Come up with a path that defines your boundary, and then set the physicsBody accordingly.
If you want to see the physics outlines, set showsPhysics on the SKView.
You probably want to mask your image so that the corners of the image are transparent (i.e. have an alpha of zero):
So, when that's on a colored background it looks like:
By masking the corners, you don't have to worry about the white corner covering up something else on the scene.
If its an image thats got white borders all around it, u can edit it in Preview and use Alpha to get rid of all of the white around it.
I think in that case, the sprite's collision method will collide with the black lines.

iOS Swift SpriteKit Achieving a sprite "explosion" effect

In my game I would like that when a collision occurs, the designated sprite would undergo an "explosion" or "glass break" effect, in which the sprite is split up into random pieces which are then moved at a random rate, speed, and angle. I would imagine that something like this may require using particles or at the very a least texture atlas.
I found a little bit on this, but the questions/explantations were catered for Objective-C. I am fairly new to iOS development and have solely used swift, so I can't really translate from one language to another. Thanks.
I would suggest you to try using the SpriteKit Emitter class for this. Add a new SpriteKit Particle Effect file to the project and configure the type of explosion there. You do not need any code, to configure it as Apple has very conveniently provided an editor window for us to easily change the values.
Once you are satisfied with the way the emitter looks, you can then open the Game Scene (assuming that is where this collision would be detected) and type:
let explosionEmitterNode = SKEmitterNode(fileNamed:"the file name")
sprite.addChild(explosionEmitterNode)
Here sprite is the actual node to which you would like to add the emitter effect to. Or you could add it to the scene directly and set its position as:
let explosionEmitterNode = SKEmitterNode(fileNamed:"the file name")
explosionEmitterNode.position = CGPointMake(200,300)
addChild(explosionEmitterNode)

Swift SpriteKit making physicsbody from texture of an image slows down my app too much

I'm trying to make an iOS app that includes some collision detection between two physics bodies. I want one of the physics bodies to be the shape of an image I am using, but when I try to do this using a texture it slows my app down tremendously and eventually causes it to freeze altogether. These are the two lines of code that are causing it:
let texture = SKTexture(imageNamed: "image.png")
physicsBody = SKPhysicsBody(texture: texture, size: size)
however, if I change these two lines to something like
physicsBody = SKPhysicsBody(rectangleOfSize: size)
then everything runs perfectly fine. Has anyone else had this problem and/or found a solution?
This may be due to the complex nature of your texture, but it's hard to tell without seeing it. As Whirlwind said, it probably shouldn't cause such a significant slowdown however it's difficult resolve without further information.
A way to get around creating the SKPhysicsBody from a texture would be to use an online tool for building the body from a path. I use this tool personally. It may be a decent work around.

Resources