как остановить движение спрайта, когда сенсорная активность все еще происходит - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть синий квадратный спрайт и карта в форме буквы. Синий квадрат должен свободно перемещаться внутри карты.

Моя цель состоит в том, чтобы ограничить спрайт синего квадрата внутри карты тайлов, даже если действие касания все еще происходит.

Проблема заключается в том, что спрайт синего квадрата движется касанием в определенном направлении, если касание все еще продолжается, спрайт выйдет за пределы красных плиток.

enter image description here

решение, которое я пробовал

logi c:

  1. создать логический флаг (isNeighbourTileNil) определить, является ли соседняя плитка ноль (не на красной плитке) в обновлении ()

    • У меня нет проблем для этого шага.
  2. Если isNeighbourTileNil равно true, то спрайт игрока должен перестать двигаться, даже когда касание все еще движется / происходит.

    • У меня проблемы с этим шагом. Проблема, с которой я столкнулся, заключается в том, что переменная bool isNeighbourTileNil обновляется каждым кадром. Однако событие touch (touchesBegan () -> touchesMoved () -> touchesEnded ()) - это линейный процесс, означающий, что я не мог передать постоянно меняющуюся переменную, такую ​​как isNeighbourTileNil, функции touchesMoved () и остановить движение игрока оттуда.

вот код, который я пробовал:

 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches{
            if(i==0){
                firstTouch = touch.location(in: self)
            }
            if(i==1){
                secondTouch = touch.location(in: self)
            }
            i = i+1
        }
        direction = directionCalculator(firstTouch, secondTouch)
        print(direction)
        if isNeighbourTileNil == false {
            moveInDirection(direction, 10.0, 10.0, -10.0, -10.0)
        }
    }
override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendere
        let playerPosition = player.position
        let column = mainTileMap.tileColumnIndex(fromPosition: playerPosition)
        let row = mainTileMap.tileRowIndex(fromPosition: playerPosition)
        let currentTile = mainTileMap.tileDefinition(atColumn: column, row: row)
        currentTileTuple.column = column
        currentTileTuple.row = row

        if !self.isMonsterCollisionDetected {
            self.detectMonsterCollisions()
        }
        detectMapCollision()

        if isNeighbourTileNil == true {
            print("player should stop moving")
            player.removeAllActions()
        }
    }

1 Ответ

1 голос
/ 04 февраля 2020

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

  1. Имейте переменную с именем canMove или что-то вроде этого, которое должно быть true, когда игрок находится в состоянии, в котором он может двигаться.
  2. Добавьте UISwipeGestureRecognizer для распознавания каждого удара. Google "uigesturerecognizer spritekit" для примеров, как это сделать. Это вызовет ваш код, когда произойдет удар, и даст вам направление, в котором игрок хочет двигаться. Игнорируйте удары, когда canMove равно false.
  3. Когда вы получите уведомление о свайпе, а canMove равно true, проверьте, может ли игрок двигаться в нужном направлении в соответствии с соседними ячейками. Если нет, проигнорируйте пролистывание.
  4. Наконец, случай, когда canMove равен true, и пролистывание указывает действительное направление ... Установите canMove в false и запустите анимацию движения игрок на новый квадрат, набрав SKAction.move(to:duration:) или что-то еще. Запустите действие с обработчиком завершения, который устанавливает canMove обратно на true после завершения действия.
...