如何将物理体添加到 SKAtlasTexture 或通过 Images.xcassets 创建动画?

How can I add a physics body to an SKAtlasTexture or create an animation through Images.xcassets?

我想制作一个汽车在路上行驶的小动画,所以我制作了一个包含 9 张不同图片的图集。这辆车看起来就像它的轮子在旋转,并且在行驶过程中有一点弹跳。我已经制作了一个带有图像的SKSpriteNode,并在其上添加了一个物理体,以便它可以跳跃并受重力影响。

所以我想知道如何将物理体添加到 SKAtlasTexture 或通过我的 image.xcassets 文件夹创建动画。我试图将 SKSpriteNode 更改为 SKAtlasTexture,但这显然不起作用,因为 SKAtlasTexture 中没有物理实体。这就是我所在的位置。任何建议或解决方案将不胜感激。

这里是我的部分代码:

class PlayScene: SKScene, SKPhysicsContactDelegate {

let road = SKSpriteNode(imageNamed: "road")
var origRoadPositionX = CGFloat(0)
var maxRoad = CGFloat(0)
var groundSpeed = 3
var carBaseLine = CGFloat(0)
let car = SKSpriteNode(imageNamed: "car")




enum ColliderType:UInt32{
    case car = 1
    case tower = 2
}



override func didMoveToView(view: SKView) {
    self.backgroundColor = UIColor(hex: 0x80E8FF)

    self.physicsWorld.contactDelegate = self
    //Car
    self.car.position = CGPointMake(CGRectGetMinX(self.frame)-20 + self.car.size.width, self.carBaseLine)
    self.car.physicsBody = SKPhysicsBody (rectangleOfSize: self.car.size)
    self.car.physicsBody?.allowsRotation = false
    self.car.physicsBody?.affectedByGravity = false
    self.car.physicsBody?.categoryBitMask = ColliderType.car.rawValue
    self.car.physicsBody?.contactTestBitMask = ColliderType.tower.rawValue
    self.car.physicsBody?.collisionBitMask = ColliderType.tower.rawValue
    self.addChild(car)

如果需要更多代码才能找到解决方案,请告诉我,我可以提供更多代码。

您可以使用 atlas 文件夹对图像进行动画处理。

考虑下面的例子:

import SpriteKit

class GameScene: SKScene {
    
    var bombFrames : [SKTexture]!
    var bomb : SKSpriteNode!
    let NoneCategory   : UInt32 = 0x1 << 0
    let ProjectileCategory  : UInt32 = 0x1 << 2
    let bombCategory : UInt32 = 0x1 << 7
    
    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        runAction(SKAction.repeatActionForever(SKAction.sequence([SKAction.runBlock(addBomb), SKAction.waitForDuration(5.0)])))
    }
    
   
    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
    }
    
    func addBomb() {
        
        let Name = "Bomb"
        let AnimatedAtlas = SKTextureAtlas(named: Name)
        var Framese = [SKTexture]()
        let numImages = AnimatedAtlas.textureNames.count
        for var i=1; i<=numImages; i++ {
            let TextureName = "\(i)"
            Framese.append(AnimatedAtlas.textureNamed(TextureName))
        }
        bombFrames = Framese
        
        let firstFrame = bombFrames[0]
        bomb = SKSpriteNode(texture: firstFrame)
        let actualY = random(min: bomb.size.height/2, max: size.height - bomb.size.height/2)
        bomb.position = CGPoint(x: size.width + bomb.size.width/2, y: actualY)
        bomb.physicsBody = SKPhysicsBody(texture: bomb.texture, size: bomb.texture!.size())
        bomb.physicsBody?.dynamic = true
        bomb.physicsBody?.categoryBitMask = bombCategory
        bomb.physicsBody?.contactTestBitMask = ProjectileCategory
        bomb.physicsBody?.collisionBitMask = NoneCategory
        bomb.physicsBody?.usesPreciseCollisionDetection = true
        addChild(bomb)
        
        let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))
        let actionMove = SKAction.moveTo(CGPoint(x: -bomb.size.width/2, y: actualY), duration: NSTimeInterval(actualDuration))
        let actionMoveDone = SKAction.removeFromParent()
        bomb.runAction(SKAction.sequence([actionMove, actionMoveDone]))
        playBombAnimation()
    }
    
    func random() -> CGFloat {
        return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
    }
    
    func random(#min: CGFloat, max: CGFloat) -> CGFloat {
        return random() * (max - min) + min
    }
    
    func playBombAnimation() {
        
        bomb.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(bombFrames, timePerFrame: 0.1, resize: false, restore: true)), withKey:"bombAnimation")
    }
}

并且不要忘记像这样将 atlas 文件夹添加到项目导航器中:

正如您在代码中看到的那样,您可以将物理体添加到您的精灵中。如果您愿意,可以尝试这种方式。

希望这会有所帮助。