【问题标题】:How to make player move to opposite side while is in a path?如何让玩家在路径中移动到对面?
【发布时间】:2016-07-04 16:12:09
【问题描述】:

我希望当触摸开始时,玩家(红色圆圈)会移动到圆形路径的另一侧。我已经让玩家遵循了一条路径,但我还没有在互联网上找到我的问题的答案。

    override func didMoveToView(view: SKView) {

    player = SKSpriteNode(imageNamed: "circulo")
    player.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2 - 170)
    player.color = colorGris
    player.colorBlendFactor = 1
    player.size = CGSize(width: 25, height: 25)
    self.addChild(player)
    player.zPosition = 3

   }
   override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
   /* Called when a touch begins */

    if gameStarted == false {

        gameStarted = true
        moveClockWise()
        movingClockWise = true

    }

       }



   func moveClockWise(){



    let dx = player.position.x - self.frame.width / 2
    let dy = player.position.y - self.frame.height / 2

    let rad = atan2(dy, dx)

    path = UIBezierPath(arcCenter: CGPoint(x:self.frame.width / 2, y: self.frame.height / 2) , radius: 170, startAngle: rad, endAngle: rad + CGFloat(M_PI * 4), clockwise: true)

    let follow = SKAction.followPath(path.CGPath, asOffset: false, orientToPath: true, speed: 200)
    player.runAction(SKAction.repeatActionForever(follow).reversedAction())

}

【问题讨论】:

    标签: swift path sprite-kit move


    【解决方案1】:

    在圆形路径中移动对象的最简单方法之一是

    1. 创建一个SKNode 容器
    2. 创建一个精灵
    3. 将容器添加到场景中
    4. 将精灵的x 位置设置为圆形路径的半径
    5. 将精灵添加到容器中
    6. 旋转容器

    如果你想将精灵移动到另一边或改变旋转的半径,只需

    1. 更改精灵的x 位置

    如果你想改变旋转的方向,

    1. 反转容器的旋转

    示例代码:

    // 1) Create the container node 
    let node = SKNode()
    // 2) Create a sprite
    let sprite = SKSpriteNode(color:SKColor.blueColor(),size:CGSizeMake(20,20))
    var rotation:CGFloat = CGFloat(M_PI)
    let radius:CGFloat = 50
    
    override func didMoveToView(view: SKView) {
        scaleMode = .ResizeFill
        node.position = view.center
        // 3) Add the container to the scene
        addChild(node)
        // 4) Set the sprite's x position
        sprite.position = CGPointMake(radius, 0)
        // 5) Add the sprite to the container
        node.addChild(sprite)
        // 6) Rotate the container
        rotate()
    }
    
    // Rotate the container
    func rotate() {
        let action = SKAction.rotateByAngle(rotation, duration: 4)
        node.runAction(SKAction.repeatActionForever(action),withKey: "rotate")
    }
    
    // 8) Reverse the direction of the rotation
    func reverse() {
        rotation = -rotation
    }
    
    // Stop rotating the container
    func stopRotation() {
        if node.actionForKey("rotate") != nil {
            node.removeActionForKey("rotate")
        }
    }
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
       /* 7) Change the sprite's x-position  */
        if sprite.actionForKey("move") == nil {
            stopRotation()
            let opposite = -sprite.position.x * 2
            let move = SKAction.moveByX(opposite, y: 0, duration: 3)
            let rotate = SKAction.runBlock {
                self.rotate()
            }
            sprite.runAction(SKAction.sequence([move, rotate]), withKey: "move")
        }
    }
    

    【讨论】:

    • 如果我想添加另一个精灵,它也会旋转?
    • 如果将精灵添加到容器中,它将旋转。如果将其添加到场景中,则不会
    • 感谢 Epsilon,但现在我如何将它添加到中心?
    • 你想在中心添加什么?
    • sprite.position = view.center
    【解决方案2】:

    我认为您可以按照以下步骤操作:

    • 停止播放器的runAction

    你可以这样做:

    let follow = SKAction.followPath(path.CGPath, asOffset: false, orientToPath: true, speed: 200)
    player.runAction(SKAction.repeatActionForever(follow).reversedAction(),withKey:"followPath")
    

    停止做简单的事:

    player.removeActionForKey("followPath")
    
    • 重新构建您的路径以在实际位置上创建一个新的“moveToPoint”(起点):

    为此,我尝试使用您的代码使其易于理解:

    var myCircle : CGMutablePath! = CGPathCreateMutable()
    let newDx = player.position.x - self.frame.width / 2
    let newDy = player.position.y - self.frame.height / 2
    let newRad = atan2(newDy, newDx)
    let newPath = UIBezierPath(arcCenter: CGPoint(x:self.frame.width / 2, y: self.frame.height / 2) , radius: 170, startAngle: newRad, endAngle: newRad + CGFloat(M_PI * 4), clockwise: true)
    
    • 镜像路径:

    要做到这一点,你可以这样写:

    var mirroring = CGAffineTransformMakeScale(1.0, -1.0) // flip horizontal
    var mirrorPath : CGMutablePath! = CGPathCreateMutable()
    CGPathAddPath(mirrorPath, &mirroring, newPath.CGPath)
    
    • 重启runAction:

    在这里你可以重新启动:

    let newFollow = SKAction.followPath(mirrorPath, asOffset: false, orientToPath: true, speed: 200)
    player.runAction(SKAction.repeatActionForever(newFollow).reversedAction(),withKey:"followPath")
    

    加法: 如果您可以添加一些不错的动画,例如点位置和圆中镜像点之间的跳转,您需要知道CGPoint 目标(在 mirrorPath 中它将是“moveToPoint”或者也是第一个点)。 Here你可以找到一个扩展来获得所有CGPath点所以:

    var mirrorPoints = mirrorPath.getPathElementsPoints()
    let destinationPoint = mirrorPoints.first!
    

    在 Sprite-kit 框架中,可用的 SKAction's 之间还没有 jumpAction,因此您可以用很少的代码创建它。
    通常“跳跃”是通过改变 Y 坐标来实现的,在你的情况下你的视图是从高处看的,所以你可以做一个 zoomIn e zoomOut(缩放)。

    【讨论】:

    • 谢谢亚历山德罗!让我试试吧!
    • 对,我来了,你想问我的时候。
    • “镜像路径”无法将类型“CGAffine Transform”的值转换为预期的参数类型“不安全点”
    • 它一直在说
    • 是的,从 objc 到 swift 2 的转换有问题,现在看看,让我知道它是否有效..
    猜你喜欢
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    相关资源
    最近更新 更多