Swift + Physics:碰撞时的角度计算错误 [英] Swift + Physics: Wrong angle calculation on collision

查看:191
本文介绍了Swift + Physics:碰撞时的角度计算错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 SpriteKit 应用程序,带有墙壁和球。两者都设置为 SKPhysicsBody

I have a simple SpriteKit App with walls and a ball. Both setup with a SKPhysicsBody.

当我向一个方向施加一个力时,我希望球反映在当碰撞但方向相反时,墙壁角度相同。

When I apply a force in one direction, I expect the ball to reflect at the wall with the same angle when it collide but in opposite direction.

但有时我看到角度很奇怪。我玩了很多 physicsBody 属性,但无法修复它。有时第一次反射看起来很好,但是第三次​​或第六次反射,有时第一次反射是错误的角度。

But sometimes I see the angle is weird. I played a lot with all the physicsBody properties, but was not able to fix it. Sometimes the first reflections look good, but then the third or sixth and sometimes the first reflection is at wrong angle.

我从不同的帖子中读到,人们有点自我计算正确的方向。但是我无法想象 SpriteKits 物理引擎无法这样做。

I read from different posts, people are kinda self-calculating the "correct direction". But I can't imagine SpriteKits physic engine is not capable to do so.

检查我的附件图片以了解我的意思是。有人可以帮忙吗?我不想开始使用Box2d for Swift,因为看起来我很难融入Swift。

Check my attached image to understand what I mean. Can anybody help on this? I don't want to start playing around with Box2d for Swift, since this looks like it will be too hard for me to integrate into Swift.

这是我的GameScene.swift文件中的 physicsWorld init我的元素被添加到:

This is the physicsWorld init on my GameScene.swift file where all my elements are added to:

self.physicsWorld.gravity = CGVectorMake(0, 0)

添加我的所有代码会太多,所以我添加了重要的部分。希望它足以分析。所有元素,如球,墙都是 SKSpriteNode 's

Adding all my code would be way too much, so I add the important pieces. Hope its enough for analyze. All elements like the ball, walls are SKSpriteNode's

这是 physicsBody 球的代码:

self.physicsBody = SKPhysicsBody(circleOfRadius: Constants.Config.playersize+self.node.lineWidth)
self.physicsBody?.restitution = 1
self.physicsBody?.friction = 0
self.physicsBody?.linearDamping = 1
self.physicsBody?.allowsRotation = false
self.physicsBody?.categoryBitMask = Constants.Config.PhysicsCategory.Player
self.physicsBody?.collisionBitMask = Constants.Config.PhysicsCategory.Wall | Constants.Config.PhysicsCategory.Enemy
self.physicsBody?.contactTestBitMask = Constants.Config.PhysicsCategory.Wall | Constants.Config.PhysicsCategory.Enemy

这是墙的物理实体:

el = SKSpriteNode(color: UIColor.blueColor(), size: CGSize(width: Constants.Config.wallsize, height: Constants.Config.wallsize))
el.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: Constants.Config.wallsize, height: Constants.Config.wallsize))
el.physicsBody?.dynamic = false
el.physicsBody?.categoryBitMask = Constants.Config.PhysicsCategory.Wall
el.physicsBody?.collisionBitMask = Constants.Config.PhysicsCategory.Player
el.physicsBody?.contactTestBitMask = Constants.Config.PhysicsCategory.Player

最后我只是在球上调用applyImpulse函数 physicsBody 让它在物理模拟中移动。

At the end I just call the applyImpulse function on the balls physicsBody to make it moving in the physics simulation.

同时检查我附加的第二张图像/ gif。它使用简单的skphysics应用程序显示边缘碰撞问题,没有任何特殊参数化。只是一个带有球的矩形,一个矢量用作冲动。

Also check my attached second image/gif. It shows the edge collision problem with a simple skphysics app without any special parameterization. just a rectangle with a ball in it and one vector applied as impulse.

使用appzYourLife中的解决方案代表完整的非工作代码。

Heres my full non-working code using the solution from appzYourLife.

class GameScene: SKScene {
private var ball:SKShapeNode!
override func didMoveToView(view: SKView) {
    let screen = UIScreen.mainScreen().bounds
    let p = UIBezierPath()
    p.moveToPoint(CGPointMake(0,0))
    p.addLineToPoint(CGPointMake(screen.width,0))
    p.addLineToPoint(CGPointMake(screen.width, screen.height))
    p.addLineToPoint(CGPointMake(0,screen.height))
    p.closePath()
    let shape = SKShapeNode(path: p.CGPath)
    shape.physicsBody = SKPhysicsBody(edgeLoopFromPath: p.CGPath)
    shape.physicsBody?.affectedByGravity = false
    shape.physicsBody?.dynamic = false
    shape.strokeColor = UIColor.blackColor()

    self.addChild(shape)

    ball = SKShapeNode(circleOfRadius: 17)
    ball.name = "player"
    ball.position = CGPoint(x: 20, y: 20)
    ball.fillColor = UIColor.yellowColor()
    ball.physicsBody = SKPhysicsBody(circleOfRadius: 17)
    ball.physicsBody?.angularDamping = 0
    ball.physicsBody?.linearDamping = 0
    ball.physicsBody?.restitution = 1
    ball.physicsBody?.friction = 0
    ball.physicsBody?.allowsRotation = false

    self.addChild(ball)
    self.ball.physicsBody?.applyImpulse(CGVector(dx: 2.4, dy: 9.7))
}

我刚刚意识到我的球精灵的质量和密度是零。为什么?甚至设置它都保持为零。

I just realized the mass and density of my ball sprite is nil. Why that? Even setting it keeps in nil.

推荐答案

Since i cannot imagine this is some unknown bug in SpriteKits physics engine, 
i very hope someone can help me here as this is a full stopper for me.

这是 SpriteKits物理引擎中的(已知)错误。但有时只是玩这些值会使这个错误消失 - 例如,每次撞到墙壁时尝试改变球的速度(即使是小值)。

It is a (known) bug in SpriteKits physic engine. But sometimes just playing with the values will make this bug disappear - for example, try changing the ball's speed (even by small value) every time it's hitting the wall.

另一个解决方案列于此处:
SpriteKit物流在Swift中 - 球滑向墙壁而不是反射

Another solutions are listed here: SpriteKit physics in Swift - Ball slides against wall instead of reflecting

(与你的问题相同,已经从2014年开始,仍未修复......)

(The same problem as yours, already from 2014, still not fixed..)

这篇关于Swift + Physics:碰撞时的角度计算错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆