Создадим рейкаст в spritekit

Я создаю игру, используя Spritekit, и пытаюсь создать raycast, который соединит игрока с точкой, в которую он нажал. Это будет похоже на веревку, которая соединяет игрока с точкой, в которую он или она постучал. Например, если игрок коснется точки x: 0, y: 0, то она станет веревкой, соединяющей обе вещи друг с другом. Со временем веревка станет короче, и игрока будет тащить за нее. У игрока есть физическое тело. Когда игрок отпустит палец, веревка будет удалена, и игрока больше не будут тащить в эту точку.

Я хочу заархивировать то же самое, как если бы вы искали raycast в единстве, но со спрайткитом.

Я знаю, как реализовать функцию касания, а также когда он или она отпускает касание. Итак, вопрос в том, как мне сделать raycast, как описано. Я также хотел бы иметь какой-то визуальный эффект, который означает skshapenode или что-то, что указывает, куда движется игрок.

Пробовал использовать SkPhysicsJoints, но безуспешно.

Любая помощь будет оценена по достоинству!


person Edwin123    schedule 09.02.2020    source источник
comment
Зачем нужен рейкаст? Звучит как простой отрезок для меня   -  person Knight0fDragon    schedule 10.02.2020
comment
Дело в том, что игрок будет соединен веревкой с тем местом, куда он нажимает. Каждую секунду или около того веревка будет становиться короче, и игрока будет притягивать физика к этой точке. Если вы можете сделать это с сегментом линии, то это абсолютно нормально. Не могли бы вы показать код о том, как это реализовать? Спасибо!   -  person Edwin123    schedule 10.02.2020
comment
Хм? Это не бросок луча и не отрезок линии. Вам нужно переработать этот вопрос, чтобы лучше объяснить, что вы пытаетесь сделать.   -  person Knight0fDragon    schedule 10.02.2020
comment
Обновили вопрос. Спасибо за ваши усилия!   -  person Edwin123    schedule 10.02.2020


Ответы (1)


Raycast поддерживается объектом physicsWorld на вашей сцене с помощью метода

func enumerateBodies(alongRayStart start: CGPoint, end: CGPoint, using block: @escaping (SKPhysicsBody, CGPoint, CGVector, UnsafeMutablePointer<ObjCBool>) -> Void)

Вы можете использовать так:

self.physicsWorld.enumerateBodies(alongRayStart: playerPosition, end: clickPosition) { body, point, vector, object in
    if let node = body.node as? SKSpriteNode {
        node.color = SKColor.red.withAlphaComponent(0.2)
        let pointNode = SKSpriteNode(color: .cyan, size: CGSize(width: 5, height: 5))
        pointNode.position = point
        let path = CGMutablePath()
        path.move(to: playerPosition)
        path.addLine(to: clickPosition)
        path.closeSubpath()
        let line = SKShapeNode(path: path)
        line.strokeColor = .green
        line.fillColor = .green
        self.addChild(line)
        self.addChild(pointNode)
    }
}

И получайте этот результат при каждом клике:

введите здесь описание изображения

Полный пример здесь: https://github.com/Maetschl/SpriteKitExamples/blob/master/Raycast2dLinesVsObjects/Raycast2dLinesVsObjects/GameScene.swift

person Maetschl    schedule 10.03.2020