在不缩小内容的情况下调整精灵的大小

我用UIBezierPath创build了一个大圆圈,并使用它将其转换为Sprite,

let path = UIBezierPath(arcCenter: CGPoint(x: 0, y: 0), radius: CGFloat(226), startAngle: 0.0, endAngle: CGFloat(M_PI * 2), clockwise: false) // create a shape from the path and customize it let shape = SKShapeNode(path: path.cgPath) shape.lineWidth = 20 shape.position = center shape.strokeColor = UIColor(red:0.98, green:0.99, blue:0.99, alpha:1.00) let trackViewTexture = self.view!.texture(from: shape, crop: outerPath.bounds) let trackViewSprite = SKSpriteNode(texture: trackViewTexture) trackViewSprite.physicsBody = SKPhysicsBody(edgeChainFrom: innerPath.cgPath) self.addChild(trackViewSprite) 

它工作正常。 它完美地创造了这个圈子。 但我需要调整它使用

 SKAction.resize(byWidth: -43, height: -43, duration: 0.3) 

这会使它变小一点。 但是,当它调整我现在设置的20行宽度是因为方面填充非常小。 所以当我眨眼的时候,看起来像这样:

在这里输入图像说明

但我需要这样缩小 – 保持20行的宽度:

在这里输入图像说明

我将如何做到这一点?

不知道这是否会影响到任何东西,但是这些精灵永远都在旋转SKAction

– 编辑 – 现在,我如何使用这种方法来缩放到一个特定的大小? 像转226×226到183×183?

由于缩小了圆,不仅缩放了半径,而且缩放了线的宽度,所以需要设置与缩放成比例的新线宽。 例如,当向下缩放圆2时,您需要将lineWidth加倍。

这可以通过两种方式来完成:

  1. run(SKAction, completion: @escaping () -> Void)的完成块run(SKAction, completion: @escaping () -> Void)方法中设置lineWidth。 但是,这将导致在animation运行时看到缩小的线条,然后在animation完成后跳到新的宽度。 如果你的animation很短,这可能不容易观察到困难。

  2. 与缩放比例一起运行并行animation,它会不断调整lineWidth。 为此,您可以使用SKAction的customAction方法。 这里是你的情况的一个例子:

     let scale = CGFloat(0.5) let finalLineWidth = initialLineWidth / scale let animationDuration = 1.0 let scaleAction = SKAction.scale(by: scale, duration: animationDuration) let lineWidthAction = SKAction.customAction(withDuration: animationDuration) { (shapeNode, time) in if let shape = shapeNode as? SKShapeNode { let progress = time / CGFloat(animationDuration) shape.lineWidth = initialLineWidth + progress * (finalLineWidth - initialLineWidth) } } let group = SKAction.group([scaleAction, lineWidthAction]) shape.run(group) 

在这个例子中,你的形状将被缩放0.5,因此,如果初始线宽为10,最终的宽度将是20.首先我们创build一个具有指定持续时间的scaleAction,然后是一个自定义动作,它将更新线的宽度每次调用actionBlock ,通过使用animation的进度使行的宽度看起来像不变。 最后,我们将这两个操作分组,以便在调用run并行run

作为提示,您不需要使用Bezierpath来创build圆, init(circleOfRadius: CGFloat)有一个init(circleOfRadius: CGFloat)初始值设定项,为您创build一个圆。