この単純な物理シミュレーションでは、ちょっとした奇妙な動作があります。 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])))
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に設定できますが、これはあなたのオブジェクトの速度、重力、方向に非常に依存します。 – Retterdesdialogs
ありがとうございました。それはどういう仕組みか分かります。 –
@Retterdesdialogs実際には問題は解決していません。あなたはそれを自分で試すことができます。私はそれが思った、他の考え? –