首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >防止SKNode离开视图

防止SKNode离开视图
EN

Stack Overflow用户
提问于 2016-01-19 05:06:33
回答 2查看 112关注 0票数 2

我正在做一个“太空入侵者”的游戏,我已经实现了CMMotionManager在倾斜上移动我的heroShip (这个游戏只运行在风景中),但是出于某种原因,我的船会移出视野,尽管

代码语言:javascript
复制
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)

应该通过创造物理优势来防止这种情况。知道为什么吗?

代码语言:javascript
复制
   import SpriteKit
    import CoreMotion

class GameScene: SKScene,SKPhysicsContactDelegate{
    let collisionBulletCategory: UInt32  = 0x1 << 0
    let collisionHeroCategory: UInt32    = 0x1 << 1
    let background = SKSpriteNode(imageNamed: "background")
    let heroShip = SKSpriteNode(imageNamed: "heroShip")
    let enemyShip = SKSpriteNode(imageNamed: "enemyShip")
    let MotionManager = CMMotionManager()



    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        self.physicsWorld.contactDelegate = self

        self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
        background.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame))
        heroShip.anchorPoint = CGPointMake(1.0, 0.5)
        heroShip.physicsBody?.mass = 0.02
        heroShip.physicsBody?.dynamic = true
        heroShip.physicsBody = SKPhysicsBody(rectangleOfSize: heroShip.size)
        heroShip.physicsBody?.affectedByGravity = false
        heroShip.physicsBody?.categoryBitMask = collisionHeroCategory
        heroShip.physicsBody?.contactTestBitMask = collisionBulletCategory
        heroShip.physicsBody?.collisionBitMask = 0x0
        heroShip.position =  CGPointMake(self.size.width/6.0, self.size.height/2.0)
        enemyShip.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
        enemyShip.zPosition = 1.0
        self.heroShip.zPosition = 1.0
        self.addChild(enemyShip)
        self.addChild(background)
        self.addChild(heroShip)

        if MotionManager.accelerometerAvailable{
            MotionManager.startAccelerometerUpdates()
        }

    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let bullet = SKSpriteNode(imageNamed: "bullet")
        bullet.position = CGPointMake(heroShip.position.x, heroShip.position.y)
        bullet.zPosition = 1.0
        // Add physics body for collision detection
        bullet.physicsBody = SKPhysicsBody(rectangleOfSize: bullet.frame.size)
        bullet.physicsBody?.dynamic = true
        bullet.physicsBody?.affectedByGravity = false
        bullet.physicsBody?.categoryBitMask = collisionBulletCategory
        bullet.physicsBody?.contactTestBitMask = collisionHeroCategory
        bullet.physicsBody?.collisionBitMask = 0x0;
        let action = SKAction.moveToX(CGRectGetMaxX(self.frame) + bullet.size.width, duration: 0.75)
        self.addChild(bullet)
        bullet.runAction(action, completion: {
            bullet.removeAllActions()
            bullet.removeFromParent()
        })
    }

    func didBeginContact(contact: SKPhysicsContact) {

    }
    override func update(currentTime: CFTimeInterval) {
        let data = MotionManager.accelerometerData
        if data?.acceleration.x == nil{
            print("nil")
        }
        else if fabs((data?.acceleration.x)!) > 0.2 {
            self.heroShip.physicsBody?.applyForce(CGVectorMake(0.0, CGFloat(50 * (data?.acceleration.x)!)))

        }

    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-19 13:38:07

根据文档,碰撞是这样发生的:

当两个物理物体相互接触时,可能会发生碰撞。通过执行逻辑和操作,将该主体的碰撞掩码与另一个主体的类别掩码进行比较。如果结果是一个非零值,这个主体会受到碰撞的影响。每个身体独立地选择它是否想被另一个身体所影响。例如,您可以使用它来避免碰撞计算,因为碰撞计算会对物体的速度造成微不足道的变化。

您已经将player的collisionBitMask设置为类似于0x00000000 (所有位都已清除)。默认情况下,categoryBitMask设置为0xFFFFFFFF (所有位设置)。因为你还没有说过,场景的物理体categoryBitMask被设置为0xFFFFFFFF。当在这两者之间执行逻辑和(&)运算符时,结果将为零,意味着没有冲突。

要解决这个问题,只需删除以下一行:

代码语言:javascript
复制
 heroShip.physicsBody?.collisionBitMask = 0x0

或者通过定义一个墙类来正确设置它..。

提示:

  • 锚点定义了如何相对于节点的位置绘制纹理。它和物理身体没有任何关系。物理体,默认情况下是以节点的位置为中心。如果你打开物理视觉表示法(skView.showsPhysics = true),你会看到,在你的例子中,物理体没有按它应有的位置定位。
  • 在你实际初始化之前设置物理体是没有意义的。你必须先初始化物理体。
票数 4
EN

Stack Overflow用户

发布于 2016-01-19 13:57:00

除了旋风的答案之外,你可能还想在你的物理身体上启用usesPreciseCollisionDetection。通过将其设置为true,这将防止您的heroShip在遇到来自加速度计数据的巨大力时从墙上弹出。

从根本上说,物理学是按照它的位置计算出来的。因此,如果有一个巨大的力,它可以说,“哦,这个巨大的力意味着我应该在这里远远超出边界框。”如果您启用了精确的碰撞检测,这将迫使它计算多个位置的物理,从这个框架的起始位置,到计算的位置。如果它在到达计算的位置之前碰到了某个物体,那么它就会进行调整,这样它就不会经过它碰到的任何东西。在大多数情况下,你不必担心这一点,但安全总比抱歉好。

因此,在初始化之后,将这一行放在物理体配置代码的某个位置:

代码语言:javascript
复制
heroShip.physicsBody?.usesPreciseCollisionDetection = true
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34868844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档