2017-11-24 20 views
0

この単純な物理シミュレーションでは、ちょっとした奇妙な動作があります。 applyImpulseは5秒ごとに適用されますが、これが発生するたびにapplyImpulseに同じ値が使用されていても、ボックスはさらに高くなります。約20秒後、ボックスが非常に高く撮影されています。ApplyImpulseは、オブジェクトをどのくらいプッシュするかに指数関数的な影響を与えます

ボックスには小さな赤いボックスが付いています。そこには衝撃が加えられています。

PHOTOSは、キャプチャ:override func didMove(to view: SKView)でそして

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)) 

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が拡張され

THIS

はコードでありますその後

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)! 
} 

それは非常に奇妙である、私はそれが意図的であるかはわかりません。それにもかかわらず、どのようにして衝動が適用されるたびにボックスが同じ距離を飛ぶようにすることができますか?正しい方法は何ですか?

は、あなたのオブジェクトは、前のように同じ位置にはないいくつかの点で

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

でself.block.positionからインパルスを適用しているようにあなたが

+0

実際のベクトルにインパルスを適用しているため、これは正しい動作です。オブジェクトに特定の速度と速度がある場合、オブジェクトにその速度と速度のインパルスを与えます。インパルスを適用する前にベロシティを0,0に設定できますが、これはあなたのオブジェクトの速度、重力、方向に非常に依存します。 – Retterdesdialogs

+0

ありがとうございました。それはどういう仕組みか分かります。 –

+0

@Retterdesdialogs実際には問題は解決していません。あなたはそれを自分で試すことができます。私はそれが思った、他の考え? –

答えて

0

に見えますありがとうございます。したがって、同じインパルスが適用されますが、別のポジションから適用されます。たぶん、あなたはself.obj.position代わりのself.block.positionをしたいか、単にそれはあなたがより高い値にDYを設定して高くジャンプできるようにするに

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

を使用しています。

+0

私はその場所で衝動を適用したかった。私が見つけた問題は回転でした。あまりにも多くのエネルギーが角運動量として保存されたので、角振動を起こしたり、回転を止めたりしました。 –

+0

ありがとうとにかく、uは正しい方向に私を操縦しました –

+0

いいえ、問題はありません:) – Retterdesdialogs

関連する問題