当前位置: 首页 > 知识库问答 >
问题:

SpriteKit中精灵之间的碰撞

班安平
2023-03-14

我正在使用SpriteKit在XCode中制作一个游戏。游戏中有一个玩家,他必须避免不同类型的投射物。当玩家与投射物相撞时,分数发生变化,投射物消失。然而,当两个弹丸碰撞时,它们会反弹。我想让两个炮弹每次相撞时,它们表现得像什么都没发生过一样,并保持原来的轨迹。我该怎么办?

*注意:这并不是整个代码,重要的是它。

    import SpriteKit

    struct Physics {
        static let player : UInt32 = 1
        static let missileOne : UInt32 = 2
        static let missileTwo : UInt32 = 3
    }

class GameScene: SKScene, SKPhysicsContactDelegate {

    var player = SKSpriteNode(imageNamed: "p1.png")

    override func didMoveToView(view: SKView) {

        physicsWorld.contactDelegate = self

        player.position = CGPointMake(self.size.width/2, self.size.height/5)
        player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size)
        player.physicsBody?.affectedByGravity = false
        player.physicsBody?.dynamic = false
        player.physicsBody?.categoryBitMask = Physics.player
        player.physicsBody?.collisionBitMask = Physics.missileOne
        player.physicsBody?.collisionBitMask = Physics.missileTwo

        var missileOneTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("SpawnMissileOne"), userInfo: nil, repeats: true)
        var missileTwoTimer = NSTimer.scheduledTimerWithTimeInterval(1.2, target: self, selector: Selector("SpawnMissileTwo"), userInfo: nil, repeats: true)

        self.addChild(player)
    }

    //When contact happens
func didBeginContact(contact: SKPhysicsContact) {
    var firstBody : SKPhysicsBody = contact.bodyA
    var secondBody : SKPhysicsBody = contact.bodyB

    if ((firstBody.categoryBitMask == Physics.player) && (secondBody.categoryBitMask == Physics.missileOne)) {

        CollisionWithMissileOne(firstBody.node as SKSpriteNode, missileOne: secondBody.node as SKSpriteNode)

    } else if ((firstBody.categoryBitMask == Physics.player) && (secondBody.categoryBitMask == Physics.missileTwo)){

        CollisionWithMissileTwo(firstBody.node as SKSpriteNode, missileTwo: secondBody.node as SKSpriteNode)

    } else if ((firstBody.categoryBitMask == Physics.missileOne)&&(secondBody.categoryBitMask == Physics.missileTwo)) {

        CollisionBetweenMissiles(firstBody.node as SKSpriteNode, missileTwo: secondBody.node as SKSpriteNode)

        } 

    }

//For Player and MissileOne
    func CollisionWithMissileOne(player: SKSpriteNode, missileOne: SKSpriteNode) {

        missileOne.removeFromParent()
    }

//For Player and MissileTwo
    func CollisionWithMissileOne(player: SKSpriteNode, missileTwo: SKSpriteNode) {

        missileTwo.removeFromParent()
    }

//For MissileOne and MissileTwo
        func CollisionBetweenMissiles(missileOne: SKSpriteNode, missileTwo: SKSpriteNode) {

        ???WHAT SHOULD I CODE HERE???

    }

}

共有1个答案

孟楷
2023-03-14

令人困惑的是,碰撞BitMask用于定义哪些物理体在物理模型中相互作用。您真正想要的是联系测试位掩码

此外,您的物理没有返回正确的值用于位掩码。作为纯整数,它们应该是1、2、4、8等。

这是你修改后的代码,希望可以正常工作,我已经在修改的地方做了注释。

 struct Physics {
        static let player : UInt32 = 1
        static let missileOne : UInt32 = 2
        static let missileTwo : UInt32 = 4 // to work properly as bit masks
    }

如果要检查与多种类型的物理的接触对象正文.categoryBitMask,则此更改是必需的。看看玩家.物理身体?.联系测试位掩码 = ...在 didMoveToView 中:

override func didMoveToView(view: SKView) {
    physicsWorld.contactDelegate = self
    // All your existing player-stuff is fine until...
    // contactTest, not collision but contact, also: use bitwise OR
    player.physicsBody?.contactTestBitMask = Physics.missileOne | Physics.missileTwo
    self.addChild(player)

    // It is not recommended to use NSTimer for SpriteKit, use SKActions instead
    let missileOneWait = SKAction.waitForDuration(1)
    let callSpawnOneAction = SKAction.runBlock({ self.spawnMissileOne() })
    let missileOneRepeat = SKAction.repeatActionForever(SKAction.sequence([missileOneWait, callSpawnOneAction]))
    runAction(missileOneRepeat)

    let missileTwoWait = SKAction.waitForDuration(1.2)
    let callSpawnTwoAction = SKAction.runBlock({ self.spawnMissileTwo() })
    let missileTwoRepeat = SKAction.repeatActionForever(SKAction.sequence([missileTwoWait, callSpawnTwoAction]))
    runAction(missileTwoRepeat)
}

几乎重写了开始接触一些我相信读起来和缩放得更好的东西:

func didBeginContact(contact: SKPhysicsContact) {
    var firstBody = contact.bodyA
    var secondBody = contact.bodyB

    // Rewritten with dynamic variables
    var playerNode : SKSpriteNode? {
        if firstBody.categoryBitMask == Physics.player {
            return firstBody.node as? SKSpriteNode
        } else if secondBody.categoryBitMask == Physics.player {
            return secondBody.node as? SKSpriteNode
        }
        return nil
    }

    // If you want to handle contact between missiles you need to split this 
    // into two different variables
    var missileNode : SKSpriteNode? {
        let bitmask1 = firstBody.categoryBitMask
        let bitmask2 = secondBody.categoryBitMask

        if bitmask1 == Physics.missileOne || bitmask1 == Physics.missileTwo {
            return firstBody.node as? SKSpriteNode
        } else if bitmask2 == Physics.missileOne || bitmask2 == Physics.missileTwo {
            return secondBody.node as? SKSpriteNode
        }
        return nil
    }

    if playerNode != nil {
        collisionBetweenPlayer(playerNode, missile: missileNode)
    }
} 

那么你只需要一个功能来联系导弹和玩家:

func collisionBetweenPlayer(player: SKSpriteNode?, missile: SKSpriteNode?) {
    missile?.removeFromParent()
}
 类似资料:
  • 我的游戏有两个职业,它们都产生精灵,唯一的区别是它们的精灵向不同的方向移动。 然而,我如何检测另一个类的精灵是否与这个类碰撞,两个类都产生了很多精灵。我的想法是也使用池为每个精灵创建一个矩形。

  • 使用< code >加速计,我的精灵图像会左右移动,如果我触摸屏幕,精灵会移动到Y轴。我想在不同的精灵之间进行碰撞检测,这样如果精灵穿过一个物体,它就会停下来藏在那个物体里。我已经看了这个https://www.youtube.com/watch?v=T1aN-vTqLc的教程,但什么也没发生。进行碰撞检测的正确方法是什么?我不知道我的编码有什么问题。任何建议或更好的教程谢谢和进步 这是我的编码

  • 我在PyGame中创建了两个简单的精灵,其中一个是雨伞,另一个是雨滴。雨滴被添加到一个名为< code>all_sprites的sprite组中。伞精灵有自己的组,名为< code>Umbrella_sprite 雨滴从屏幕顶部“落下”,如果其中一个碰到雨伞/与雨伞碰撞..雨滴应该被删除了。但是除了特定雨滴之外,所有其他雨滴都受此影响。

  • 这就是正在发生的事情,游戏不断停止,因为两个圆圈相互碰撞,我正在尝试通过确保ID是正方形ID来防止这种情况,我试图让圆圈碰撞在一起,而忽略碰撞,但它没有这样做,我不知道如何确切地阻止它相互碰撞,只允许它与正方形碰撞。 基本上我想阻止这个圆与另一个圆碰撞,并允许它与正方形碰撞。 任何帮助都会很好谢谢 游戏引擎引擎类 这是我在扩展game.engine.engine包的game类中检查冲突的地方。 游

  • 我正在与Pygame一起练习,试图学习类,对象等的一些基本用法。 现在,在http://programarcadegames.com/的帮助下,我正在制作一个基本的平台 我有一个精灵播放器和精灵平台。这些平台也可以是移动平台,它应该在碰撞时移动玩家,但是当玩家移动到其他平台时,会发生一些奇怪的传送,我现在没有看到问题。 基本上,当被推时,玩家在逻辑上没有被移动(至少对我来说是这样)。 非常感谢任何

  • 在get_hit=pyGame.sprite的第82行,我检查sprite碰撞的移动时,它会给出错误提示:“:File”c:\Users\pc\VS_PYTHON_PY\pyGame.PY“。”。spritecollide(Player,敌方,True)文件“C:\python py\lib\site packages\pygame\sprite.py”,第1682行,位于spritecrolli