Swift Spritekit - сталкиваются только спрайты, когда они находятся в определенных позициях? - PullRequest
1 голос
/ 17 июня 2019

Привет, смирись со мной, я все еще новичок в стремительности.Я создаю игру, в которой ваш персонаж (в левой части экрана) должен провести вверх или вниз, чтобы сменить полосу движения (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 со спрайтом куста, если они находились в одной полосе, и проходили мимо, не сталкиваясь, если персонаж не находится в препятствии.пер.

1 Ответ

0 голосов
/ 18 июня 2019

Во-первых, этот сложный переключатель можно упростить до чего-то подобного (каждый раз, когда вы пишете один и тот же код более одного раза, подумайте, можете ли вы его упростить):

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, но, возможно, это то, что вы можете настроить, или определить массив смещения как свойство:

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]

Когда Догго переходит на новую полосу движения, передайте физику тела Догго, соответствующую collisonBitmask, полосу, в которую он только что перешел:

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

Когда вы создаете препятствие, также присвойте ему битовую маску столкновения для полосы, в которой он находится:

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

Теперь Догго и куст будут сталкиваться, только если они находятся в одной полосе. Если они находятся в разных полосах, они не будут, даже если некоторые их пиксели перекрываются.

Возможно, вам придется настроить это, если на экране есть другие спрайты, с которыми догго и кустарнику нужно взаимодействовать.

Примечание:

Вы уверены, что хотите, чтобы они столкнулись и не соприкасались? Столкновения происходят, когда спрайты сталкиваются и отскакивают друг от друга и летают по экрану; контакты - это место, где соприкасаются 2 спрайта, и ваш код вызывается, и вы можете взорвать или потерять жизнь, или увеличить счет и т. д.

Редактировать: мое пошаговое руководство по столкновениям и контактам: https://stackoverflow.com/a/51041474/1430420

И руководство по столкновениям и контактам. Тест битовых масок: https://stackoverflow.com/a/40596890/1430420

Управление битовыми масками для выключения и включения отдельных контактов и контактов. https://stackoverflow.com/a/46495864/1430420

...