Swift中的SpriteKit物理学 – 球滑动而不是反射

前端之家收集整理的这篇文章主要介绍了Swift中的SpriteKit物理学 – 球滑动而不是反射前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在学习SpriteKit(使用Ray Wenderlich等人的教程中使用iOS游戏)的基础上,我已经创建了我自己的非常简单的测试游戏,以了解是否可以应用我学到的概念.我决定通过使用.sks文件来创建sprite节点并替换我的手动范围检查和与物理机构的碰撞来简化我的代码.

然而,我的球保持平行于墙壁/其他矩形(如同,简单地向上和向下滑动),任何时候它们以陡峭的角度与它们碰撞.这里是相关的代码 – 我把物理属性转移到代码中,使它们更加可见:

import SpriteKit

struct PhysicsCategory {
  static let None:        UInt32 = 0      //  0
  static let Edge:        UInt32 = 0b1    //  1
  static let Paddle:      UInt32 = 0b10   //  2
  static let Ball:        UInt32 = 0b100  //  4
}

var paddle: SKSpriteNode!
var ball: SKSpriteNode!

class GameScene: SKScene,SKPhysicsContactDelegate {

  override func didMoveToView(view: SKView) {

    physicsWorld.gravity = CGVector.zeroVector

    let edge = SKNode()
    edge.physicsBody = SKPhysicsBody(edgeLoopFromRect: frame)
    edge.physicsBody!.usesPreciseCollisionDetection = true
    edge.physicsBody!.categoryBitMask = PhysicsCategory.Edge
    edge.physicsBody!.friction = 0
    edge.physicsBody!.restitution = 1
    edge.physicsBody!.angularDamping = 0
    edge.physicsBody!.linearDamping = 0
    edge.physicsBody!.dynamic = false
    addChild(edge)

    ball = childNodeWithName("ball") as SKSpriteNode
    ball.physicsBody = SKPhysicsBody(rectangleOfSize: ball.size))
    ball.physicsBody!.usesPreciseCollisionDetection = true
    ball.physicsBody!.categoryBitMask = PhysicsCategory.Ball
    ball.physicsBody!.collisionBitMask = PhysicsCategory.Edge | PhysicsCategory.Paddle
    ball.physicsBody!.allowsRotation = false
    ball.physicsBody!.friction = 0
    ball.physicsBody!.restitution = 1
    ball.physicsBody!.angularDamping = 0
    ball.physicsBody!.linearDamping = 0

    physicsWorld.contactDelegate = self
}

忘了提到这个以前,但我添加了一个简单的touchesBegan功能来调试弹跳 – 它只是调整速度来指向球在接触点:

override func touchesBegan(touches: NSSet,withEvent event: UIEvent) {
  let touch = touches.anyObject() as UITouch
  let moveToward = touch.locationInNode(self)
  let targetVector = (moveToward - ball.position).normalized() * 300.0
  ball.physicsBody!.velocity = CGVector(point: targetVector)
}

normalized()函数只是将球/触摸位置增量减小到单位向量,并且有一个减号运算符的覆盖,允许CGPoint减法.

球/边缘碰撞应该始终以正确相反的角度反射球,但是由于某种原因,球真的似乎有一个直角的东西.我当然可以实现一些解决方法来手动反映球的角度,但重要的是我想使用SpriteKit中的内置物理功能来做到这一点.有没有什么明显的,我失踪了?

这似乎是碰撞检测的问题.大多数人通过使用didBeginContact找到解决方案,并以相反的方向重新施加力.注意他说didMoveToView,但是在后来的评论中纠正了自己做的BeginContact.

请参阅Ray Wenderlich教程here底部的注释

I have a fix for the problem with the ball “riding the rail” if it
strikes at a shallow angle (@aziz76 and @colinf). I added another
category,“BorderCategory” and assigned it to the border PhysicsBody
we create in didMoveToView.

和一个类似的SO问题here解释为什么发生.

Even if you do that,though,many physics engines (including
SpriteKit’s) have trouble with situations like this because of
floating point rounding errors. I’ve found that when I want a body to
keep a constant speed after a collision,it’s best to force it to —
use a didEndContact: or didSimulatePhysics handler to reset the moving
body’s velocity so it’s going the same speed it was before the
collision (but in the opposite direction).

另外我注意到,你正在使用一个正方形,而不是一个圆圈,你可能会考虑使用…

ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width/2)

所以原来你并不疯狂,总是很好的从别人听到,希望这将帮助您找到一个最适合您的应用程序的解决方案.

猜你在找的Swift相关文章