ios - SpriteKit applyImpulse 不影响 Sprite

标签 ios swift sprite-kit skphysicsbody

我有一个 Skier 类型的播放器节点,我想通过触摸和拖动围绕 x 轴移动,类似于 this tutorial .我将我的播放器节点添加到场景中,它有一个 isDynamic 设置为 true 的物理体,但由于某种原因,当我触摸并拖动播放器时,它不会移动。我究竟做错了什么?这是我的 GameScene 和我的 Skier 类:

滑雪者:

class Skier: SKSpriteNode {
    let playerTexture = SKTexture(imageNamed: "snowmanFancy_NE")
    let playerSize = CGSize(width: 24, height: 40)

    init () {
        super.init(texture: playerTexture, color: UIColor.clear, size: playerSize)
        self.name = "player"
        setPhysics()
    }

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

    func setPhysics(){
        self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        self.physicsBody? = SKPhysicsBody(rectangleOf: size)
        self.physicsBody?.categoryBitMask = PhysicsCategory.player
        self.physicsBody?.contactTestBitMask = PhysicsCategory.tree | 
        PhysicsCategory.rock | PhysicsCategory.cabin | PhysicsCategory.snowman | 
        PhysicsCategory.marker
        self.physicsBody?.collisionBitMask = 0
        self.physicsBody?.allowsRotation = false
        self.physicsBody?.angularDamping = 0
        self.physicsBody?.isDynamic = true
    }
}

游戏场景:

class GameScene: SKScene, SKPhysicsContactDelegate {
    var lastTouch: CGPoint? = nil

    var world = SKNode()
    var cam = SKCameraNode()

    var player = Skier()
    let playerDefaultYInset : CGFloat = 350

    var sceneVelocity = CGVector(dx: 0, dy: -170)
    var zPositionCounter: CGFloat = 0

    override func didMove(to view: SKView) {
        //Set up the scene
        self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        backgroundColor = SKColor.white

        //Add top-level world node to the scene
        self.addChild(world)

        self.physicsWorld.contactDelegate = self

        //Add player to scene
        spawnPlayer()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
        if let location = touch?.location(in: self) {
            lastTouch = location
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
        if let location = touch?.location(in: self) {
            lastTouch = location
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        lastTouch = nil
    }

    override func update(_ currentTime: TimeInterval) {
        // Only add an impulse if there's a lastTouch stored
        if let touch = lastTouch {
            let impulseVector = CGVector(dx: touch.x - player.position.x, dy: 0)
            // If myShip starts moving too fast or too slow, you can multiply impulseVector by a constant or clamp its range
            player.physicsBody?.applyImpulse(impulseVector)
        }
    }

    func spawnPlayer() {
        player.position = CGPoint(x: 0, y: (-self.frame.height / 2) + playerDefaultYInset)
        player.zPosition = CGFloat(Int.min)
        world.addChild(player)
    }
}

最佳答案

我发现我做错了什么。当我为 Skier 类设置我的物理体时,我像这样分配了一个可选的物理体:

self.physicsBody? = SKPhysicsBody(rectangleOf: size)

所以物理体实际上并没有分配给 sprite。我通过将其更改为此来修复它:

self.physicsBody = SKPhysicsBody(rectangleOf: playerSize)

现在它完美运行了。话虽这么说,对于任何其他试图通过手指拖动在场景中移动 Sprite 来实现类似效果的人来说,我最终想出了一个更简单的解决方案。我的 touchesMoved 方法中有这个:

let touch = touches.first
    if let location = touch?.location(in: self) {
        let prev = touch?.previousLocation(in: self)
        let impulse = CGVector(dx: 0.02 * (location.x - (prev?.x)!), dy: 0)
        player.physicsBody?.applyImpulse(impulse)
}

它的工作原理完全不必担心更新、touchesBegan 或 touchesEnded 方法。更简单、更容易。

关于ios - SpriteKit applyImpulse 不影响 Sprite ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54780380/

相关文章:

ios - Cocos2d和iphone 5显示

jquery - 首次运行应用程序时不会触发 PhoneGap Deviceready (iOS)

swift - NSWorkspace setDesktopImageURL 适合屏幕

ios - SpriteKit - 动画 SKShapeNode 形状路径

swift - 使物体在特定区域下落速度变慢 - Sprite 套件

swift - 如何在 SpriteKit 的自上而下 View 中检测游戏结束无尽的 runner 游戏

ios - 文本文件内容问题

ios - 通过键盘应用程序或 iMessage 应用程序截取屏幕截图

ios - 如何使 Sprite 节点的纹理变暗

ios - 如何使用 json 中的可变数组填充我的 tableview