SpriteKit SKEmitterNode Wont Change Size - ios

My SKEmitterNode in my game isnt changing size when I call its property particleSize.
let myParticle = SKEmitterNode(fileNamed: "MyParticle.sks")
myParticle?.particleSize = CGSize(width: 100, height: 100)
self.addChild(myParticle!)
My Particle still has its large rectangle size. Am I calling the wrong property or what? Any ideas or suggestions would be greatly appreciated! Thanks!

Try:
let myScale: CGFloat = 2 //2 = double dimension; 0.5 = half dimension
let myParticle = SKEmitterNode(fileNamed: "MyParticle.sks")
myParticle?.particleScale = myScale
self.addChild(myParticle!)

Related

Random place in frame

I am developing a small game but I'm stuck on this. I want to generate a random position for an SKSpriteNode called div. I have this code
let random = arc4random() % UInt32(self.frame.size.width)
let random1 = arc4random() % UInt32(self.frame.size.height)
div.position = CGPoint(x: Int(random), y: Int(random1))
self.addChild(div)
I can't figure out what's wrong and why the div is sometimes out of the frame and not visible. Does anyone has a good solution for this?
Any help is appreciated! Thanks!
try setting this in your didMoveToView,
self.size = view.bounds.size

Swift / SpriteKit help: Increase CGFloat continuously to allow continuous rotation around a fixed point

Im making a simple game with apple's SpriteKit and Swift and have encountered a problem. Im trying to get a paddle node (paddle) to rotate continuously around a fixed node (anchorNode) inside a circle; however, I cannot figure out how to make the paddle node (paddle) keep rotating around the fixed point node (anchorNode) because of the constrains in the SKAction.rotateByAngle statement making it end after a certain amount of time / rotation.
Any help is greatly appreciated!
Here is my code for reference:
//Setting up anchor Node
anchorNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
anchorNode.size.height = (self.frame.size.height / 1000)
anchorNode.size.width = anchorNode.size.height
self.addChild(anchorNode)
//Setting up achor Node's physucs
anchorNode.physicsBody = SKPhysicsBody(circleOfRadius: (circle.frame.size.height / 1000))
anchorNode.physicsBody?.dynamic = false
anchorNode.physicsBody?.affectedByGravity = false
anchorNode.physicsBody?.friction = 0
//Making the anchor Node rotate
let rotate = SKAction.rotateByAngle(CGFloat(3.14), duration: NSTimeInterval(1.5))
anchorNode.runAction(rotate)
//Setting up the paddle node
paddle.position = CGPointMake((circle.frame.width / 2), 0)
paddle.size.height = (self.frame.size.height / 50)
paddle.size.width = (self.frame.size.width / 7)
anchorNode.addChild(paddle)
Try adding this code.
override func update(currentTime: NSTimeInterval) {
//How to make it spin
let speed = CGFloat(5)
let degreeRotation = CDouble(speed) * M_PI / 180
paddle.zRotation -= CGFloat(degreeRotation)
}
Using this fixed my problem:
anchorNode.runAction(SKAction.repeatActionForever(rotate))
Thanks, User:
0x141E

swift: converting SKShapeNode into SKSpriteNode -> No texture

I'm trying to convert SKShapeNode into a Sprite node by first converting the SKShapeNode into a texture. However the results is invisible sprite. The Physics body is there normally but no graphics are being displayed. Something wrong with the way I try to convert the SKShapeNode, I suppose but I can't think of what. Do you have sense on what's wrong? ALL HELP APPRECIATED!
let createdShape = SKShapeNode(path: path)
createdShape.physicsBody = SKPhysicsBody(edgeLoopFromPath: createdShape.path)
createdShape.physicsBody?.categoryBitMask = PhysicsCategory.Shape
createdShape.physicsBody?.contactTestBitMask = PhysicsCategory.None
createdShape.name = "paintedArea"
createdShape.strokeColor = shapeBorderColor
createdShape.lineWidth = 5.0
createdShape.fillColor = shapeFillColor
createdShape.alpha = 1.0
createdShape.zPosition = shapeZPosition
let texture = view?.textureFromNode(createdShape)
println(texture?.description)
let sprite = SKSpriteNode(texture: texture)
sprite.physicsBody = createdShape.physicsBody
sprite.position = createdShape.position
sprite.color = UIColor.blueColor()
self.addChild(sprite)
Ahh I got it! My z-position was wrong! The created shape was on top of my backgrond image but the newly created sprite wasn't. Stupid of me...

SKEmitterNode updating speed of particles already released

Using SKEmitterNode in SprikeKit, is it possible to change the speed/alpha of particles after they are released?
What I'm looking for is a particle emitter that emits particles, those particles are static but after x amount of seconds, they start moving. Is this possible?
I wrote the answer in swift before i saw the objective-c tag.. hope thats okay.
heres my particle file so you can try it yourself:
DOWNLOAD
let emitter = SKEmitterNode(fileNamed: "fire")
emitter.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
let time = CGFloat(2)
emitter.runAction(SKAction.sequence([
SKAction.waitForDuration(3),
SKAction.customActionWithDuration(NSTimeInterval(time), actionBlock: {
_, t in
let timePercentage = t / time // percentage of elapsed time
let maxSpeed = CGFloat(200)
emitter.particleSpeed = timePercentage * maxSpeed
})
]))
self.addChild(emitter)
this code will allow you to animate your emitter's properties over time.

In SpriteKit on iOS, scaling a textured sprite produces an incorrect frame?

I'm learning SpriteKit game development for the fun of it & I've run across a seemingly simple problem that has me stumped.
Basically, after I scale a textured SKSpriteNode, the frame is NOT what I expect. I have figured out a few hacks to force it to what I want, but I'm trying to understand what is going on. Any ideas appreciated!
Here's my code WITHOUT SCALING:
func addSpaceship()
{
let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png")
spaceship.name = "spaceship"
// spaceship.setScale(0.50)
let debugFrame = SKShapeNode.init(rect: spaceship.frame)
debugFrame.strokeColor = SKColor.greenColor()
spaceship.addChild(debugFrame)
spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150)
self.addChild(spaceship)
}
And my app looks like this:
Now, if I comment back in the line of code which scales it (spaceship.setScale(0.50)), I get this:
Notice that the spaceship is scaled down in the second image, but the frame is scaled even smaller. Why?
If I move the scaling line to after I add the spaceship to the scene, it does what I expect, but that seems wrong:
Here's the code with setScale called after adding the spaceship to the scene:
func addSpaceship()
{
let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png")
spaceship.name = "spaceship"
let debugFrame = SKShapeNode.init(rect: spaceship.frame)
debugFrame.strokeColor = SKColor.greenColor()
spaceship.addChild(debugFrame)
spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150)
self.addChild(spaceship)
spaceship.setScale(0.50)
}
And here is what running my app looks like then:
So that works, but why is it necessary?
It has been suggested below, that this is a bug with SKShapeNode. But, replacing the SKShapeNode with an SKLabelNode has the same problem:
func addSpaceship()
{
let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png")
spaceship.name = "spaceship"
spaceship.setScale(0.50)
let scoreNode = SKLabelNode(text: "100")
scoreNode.position = CGPointMake(CGRectGetMidX(spaceship.frame), CGRectGetMaxY(spaceship.frame))
scoreNode.fontColor = SKColor.redColor()
scoreNode.fontSize = 15.0
scoreNode.fontName = "Monaco"
scoreNode.zPosition = 10.0
spaceship.addChild(scoreNode)
spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150)
self.addChild(spaceship)
}
which gives us:
The intent is to have the score label (scoreNode) centered above the rocket, but as you can see it is on top of the top porthole. There is just something wrong with the spaceship's frame after I call spaceship.setScale.
I have made one additional discovery: the setScale call does not need to be after I add the spaceship to the scene. It just needs to be after I add the debugFrame/scoreNode to the spaceship. If I setScale AFTER that point, all is well:
func addSpaceship()
{
let spaceship = SKSpriteNode.init(imageNamed: "rocketship.png")
spaceship.name = "spaceship"
let scoreNode = SKLabelNode(text: "100")
scoreNode.position = CGPointMake(CGRectGetMidX(spaceship.frame), CGRectGetMaxY(spaceship.frame))
scoreNode.fontColor = SKColor.redColor()
scoreNode.fontSize = 15.0
scoreNode.fontName = "Monaco"
scoreNode.zPosition = 10.0
spaceship.addChild(scoreNode)
spaceship.setScale(0.50)
spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150)
self.addChild(spaceship)
}
which results in:
Your problem may be in the order of these two lines :
spaceship.setScale(0.50)
let debugFrame = SKShapeNode.init(rect: spaceship.frame)
You scaled down the spaceship and then calculate the size of the rectangle with the scaled spaceship. Then when rendering the rectangle is scaled down to half its size which is quarter of the original spaceship size.
If you swap the lines, it should work as expected.
In general, it is better to make compose in the real size and then scale the whole just before adding it to the scene.
First of all, let me preface with SKShapeNode is a really funky (maybe buggy class). At least it was in previous iterations of spritekit. If your goal is to add a debug rectangle for physics purposes. You can turn on showsPhysics on your SKView class inside of your GameViewController
Heres my experiment
let redbox = SKSpriteNode(color: SKColor.redColor(), size: CGSize(width: 100, height: 100))
redbox.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
redbox.setScale(0.5)
let debugFrame = SKShapeNode(ellipseOfSize: redbox.size)
debugFrame.strokeColor = SKColor.greenColor()
self.addChild(redbox)
redbox.addChild(debugFrame)
looks same as yours. if i call setScale after i add the nodes then my circle fills up my red square.
Also if I keep everything the same, but I just add my debugframe to the scene directly it will be scaled the right way, weird huh??
ok another test. note I set greenbox to 50% of redboxes size so we can see the redbox beneath. If the bug was occuring here than greenbox would end up filling 25% of the redbox.
let redbox = SKSpriteNode(color: SKColor.redColor(), size: CGSize(width: 100, height: 100))
redbox.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
redbox.setScale(0.5)
let greenbox = SKSpriteNode(color: SKColor.greenColor(), size: CGSize(width: 50, height: 50))
self.addChild(redbox)
redbox.addChild(greenbox)
Ok so i did the same thing using another SKSpriteNode, and it behaves the way we'd expect. So for whatever reason, when you use an SKShapeNode as a child.. setScale is being called twice on it; unless you set the scale after adding the nodes to the scene. But this doesnt happen with SKSpriteNode.
The answer is.. I don't think there's a good answer. It's probably a bug. SKShapeNode has a history of bugs. SpriteKit has a few bugs =/ Someone correct me if I'm wrong.

Resources