平衡精灵

Balancing a sprite

所以我的问题是关于精灵的旋转。我希望它看起来像是在平衡。当您向左轻按时 - 精灵向左移动,当您向右轻按时 - 精灵向右移动。为了得到一个更好的主意,在它的末端放一支铅笔并尝试平衡它......是的......那个(但仅限于 x 轴)。

目前我正在顺时针或逆时针旋转精灵,具体取决于我是点击屏幕的左侧还是右侧。这一切都是使用 SKActions 完成的。

这样做的问题是它会导致非常 'jerky' 而不是特别逼真的运动。

我假设我想使用物理体和类似于速度的东西,但我的问题是:

提前致谢!

-- 代码 - 这就是我目前旋转和移动精灵的方式:

import SpriteKit
enum rotationDirection{
case clockwise
case counterClockwise
case none
}

   // Creates GameScene and initialises Sprites in Scene //
  class GameScene: SKScene, SKPhysicsContactDelegate {

   // Rotation direction variable for ship motion (rotation and movement) //
var currentRotationDirection = rotationDirection.none
var xVelocity: CGFloat = 0

var sprite = SKSpriteNode()



 // Setup Scene here //
     override func didMoveToView(view: SKView) {

    // Background colour //
    self.backgroundColor = SKColor.whiteColor()

    // sprite Physics + add's sprite //
    sprite.physicsBody = SKPhysicsBody(rectangleOfSize: ship.size)
    sprite.physicsBody?.affectedByGravity = true
    sprite.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
    self.addSprite()


  // Initialises sprite node and it's properties //
func addSprite() {

    // Sprite dimension properities //
    sprite.name = "sprite"
    sprite = SKSpriteNode(imageNamed: "sprite")
    sprite.setScale(0.5)
    sprite.position = CGPointMake(frame.midX, 220)
    sprite.anchorPoint = CGPoint(x: 0.5, y: 0.25)
    sprite.zPosition = 1;
    // sprite Physics properties //
    sprite.physicsBody = SKPhysicsBody(rectangleOfSize: ship.size)
    sprite.physicsBody?.categoryBitMask = UInt32(shipCategory)
    sprite.physicsBody?.dynamic = true
    sprite.physicsBody?.contactTestBitMask = UInt32(obstacleCategory)
    sprite.physicsBody?.collisionBitMask = 0
    self.addChild(sprite)





 override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {

    // Defines UI Touch //
    let touch = touches.first as UITouch!
    let touchPosition = touch.locationInNode(self)

    // Sets up Inital Rotation Direction //
    let newRotationDirection : rotationDirection = touchPosition.x < CGRectGetMidX(self.frame) ? .clockwise : .counterClockwise


    // Left or Right movement based on touch //
    if touchPosition.x < CGRectGetMidX(self.frame) {xVelocity = -75}
    else {xVelocity = 75}


    // Clockwise or anticlockwise rotation based on touch //
    if currentRotationDirection != newRotationDirection && currentRotationDirection != .none {
        reverseRotation()
        currentRotationDirection = newRotationDirection
    }
    else if (currentRotationDirection == .none) {
        setupRotationWith(direction: newRotationDirection)
        currentRotationDirection = newRotationDirection
    }
}

func reverseRotation() {
    let oldRotateAction = sprite.actionForKey("rotate")
    let newRotateAction = SKAction.reversedAction(oldRotateAction!)
    sprite.runAction(newRotateAction(), withKey: "rotate")
}


func stopRotation() {
    sprite.removeActionForKey("rotate")
}

 func setupRotationWith(direction direction: rotationDirection){
    let angle : CGFloat = (direction == .clockwise) ? CGFloat(M_PI) : -CGFloat(M_PI)
    let rotate = SKAction.rotateByAngle(angle, duration: 2)
    let repeatAction = SKAction.repeatActionForever(rotate)
    sprite.runAction(repeatAction, withKey: "rotate")
}

override func update(currentTime: CFTimeInterval) {
    let rate: CGFloat = 0.3; //Controls rate of motion. 1.0 instantaneous, 0.0 none.
    let relativeVelocity: CGVector = CGVector(dx:xVelocity-sprite.physicsBody!.velocity.dx, dy:0);
        sprite.physicsBody!.velocity=CGVector(dx:sprite.physicsBody!.velocity.dx+relativeVelocity.dx*rate, dy:0);
    }

我认为您要研究的是加速。现在您正在使用以下静态量调整 verlocityX:

if touchPosition.x < CGRectGetMidX(self.frame) {
    xVelocity = -75
}
else {
    xVelocity = 75
}

这样做会导致动作不稳。这实际上只是线性的。使用加速可以避免这种情况。

为此,您还需要 maxVelocityacceleration 两个变量。你可能想要一个 maxVelocity 来限制速度。每帧你都需要增加 velocity 的加速度。

我建议你尝试这样的事情:

velocity     = 0  // No movement
acceleration = 2  // Increase velocity with 2 each frame
maxVelocity  = 75 // The maximum velocity

if touchPosition.x < CGRectGetMidX(self.frame) {
    xVelocity += acceleration
    if xVelocity <= -maxVelocity {
        xVelocity = -maxVelocity 
    }
}
else {
    xVelocity -= acceleration
    if xVelocity >= maxSpeed {
        xVelocity = maxSpeed
    }
}

像这样提高速度将导致第一帧的旋转速度为 2,第二帧为 4,第三帧为 6,等等。因此它会产生增加的效果。与此同时,当你试图扭转它时,你也不会有生涩的效果。假设速度为 50,您首先将其降低到 48、46、44 等。直到 0 点,您才真正开始以另一种方式旋转。