Как дать спрайту точное сенсорное место? - PullRequest
3 голосов
/ 14 апреля 2020

Мой вопрос:

Когда я касаюсь областей с черными стрелками, я все еще касаюсь всего изображения, но я хочу только касаться и действовать, когда я касаюсь только красной области, Я пытался дать имя spriteNode plane = childNode(withName: "play"), но он берет / трогает все рамки изображения, а не только alphaBody.

красные и черные области

Я провел некоторые поиски на Google, но без положительных результатов.

Большое спасибо.

Ответы [ 2 ]

2 голосов
/ 14 апреля 2020

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

enter image description here

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

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

  • коснитесь левого / правого крыла, чтобы повернуть это направление
  • коснитесь тела, чтобы заправиться
  • коснитесь крыльев, чтобы сменить оружие

вот код, который я использовал в своем классе самолетов

class Plane: SKSpriteNode {

    private var background: SKSpriteNode!
    private var wingsHitTest: SKSpriteNode!
    private var bodyHitTest: SKSpriteNode!
    private var smallWingsHitTest: SKSpriteNode!

    init() {

        super.init(texture: nil, color: .clear, size: CGSize.zero)
    }

    required init?(coder aDecoder: NSCoder) {

        super.init(coder: aDecoder)
        setup()
    }

    func setup() {

        isUserInteractionEnabled = true
        self.color = .clear

        if let background = self.childNode(withName: "//background") as? SKSpriteNode {
            self.background = background
        }

        if let wingsHitTest = self.childNode(withName: "//wingsHitTest") as? SKSpriteNode {
            self.wingsHitTest = wingsHitTest
        }

        if let bodyHitTest = self.childNode(withName: "//bodyHitTest") as? SKSpriteNode {
            self.bodyHitTest = bodyHitTest
        }

        if let smallWingsHitTest = self.childNode(withName: "//smallWingsHitTest") as? SKSpriteNode {
            self.smallWingsHitTest = smallWingsHitTest
        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first as UITouch? {

            let touchLocation = touch.location(in: self)

            if wingsHitTest.contains(touchLocation) {
                print("hit in the wings")
            }
            else if smallWingsHitTest.contains(touchLocation) {
                print("hit in the back wings")
            }
            else if bodyHitTest.contains(touchLocation) {
                print("hit in the body")
            }
        }
    }
}
1 голос
/ 14 апреля 2020

Кажется, что нужное вам поведение не включено в SpriteKit, поэтому вам придется реализовать его самостоятельно.

Цитирование по ссылке выше:

Вам нужно будет найти locationInNode(spriteNode) объекта UITouch объекта, чтобы получить координаты внутри спрайта, а затем прочитать альфа значение из изображения спрайта (не тривиальное) или предварительно вычисленные битовые маски (единицы и нули) из ваших изображений и считайте значение в соответствующей точке битовой маски для спрайта

Так что вам нужно будет загрузить image как UIImage или CGImage и проверьте, был ли цвет в пикселях, где произошло касание, прозрачным или нет. Вы можете найти больше информации о том, как это сделать, в этом вопросе: Как получить цвет пикселей из SKSpriteNode или из SKTexture?

...