Swift Spritekit-只有在特定位置时才碰撞精灵吗?

时间:2019-06-17 04:41:10

标签: ios swift xcode sprite-kit collision-detection

嗨,请放心,因为我还是个新手。我正在创建一个游戏,您的角色(在屏幕左侧)必须向上或向下滑动以更改车道(4车道)或通过点击屏幕右侧来跳跃,以躲避来自右侧的障碍物屏幕的侧面。这就带来了一个问题,当角色精灵位于一个通道中时,其中一些像素位于上方的通道中,因此位于不同的通道中并不能使角色免受碰撞。 (当角色跳跃时也会出现此问题)是否有编程方法,以便角色和障碍物只有在同一车道时才发生碰撞?

我试图做到这一点,所以.collisionBitMask和.categoryBitMask会根据障碍物或角色的位置而变化,但我不知道如何正确编码。老实说我很失落。这是一些代码:

runningDoggo.physicsBody = SKPhysicsBody(texture: doggoTexture, size: runningDoggo.size)
runningDoggo.physicsBody?.affectedByGravity = false
runningDoggo.physicsBody?.isDynamic = true
runningDoggo.physicsBody?.collisionBitMask = 0x1 << 2
bush.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "8-bit bush"), size: bush.size)
bush.physicsBody?.isDynamic = true
bush.physicsBody?.affectedByGravity = false
bush.physicsBody?.categoryBitMask = 0x1 << 1

然后我有一组开关盒,用于随机选择灌木丛进入哪个车道的功能

    switch randomLane{
    case 1:
        bush.position = CGPoint(x: 0.4*UIScreen.main.bounds.width, y:-0.07*UIScreen.main.bounds.height)
        if(bush.position.y < runningDoggo.position.y) {
            bush.zPosition = 6
        }
        self.addChild(bush)
    case 2:
        bush.position = CGPoint(x: 0.4*UIScreen.main.bounds.width, y:-0.18*UIScreen.main.bounds.height)
        if(bush.position.y < runningDoggo.position.y)  {
            bush.zPosition = 6
        }
        self.addChild(bush)
    case 3:
        bush.position = CGPoint(x: 0.4*UIScreen.main.bounds.width, y:-0.29*UIScreen.main.bounds.height)
        if(bush.position.y < runningDoggo.position.y) {
            bush.zPosition = 6
        }
        self.addChild(bush)
    case 4:
        bush.position = CGPoint(x: 0.4*UIScreen.main.bounds.width, y:-0.4*UIScreen.main.bounds.height)
        if(bush.position.y < runningDoggo.position.y) {
            bush.zPosition = 6
        }
        self.addChild(bush)
    default:
        print("How is this not 1,2,3, or 4?")
    }
    bush.run(moveAndRemoveBush)

如果它们在同一车道中,我希望它仅碰撞(编辑:不是碰撞而是与之接触)runningDoggo雪碧与灌木雪碧,并且如果角色不在障碍物的车道中,则不与之碰撞而通过。 / p>

1 个答案:

答案 0 :(得分:0)

首先,可以将复杂的开关简化为这样的东西(任何时候多次编写相同的代码,请考虑是否可以简化):

bush.position.x = 0.40 * UIScreen.main.bounds.width
bush.position.y = 0.07 * randomLane * UIScreen.main.bounds.height) // 0.07, 0.14, 0.21 or 0.28 for lanes 1-4 
if (bush.position.y < runningDoggo.position.y) bush.zPosition = 6
self.addChild(bush)
bush.run(moveAndRemoveBush)

好-我知道y值0.07、0.14、0.21和0.28与您的0.07、0.18、0.29和0.40值不匹配,但是也许您可以tweek或将偏移数组定义为属性:

let bushYOffset = [0.07, 0.18, 0.29, 0.40]

然后选择与车道相对应的偏移量

bush.position.x = 0.40 * UIScreen.main.bounds.width
bush.position.y = bushYOffset[randonLane-1] * UIScreen.main.bounds.height)
if (bush.position.y < runningDoggo.position.y) bush.zPosition = 6
self.addChild(bush)
bush.run(moveAndRemoveBush)

要解决您的主要问题,您可以为数组中的每个通道创建一个位掩码:

let laneMask: [UInt32] = [1<<1, 1<<2, 1<<3, 1<<4]

当Doggo移至新车道时,将与collisonBitmask相对应的Doggo的physicsBody移至刚移入的车道:

runningDoggo.physicsBody?.collisionBitMask = laneMask[doggoLane - 1] // Arrays start at 0

生成障碍物时,还为其提供碰撞路径的碰撞位掩码:

bush.physicsBody?.collisionBitMask = laneMask[randomLane - 1] // Arrays start at 0

现在,Doggo和灌木丛只有在同一车道时才会发生碰撞。如果它们位于不同的车道,即使它们的某些像素重叠,也不会。

如果屏幕上还有其他与Doggo和灌木丛互动的子画面,则可能需要调整此值。

注意:

您确定要让他们碰撞而不联系吗?当精灵相互碰撞并弹回并在屏幕上飞来飞去时,就会发生碰撞。接触是2个精灵接触到的地方,您的代码将被调用,您可以爆炸,丧命或增加得分等。

编辑:我关于碰撞和接触的循序渐进指南: https://stackoverflow.com/a/51041474/1430420

以及碰撞和接触的指南测试位掩码: https://stackoverflow.com/a/40596890/1430420

操纵位掩码以打开和关闭各个碰撞和接触。 https://stackoverflow.com/a/46495864/1430420