SpriteKit - 在 SKAction 期间精灵的正确位置

Posted

技术标签:

【中文标题】SpriteKit - 在 SKAction 期间精灵的正确位置【英文标题】:SpriteKit - correct location of sprites during SKAction 【发布时间】:2015-10-04 06:58:03 【问题描述】:

我正在编写一个具有连续(sdieways)滚动地形的应用程序,该地形由图像动态组成。所以我创建了一个精灵,将它侧向滚动,当它继续滚动时要显示其右边缘时,我在它的右侧添加了第二个精灵,它也会滚动,等等。当它们从左边消失时,它们'被删除。

问题是当我添加新精灵时,它与前一个精灵之间有一个小间隙(大约 4 px),好像在将它放在屏幕上的时间里,滚动动画移动了一些像素。

滚动类是这样的-

import UIKit
import SpriteKit


private let lagOffset: CGFloat = 4.0 // currently, this is the only way I can get rid of the gap between terrain blocks


class GameScene: SKScene

    private var terrainNumber = 2
    private var followingTerrainBlock: TerrainBlock? = .None


    override init(size: CGSize)
    
        super.init(size: size)

        // create the first terrain block

        let terrainBlock = TerrainBlock(size: Size.terrainBlock, terrainNumber: 1)
        terrainBlock.position = CGPoint(x: size.width / 2.0 + Size.terrainBlock.width, y: size.height / 2.0)

        addChild(terrainBlock)

        followingTerrainBlock = terrainBlock

        moveTerrainBlock(terrainBlock)
    

    required init?(coder aDecoder: NSCoder)
    
        fatalError("init(coder:) has not been implemented")
    


    func moveTerrainBlock(terrainBlock: TerrainBlock)
    
        // create the next terrain block on a background thread as it's quite expensive
        // it'll be ready in plenty of time for when it's needed

        GCD.async  () -> () in
            self.followingTerrainBlock = TerrainBlock(size: Size.terrainBlock, terrainNumber: self.terrainNumber)
        


        var targetX = size.width / 2.0
        let y = terrainBlock.position.y

        let move = SKAction.moveTo(CGPoint(x: targetX, y: y), duration: Time.terrainScroll)

        // move the terrain block to centre on the screen - at this point we add the following terrain block immediately behind it, off-screen
        // the scroll animation lasts 5 seconds before the completion closure runs, by which time self.followingTerrainBlock has been ready for ages 

        terrainBlock.runAction(move)  [weak self]() -> Void in

            if let strongSelf = self
            
                strongSelf.terrainNumber++

                // we have to put an offset into the position of the new terrain block, or there'll be a gap between the old & new blocks

                strongSelf.followingTerrainBlock!.position = CGPoint(x: targetX + Size.terrainBlock.width - lagOffset, y: y)
                strongSelf.addChild(strongSelf.followingTerrainBlock!)

                // now we tell the new terrain block to follow the existing one

                strongSelf.moveTerrainBlock(strongSelf.followingTerrainBlock!)


                // then we continue moving the existing terrain block until it's off-screen, then remove the sprite

                targetX -= Size.terrainBlock.width - lagOffset
                let move = SKAction.moveTo(CGPoint(x: targetX, y: y), duration: Time.terrainScroll)

                terrainBlock.runAction(move)  () -> Void in
                    terrainBlock.removeFromParent()
                
            
        
    

我想知道的是如何将以下地形块放在屏幕上,以便它们与前一个地形块的右边缘完全对齐。如果我停止动画并添加一个,没有偏移量的位置是正确的,所以位置计算没有问题。

【问题讨论】:

如何在 block1-block2-block3 之间创建一些约束(我猜是常数 = 0)。 我不知道你可以在 SpriteKit 中使用约束 - 我会研究一下 @Dustin - 这是正确的答案,如果您将其作为答案发布,我会接受。谢谢! 【参考方案1】:

当您创建每个块时,创建一个约束(常量 = 0)将其附加到前一个块...等等之后的每个块。

我相信随着每个块移出视图,约束也会解除分配,但您可能也必须考虑这部分。

【讨论】:

约束确实可以很好地解除分配,现在一切都正确排列。谢谢

以上是关于SpriteKit - 在 SKAction 期间精灵的正确位置的主要内容,如果未能解决你的问题,请参考以下文章

spritekit 如何在两个不同的节点上转换两个 SKAction

Spritekit Hexagonal map:SKAction 中的瓦片检测。

多个 SKSpriteNode 的 SpriteKit 多个 SKActions - 等待全部完成

如何防止 SKAction 序列在解码后重新启动?

SpriteKit 动画意外停止

减少 Spritekit 中的延迟