2014-09-28 113 views
1

我可以制作一个随机选择并从屏幕顶部到底部的SK节点数组。例如,假设我有25个左右不同的平台,这些平台将会在肖像iPhone上掉下来。我需要它从数组中随机选择一个平台开始,然后在一定时间/或像素空间之后随机选择另一个以继续相同的动作,直到达到底部等等。Im新到快速但有相当体面的了解它。我还没有找到如何创建一个SKsprite节点数组。有人可以帮忙吗?快速移动多个精灵节点

到目前为止,我已经能够获得任何类似于我想要的效果的唯一方法是将每个节点放在屏幕上并将它们添加到字典中,并使它们像这样移动

类ObstacleStatus {

var isMoving = false 
    var timeGapForNextRun = Int(0) 
    var currentInterval = Int(0) 
    init(isMoving: Bool, timeGapForNextRun: Int, currentInterval: Int) { 
     self.isMoving = isMoving 
     self.timeGapForNextRun = timeGapForNextRun 
     self.currentInterval = currentInterval 
} 

func shouldRunBlock() -> Bool { 
    return self.currentInterval > self.timeGapForNextRun 

} 

func moveBlocks(){ 
    for(blocks, ObstacleStatus) in self.blockStatuses { 
     var thisBlock = self.childNodeWithName(blocks) 
     var thisBlock2 = self.childNodeWithName(blocks) 
     if ObstacleStatus.shouldRunBlock() { 
      ObstacleStatus.timeGapForNextRun = randomNum() 
      ObstacleStatus.currentInterval = 0 
      ObstacleStatus.isMoving = true 
     } 

     if ObstacleStatus.isMoving { 
      if thisBlock?.position.y > blockMaxY{ 
        thisBlock?.position.y -= CGFloat(self.fallSpeed) 
      }else{ 
       thisBlock?.position.y = self.origBlockPosistionY 
       ObstacleStatus.isMoving = false 
      } 
     }else{ 
       ObstacleStatus.currentInterval++ 
      } 

    } 
} 

使用该用于该随机函数

func randomNum() -> Int{ 
return randomInt(50, max: 300)   
} 

func randomInt(min: Int, max:Int) -> Int { 
    return min + Int(arc4random_uniform(UInt32(max - min + 1))) 
} 

这一切对我来说都是以随机的时间间隔往下移动,但是增加随机数的最小或最大值并不会影响间隙的实际时间。我需要能够指定距离或时间差距。

+0

您应该添加您迄今尝试的内容。 – 2014-09-28 07:51:33

+0

增加了我用过的一些东西。 – Alex 2014-09-28 08:45:42

回答

1

许多可能的解决方案之一是创建一个递归调用自己的下降动作序列,直到没有剩下的平台节点。您可以控制平均“间隔时间”和其随机变化的范围。下面是一个工作示例(假设iOS SpriteKit游戏模板):

import SpriteKit 

extension Double { 
    var cg: CGFloat { return CGFloat(self) } 
} 

extension Int { 
    var cg: CGFloat { return CGFloat(self) } 
} 

func randomInt(range: Range<Int>) -> Int { 
    return range.startIndex + Int(arc4random_uniform(UInt32(range.endIndex - range.startIndex))) 
} 

extension Array { 
    func randomElement() -> Element? { 
     switch self.count { 
     case 0: return nil 
     default: return self[randomInt(0..<self.count)] 
     } 
    } 

    func apply<Ignore>(f: (T) -> (Ignore)) { 
     for e in self { f(e) } 
    } 
} 

class GameScene: SKScene { 

    var screenWidth: CGFloat { return UIScreen.mainScreen().bounds.size.width } 
    var screenHeight: CGFloat { return UIScreen.mainScreen().bounds.size.height } 

    let PlatformName = "Platform" 
    let FallenPlatformName = "FallenPlatform" 

    func createRectangularNode(#x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) -> SKShapeNode { 
     let rect = CGRect(x: x, y: y, width: width, height: height) 
     let path = UIBezierPath(rect: rect) 
     let node = SKShapeNode(path: path.CGPath) 
     return node 
    } 

    func createPlatformNodes(numNodes: Int, atHeight: CGFloat) -> [SKShapeNode] { 
     var padding = 20.cg 
     let width = (screenWidth - padding)/numNodes.cg - padding 
     padding = (screenWidth - width * numNodes.cg)/(numNodes.cg + 1) 
     let height = width/4 
     var nodes = [SKShapeNode]() 
     for x in stride(from: padding, to: numNodes.cg * (width + padding), by: width + padding) { 
      let node = createRectangularNode(x: x, y: atHeight, width: width, height: height) 
      node.fillColor = SKColor.blackColor() 
      node.name = PlatformName 
      nodes.append(node) 
     } 
     return nodes 
    } 

    func createFallingAction(#by: CGFloat, duration: NSTimeInterval, timeGap: NSTimeInterval, range: NSTimeInterval = 0) -> SKAction { 
     let gap = SKAction.waitForDuration(timeGap, withRange: range) 
//  let fall = SKAction.moveToY(toHeight, duration: duration) // moveToY appears to have a bug: behaves as moveBy 
     let fall = SKAction.moveByX(0, y: -by, duration: duration) 
     let next = SKAction.customActionWithDuration(0) { [unowned self] 
      node, time in 
      node.name = self.FallenPlatformName 
      self.fallNextNode() 
     } 
     return SKAction.sequence([gap, fall, next]) 
    } 

    func fallNextNode() { 
     if let nextNode = self[PlatformName].randomElement() as? SKShapeNode { 
      let falling = createFallingAction(by: screenHeight * 0.7, duration: 1, timeGap: 2.5, range: 2) // mean time gap and random range 
      nextNode.runAction(falling) 
     } else { 
      self.children.apply { ($0 as? SKShapeNode)?.fillColor = SKColor.redColor() } 
     } 
    } 

    override func didMoveToView(view: SKView) { 
     self.backgroundColor = SKColor.whiteColor() 
     for platform in createPlatformNodes(7, atHeight: screenHeight * 0.8) { 
      self.addChild(platform) 
     } 
     fallNextNode() 
    } 
} 
+0

谢谢你,那是我希望的更先进一点,我会试着弄清楚一切是如何运作的。 – Alex 2014-09-29 08:50:09

+0

如果您有关于代码的具体问题,请告知我。顺便说一下,您可以将其复制/粘贴到iOS SpriteKit游戏模板生成的默认GameScene代码的位置,然后您就可以看到它在运行。 – milos 2014-09-29 12:01:23