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
How to Catch an Exception in Swift
Swift Protocol That Is Using an Enum with Generic Associated Type
Swift: Handling an Unexpected Nil Value, When Variable Is Not Optional
Restrictions Around Protocols and Generics in Swift
Nstimer Scheduledtimerwithtimeinterval and Target Is "Class Level Function"
Arkit - Place a Scnplane Between 2 Vector Points on a Plane in Swift 3
Macos Swift UI View Where There Is a Search Field in The Title Bar
Swiftui - Form with Error Message on Button Press and Navigation
Redirect Process Stdout to Apple System Log Facility in Swift
How to Insert UIlabel After UItextfield in UIalertcontroller
How to Hide The Top Bar (With Buttons) Usin Swift and Macos
How to Get a Popup Dialog Box in Swift Playgrounds
Cloudkit - What to Do When a User Adds, Modifies or Deletes an Object While Offline
How to Cut a Hole in a Sprite Image or Texture to Show What Is Behind It Using Spritekit in Swift