swift - прыгать только при приземлении

Я хочу ограничить своего персонажа (кошку), чтобы он прыгал только тогда, когда он находится либо на земле (фиктивный SKNode), либо на дереве (treeP SKNode).

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

Если бы кто-нибудь мог мне помочь, я был бы очень счастлив.

То, что я хотел бы сделать, но не имею опыта, - это включить щелчок (прыжок), если кошка соприкасалась с манекеном или деревом, и аналогичным образом отключить щелчки, если он не соприкасается ни с манекеном, ни с деревом.

Вот все, что может пригодиться....

class GameScene: SKScene, SKPhysicsContactDelegate {

let catCategory: UInt32 = 1 << 0
let treeCategory: UInt32 = 1 << 1
let worldCategory: UInt32 = 1 << 1

override func didMoveToView(view: SKView) {

// part of cat code    

    cat = SKSpriteNode(texture: catTexture1)
    cat.position = CGPoint(x: self.frame.size.width / 2.2, y: self.frame.size.height / 7.0 )
    cat.physicsBody?.categoryBitMask = catCategory
    cat.physicsBody?.collisionBitMask = crowCategory | worldCategory
    cat.physicsBody?.contactTestBitMask = crowCategory | contact2Category

// part of the ground code

    var dummy = SKNode()
    dummy.position = CGPointMake(0, groundTexture.size().height / 2)
    dummy.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, groundTexture.size().height))
    dummy.physicsBody!.dynamic = false
    dummy.physicsBody?.categoryBitMask = worldCategory
    dummy.physicsBody?.collisionBitMask = 0
    dummy.physicsBody?.contactTestBitMask = 0
    moving.addChild(dummy)

// part of the tree code

func spawnTrees() {
    var treeP = SKNode()
    treeP.position = CGPointMake( self.frame.size.width + treeTexture1.size().width * 2, 0 );
    treeP.zPosition = -10; 
    var height = UInt32( self.frame.size.height / 4 )
    var y = arc4random() % height;
    var tree1 = SKSpriteNode(texture: treeTexture1)
    tree1.position = CGPointMake(0.0, CGFloat(y))
    tree1.physicsBody = SKPhysicsBody(rectangleOfSize: tree1.size)
    tree1.physicsBody?.dynamic = false
    tree1.physicsBody?.categoryBitMask = treeCategory;
    tree1.physicsBody?.collisionBitMask = 0
    tree1.physicsBody?.contactTestBitMask = 0
    treeP.addChild(tree1)

    treeP.runAction(moveAndRemoveTrees)

    trees.addChild(treeP)

}

// all of touchesBegan

override func  touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    /* Called when a touch begins */


    if (moving.speed > 0){
        cat.physicsBody!.velocity = CGVectorMake(0, 0)
        cat.physicsBody!.applyImpulse(CGVectorMake(0, 20))

                } else if (canRestart) {
                    self.resetScene()
    }

}

person Rich Townsend    schedule 09.08.2015    source источник


Ответы (2)


У меня недавно была эта проблема. Вот как я это исправил. В игровой сцене создайте эту переменную:

    var ableToJump = true

Затем в методе обновления поместите этот код:

    if cat.physicsBody?.velocity.dy == 0 {
ableToJump = true
    }
    else {
ableToJump = false
    }

Приведенный выше код будет работать, потому что метод обновления запускается в каждом кадре игры. В каждом кадре он проверяет, движется ли ваш кот по оси Y. Если у вас нет метода обновления, просто введите override func update, и он должен выполниться автоматически.

Теперь последний шаг — поместите этот код в touchesBegan:

    if ableToJump == true {
cat.physicsBody!.applyImpulse(CGVectorMake(0,40))
 }

Примечание: возможно, вам придется повозиться с импульсом, чтобы получить желаемую высоту прыжка.

person Aidan Kaiser    schedule 10.08.2015
comment
Отлично, ты мой новый любимый человек! Спасибо. - person Rich Townsend; 10.08.2015
comment
Будьте осторожны, если это единственная проверка, то вы можете прыгнуть, когда персонаж достигнет высшей точки во время прыжка. Это позволит вам продолжать прыгать в воздухе. Также эта проверка не будет работать при спуске по склону. - person Epic Byte; 10.08.2015
comment
Вы можете создать еще одну проверку, если хотите, но вероятность того, что кто-то действительно сможет поймать ее в верхней части прыжка, маловероятна. Вы можете исправить это, проверив, меньше ли положение, чем любая точка прыжка. А я просто предположил, что уклонов не было, когда отвечал. - person Aidan Kaiser; 10.08.2015

Вы можете использовать пользовательскую логическую переменную с именем isOnTheGround, чтобы ограничить прыжки в воздухе. Эта переменная должна быть обновлена ​​вами. Обратите внимание, что персонаж не обязательно находится на земле, только если он соприкасается с «платформой» (например, может произойти боковой контакт). Итак, вам решать, что значит «на земле». Когда вы определяете это, это легко:

Подсказка: вы можете сравнить позицию y персонажа с позицией y платформы, чтобы увидеть, действительно ли персонаж находится на платформе.

Предполагая, что точка привязки персонажа и платформы неизменна (0,5,0,5), для вычисления положения ног персонажа по оси y вы можете сделать что-то вроде этого (псевдокод):

characterLegsY = characterYPos - characterHeight/2

И чтобы получить поверхность платформы:

platformSurfaceYPos = platformYPos + platformHeight/2

Предотвращение прыжков в воздухе

В контактахНачало:

  • если isOnTheGround -> прыжок

В didEndContact:

  • здесь вы устанавливаете isOnTheGround в false (персонаж закончил контакт с землей/платформой)

В didBeginContact:

  • проверить, действительно ли персонаж находится на земле
  • установить для переменной isOnTheGround значение true

Здесь вы можете найти пример чего-то подобного...

person Whirlwind    schedule 09.08.2015