斯威夫特|我试图旋转精灵并在我点击时改变旋转的方向

时间:2015-04-23 11:08:25

标签: swift sprite-kit

我想无限期地旋转一个精灵,每次点击按钮,我都希望精灵以相反的方向旋转(从顺时针到逆时针等来回旋转等。

以下是我的代码:

http://pastebin.com/Avj8Njwt

class GameScene: SKScene {

    var center = SKSpriteNode()
    var bg = SKSpriteNode()
    var bigCircle = SKSpriteNode()
    let counterClockwise = SKAction.rotateByAngle(CGFloat(3.14), duration:1)
    let clockwise = SKAction.rotateByAngle(CGFloat(-3.14), duration:1)
    var spin = SKAction()


    override func didMoveToView(view: SKView) {

//Background
        var bgTexture = SKTexture(imageNamed: "images/bg.png")
        bg = SKSpriteNode(texture:bgTexture)
        bg.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        self.addChild(center)

//Center Circle
        var bigCircleTexture = SKTexture(imageNamed: "images/bigCircle.png")
        bigCircle = SKSpriteNode(texture:bigCircleTexture)
        bigCircle.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        self.addChild(bigCircle)

//Center Triangle
        var centerTexture = SKTexture(imageNamed: "images/center.png")
        center = SKSpriteNode(texture:centerTexture)
        center.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        self.addChild(center)
        spin = clockwise
        center.runAction(SKAction.repeatActionForever(spin))
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        /* Called when a touch begins */
        if spin == clockwise  {
            spin = counterClockwise

        }

        else {
            spin  = clockwise
        }
        center.runAction(SKAction.repeatActionForever(spin))
}


    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
    }
}

4 个答案:

答案 0 :(得分:1)

您的问题是,您没有删除尝试轮换SKAction的旧版SKSpriteNode。要做到这一点,你需要跟踪你的精灵旋转的方式。如果我要实现这个,我会继承SKSpriteNode,如下:

class RotatingSprite: SKSpriteNode {
    // This is used to keep track of which way the sprite is rotating.
    enum Direction {
        case Left, Right

        mutating func inverse() {
            switch self {
                case .Left : self = .Right
                case .Right: self = .Left
            }
        }
    }

    // These names will be the keys used when running an action.
    // This will allow you to stop the rotate-left or rotate-right actions.
    static let rotateLeftName  = "RotateLeftAction"
    static let rotateRightName = "RotateRightAction"

    var rotationDirection: Direction? {
        didSet {
            if let r = rotationDirection {
                switch r {
                    // Checks the sprite isn't already rotating to the left.
                    // If it isn't, make the sprite rotate to the left.
                    case .Left where oldValue != .Left:
                        rotateLeft()
                    case .Right where oldValue != .Right:
                        rotateRight()
                    default:
                        break
                }
            }
        }
    }

    private func rotateLeft() {
        // Remove the action rotating the sprite to the right.
        self.removeActionForKey(RotatingSprite.rotateRightName)
        // And start the action rotating the sprite to the left.
        let rotateAction = SKAction.rotateByAngle(-CGFloat(M_PI), duration: 1.0)
        self.runAction(SKAction.repeatActionForever(rotateAction), withKey: RotatingSprite.rotateLeftName)
    }

    private func rotateRight() {
        self.removeActionForKey(RotatingSprite.rotateLeftName)
        let rotateAction = SKAction.rotateByAngle(CGFloat(M_PI), duration: 1.0)
        self.runAction(SKAction.repeatActionForever(rotateAction), withKey: RotatingSprite.rotateRightName)
    }
}

现在你可以这样使用RotatingSprite

class GameScene: SKScene {
    let rotatingSprite = RotatingSprite(texture:bgTexture)

    override func didMoveToView(view: SKView) {
        rotatingSprite.position = CGPoint(x: frame.midX, y: frame.midY)
        self.addChild(rotatingSprite)
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        // If the sprite isn't turning you've got to set it off.
        if rotatingSprite.rotationDirection == nil {
            rotatingSprite.rotationDirection = .Left

        // If it is turning, change its direction.
        } else {
            rotatingSprite.rotationDirection!.inverse()
        }
    }
}

希望有所帮助!

答案 1 :(得分:1)

实现这一目标非常容易。试试这个,

 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */

    [sprite removeAllActions];

     SKAction *action;
    if (isClockWise)
    {

        action = [SKAction rotateByAngle:M_PI duration:1];
    }
    else
    {
        action = [SKAction rotateByAngle:-M_PI duration:1];
    }

   isClockWise = !isClockWise;
    [sprite runAction:[SKAction repeatActionForever:action]];

}

其中精灵是SKSpriteNode并根据您的初始移动方向将isClockWise启动为是或否。

答案 2 :(得分:0)

执行此操作的快速而肮脏的方法如下:

import SpriteKit

class GameScene: SKScene {

    var center = SKSpriteNode()
    var bg = SKSpriteNode()
    var bigCircle = SKSpriteNode()
    let counterClockwise = SKAction.rotateByAngle(CGFloat(3.14), duration:1)
    let clockwise = SKAction.rotateByAngle(CGFloat(-3.14), duration:1)
    var spin = SKAction()

    // this is used to identify which direction we are going in. When we change it spin is changed as well
    var isClockwise: Bool = true {
        didSet {
            if isClockwise {
                spin = clockwise
            } else {
                spin = counterClockwise
            }
        }
    }

    let actionKey = "spin" // this is used to identify the SKAction

    override func didMoveToView(view: SKView) {
        //Background
        var bgTexture = SKTexture(imageNamed: "images/bg.png")
        bg = SKSpriteNode(texture:bgTexture)
        bg.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        self.addChild(center)

        //Center Circle
        var bigCircleTexture = SKTexture(imageNamed: "images/bigCircle.png")
        bigCircle = SKSpriteNode(texture:bigCircleTexture)
        bigCircle.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        self.addChild(bigCircle)

        //Center Triangle
        var centerTexture = SKTexture(imageNamed: "images/center.png")
        center = SKSpriteNode(texture:centerTexture)
        center.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        self.addChild(center)
        isClockwise = true // set the initial direction to clockwise
        center.runAction(SKAction.repeatActionForever(spin), withKey: actionKey)
    }

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        // remove the existing spin action
        center.removeActionForKey(actionKey)

        // reset the direction (this will automatically switch the SKAction)
        isClockwise = !isClockwise

        center.runAction(SKAction.repeatActionForever(spin), withKey: actionKey)
    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
    }
}

您需要在应用新操作之前删除操作 - 您可以通过调用runAction(action:,withKey :)来有选择地删除操作。这使您能够使用相同的键删除相同的操作。对于spin var声明,更改didSet的逻辑位于isClockwise

答案 3 :(得分:0)

就像在每个if语句中放置center.removeAllActions一样简单,以确保当方向应该被更改时,精灵当前没有移动。