ApplyImpulse оказывает экспоненциальное влияние на то, насколько сильно он толкает объект
В этом простом физическом моделировании есть немного странного поведения. 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 ответ
Похоже, что вы применяете импульс из позиции self.block.
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 более высокое значение.