ApplyImpulse对推动对象的程度有指数影响

时间:2017-11-24 09:42:49

标签: ios swift sprite-kit skphysicsbody skphysicsworld

在这个简单的物理模拟中,有一些奇怪的行为。 applyImpulse每5秒应用一次,但每次发生这种情况时,即使相同的值用于applyImpulse,框也会更高。大约20秒后,盒子的拍摄速度非常高。

盒子上附有一个小红框,这是施加冲动的地方。

照片被捕:

这是代码:

import SpriteKit

enum collisionType: UInt32 {
    case obj = 0b1 //1
    case bottom = 0b10 //2
}

var cam: SKCameraNode?
var screenSize = CGSize()

class GameScene: SKScene, SKPhysicsContactDelegate {

    let obj = SKSpriteNode(color: .white, size: CGSize(width: 50, height: 50))
    var camBottom = SKSpriteNode()
    let block = SKSpriteNode(color: .red, size: CGSize(width: 25, height: 25))

然后在override func didMove(to view: SKView)

    screenSize = self.size
    camBottom = SKSpriteNode(color: .gray, size: CGSize(width: ((3/2) * screenSize.width), height: 200))
    physicsWorld.contactDelegate = self

    cam = SKCameraNode()
    self.camera = cam
    addChild(cam!)

    camBottom.position.y = -screenSize.height/2 + camBottom.size.height/2
    camBottom.zPosition = -1
    addChild(camBottom)
    camBottom.addPhysicsBody(category: .bottom, collision: nil, contact: .obj, isDynamic: false, gravity: false, rotation: false)
    camBottom.physicsBody?.restitution = 0.0
    camBottom.physicsBody?.isResting = true
    camBottom.physicsBody?.friction = 1.0

    addChild(obj)
    block.position = CGPoint(x: -30, y: -obj.size.height/2)
    obj.addChild(block)

    obj.physicsBody = SKPhysicsBody(bodies: [SKPhysicsBody(rectangleOf: obj.size, center: obj.position), SKPhysicsBody(rectangleOf: block.size, center: block.position)])
    obj.physicsBody?.categoryBitMask = collisionType.obj.rawValue
    obj.physicsBody?.collisionBitMask = collisionType.bottom.rawValue
    obj.physicsBody?.contactTestBitMask = collisionType.bottom.rawValue
    obj.physicsBody?.affectedByGravity = true
    obj.physicsBody?.allowsRotation = true

    runAutomation()

    let wait = SKAction.wait(forDuration: 0.01)
    let act = SKAction.run {
        self.updateCam()
    }
    run(SKAction.repeatForever(SKAction.sequence([wait, act])))

.addPhysicsBody是在新的Swift文件中定义的扩展,它是:

extension SKSpriteNode {
func addPhysicsBody(category: collisionType, collision: collisionType?, contact: collisionType?, isDynamic: Bool, gravity: Bool, rotation: Bool) {
    self.physicsBody = SKPhysicsBody(rectangleOf: self.size)
    self.physicsBody?.categoryBitMask = category.rawValue
    if collision != nil {
        self.physicsBody?.collisionBitMask = (collision?.rawValue)!
    } else {
        self.physicsBody?.collisionBitMask = 0
    }
    if contact != nil {
        self.physicsBody?.contactTestBitMask = (contact?.rawValue)!
    } else {
        self.physicsBody?.contactTestBitMask = 0
    }
    self.physicsBody?.isDynamic = isDynamic
    self.physicsBody?.affectedByGravity = gravity
    self.physicsBody?.allowsRotation = rotation
}
}

然后是GameScene中定义的函数:

func updateCam() {
    let val: CGFloat = 15
    let xDist = (obj.position.x - (camera?.position.x)!)/val
    let yDist = (obj.position.y - (camera?.position.y)!)/val
    camera?.position.x += xDist
    camera?.position.y += yDist
}

func runAutomation() {
    let wait = SKAction.wait(forDuration: 5.0)
    let act = SKAction.run {
        print("Before", self.obj.physicsBody?.velocity)
        self.obj.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 30), at: self.block.position)
        print("After", self.obj.physicsBody?.velocity)
    }
    run(SKAction.repeatForever(SKAction.sequence([wait, act])))
}

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
    camBottom.position.x = (camera?.position.x)!
}

这很奇怪,我不确定它是否是故意的。然而,我怎样才能使每次施加脉冲时,盒子飞起大约相同的距离?什么是正确的方法?

谢谢

1 个答案:

答案 0 :(得分:0)

看起来你正在使用

中的self.block.position来施加冲动
self.obj.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 30), at: self.block.position)

在某些时候,你的物体与以前不在同一个位置。所以它将应用相同的冲动,但从另一个位置。也许你想要self.obj.position而不是self.block.position或者只是使用

self.obj.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 30))

要让它跳得更高,你可以将dy设置为更高的值。