加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 05:20:50 所属栏目:百科 来源:网络整理
导读:在学习SpriteKit(使用Ray Wenderlich等人的教程中使用iOS游戏)的基础上,我已经创建了我自己的非常简单的测试游戏,以了解是否可以应用我学到的概念.我决定通过使用.sks文件来创建sprite节点并替换我的手动范围检查和与物理机构的碰撞来简化我的代码. 然而,我
在学习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)

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读