How to Add Skspritenode in a Loop

How to create SKSprite node one by one in For loop using Swift SpriteKit

all your doing in your code is making a loop that creates the nodes, any duration that you apply to those nodes in that loop will affect them all equally. You need an variable outside of the loop that gets incremented in the loop per instance of node.

var delay: Double = 1.0 

for i in 1 ... 10 {

self.run(.wait(forDuration: delay) {

self.stone[i - 1].position = CGPoint(x: 0 , y: -100)
self.stone[i - 1].anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.stone[i - 1].size = CGSize(width: 50, height: 50)
self.stone[i - 1].physicsBody = SKPhysicsBody(circleOfRadius: 20)
self.stone[i - 1].physicsBody!.affectedByGravity = false
self.stone[i - 1].physicsBody!.categoryBitMask = PhysicsCategory.Object1
self.stone[i - 1].zPosition = 2
self.addChild(self.stone[i - 1])

let actionMove = SKAction.move(to: CGPoint(x: 0, y: 0), duration: 0.3)
let actionRolling = SKAction.animate(with: stone[i - 1].arrayTexture, timePerFrame: 0.05)
let actionDelay = SKAction.wait(forDuration: 1.0)
let actionSequence = SKAction.sequence([actionMove,actionRolling,actionDelay])
stone[i - 1].run(actionSequence)
}

delay += 1.0
}

How to create a variable for a SKSpriteNode that was created in a while loop, for the purpose of checking the sprite for a touch

Your "x" variable is float, so probably your names are look like "0.0","1.0"...
Change this code: var x = 0.0 to var x:Int = 0
And probably you will have to change your anchor point code to this:

sprite.anchorPoint = CGPoint(x: 2.0 - 2 * CGFloat(x), y: 3)

Moving a SKSpriteNode in a downward loop, using Swift

I've put together some sample code which you can adapt for your purposes. I've based the code off the equation for an Archimedean Spiral:

r = a + bθ

Where a is the starting radius; b is the radius the spiral will increase by per revolution and θ is the current angle.

A spiral is basically a glorified circle (IMO), so to move your node in a spiral you need to be able to calculate point on a circle using an angle, radius and center point:

func pointOnCircle(#angle: CGFloat, #radius: CGFloat, #center: CGPoint) -> CGPoint {
return CGPoint(x: center.x + radius * cos(angle),
y: center.y + radius * sin(angle))
}

Next, extend SKAction so you can easily create a spiral action:

extension SKAction {
static func spiral(#startRadius: CGFloat, endRadius: CGFloat, angle
totalAngle: CGFloat, centerPoint: CGPoint, duration: NSTimeInterval) -> SKAction {

// The distance the node will travel away from/towards the
// center point, per revolution.
let radiusPerRevolution = (endRadius - startRadius) / totalAngle

let action = SKAction.customActionWithDuration(duration) { node, time in
// The current angle the node is at.
let θ = totalAngle * time / CGFloat(duration)

// The equation, r = a + bθ
let radius = startRadius + radiusPerRevolution * θ

node.position = pointOnCircle(angle: θ, radius: radius, center: centerPoint)
}

return action
}
}

Finally, an example of use. In didMoveToView:

let node = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 10, height: 10))
node.position = CGPoint(x: size.width / 2, y: size.height / 2)
addChild(node)

let spiral = SKAction.spiral(startRadius: size.width / 2,
endRadius: 0,
angle: CGFloat(M_PI) * 2,
centerPoint: node.position,
duration: 5.0)

node.runAction(spiral)

Loop through all children of an SKNode?

You can simply enumerate parentNode.children:

for child in parentNode.children as! [SKNode] {
// ...
}

If necessary, check each child if it is actually a SKSpriteNode:

for child in parentNode.children {
if let spriteNode = child as? SKSpriteNode {
// ...
}
}

As of Swift 2 (Xcode 7), enumeration and optional cast can be combined with to a for-loop with a case-pattern:

for case let child as SKSpriteNode in parentNode.children {
// ...
}

SpriteKit for loop

If I understand your question correctly, here's the answer. Based on this code:

for var row = 1; row <= kInvaderRowCount; row++ // start of loop
{
var invaderType: InvaderType // varible of atype etc
if row % 3 == 0
{
invaderType = .AType
} else if row % 3 == 1

The first line means:

var row = 1: given a new variable, row, with a value of 1

row <= kInvaderRowCount: as long as the variable row is less than or equal to kInvaderRowCount, keep running the for loop

row++: after each time the loop is run, increment (increase) the value of row by 1

As for the "%", that is the modulo operator. It returns the remainder after a division operation on integer values. So if 7 divided by 3 = 2, with a remainder of 1, then

7 / 3 = 2

7 % 3 = 1

The modulus operator results in an integer. While 1 / 3 = 0.33..., 1 % 3 = 1. Because the remainder of 1 divided by 3 is 1.

1 % 3 = 1

2 % 3 = 2

3 % 3 = 0

4 % 3 = 1

5 % 3 = 2

6 % 3 = 0

see also: How Does Modulus Divison Work.

Adding multiple sprite nodes to the scene using single function/method in swift

Either way is acceptable solution. Here are full details. In baseScene we create function createNodes and call that function in didMoveToView where nodeA1 is given position and added to the scene as shown below.

override func didMoveToView(view: SKView) {
let nodeA1Pos = CGPointMake(CGRectGetMidX(self.frame)/1.5, CGRectGetMidY(self.frame)/2.0)
nodeA1 = createNodes(imageNamed: "dot_1", name: "A1_Dot", pos: nodeA1Pos)
addChild(nodeA1)
}

Then in Level1Scene which is subclass of baseScene we just give a new position to nodeA1 which will override position originally set in baseScene:

override func didMoveToView(view: SKView) {
super.didMoveToView(view)
nodeA1.position = CGPointMake(CGRectGetMidX(self.frame)/1.3, CGRectGetMidY(self.frame)/0.67)
}

This way of subclassing saves a lot of time and code as only one function is used to generate all common sprite nodes.

All thanks to crashoverride777 !!!!



Related Topics



Leave a reply



Submit