Использование Sprite Kit после создания проекта не как Game а как App


#1

Добрый день!
Проект на swift UIkit
Уже после создания проекта поставили задачу внедрить персонажа и сделать для него управление с помощью джойстика на экране.
Нашел вот такое решение но там в основе sprite kit.
Попытался подключить Sprite kit в проект но сцена не добавляется во View Сontroller

class MapViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

// scene.backgroundColor = .white

    if let view = self.view as! SKView? {
        print("asldkfj ;lj ")

        let scene = GameScene(size: self.view.bounds.size)

        scene.scaleMode = .aspectFill
        view.presentScene(scene)

        view.showsFPS = true
        view.showsNodeCount = true
        view.ignoresSiblingOrder = true
    }
}

override var shouldAutorotate : Bool {
    return true
}

override var supportedInterfaceOrientations : UIInterfaceOrientationMask  {
    return UIDevice.current.userInterfaceIdiom == .phone ? .allButUpsideDown : .all
}


override var prefersStatusBarHidden : Bool {
    return true
}

}

с ошибкой в сроке: if let view = self.view as! SKView? {

Could not cast value of type ‘UIView’ (0x7fff86f664a0) to ‘SKView’ (0x7fff87b1b790).

CoreSimulator 732.18.6 - Device: iPhone 12 Pro Max (602B3ECE-BDE5-4DBF-94AB-2D425ADFAF68) - Runtime: iOS 14.4 (18D46) - DeviceType: iPhone 12 Pro Max

(lldb)

Как можно побороть? Что я упустил

Файл сцены

import SpriteKit

class GameScene: SKScene {

var appleNode: SKSpriteNode?
let jSizePlusSpriteNode = SKSpriteNode(imageNamed: "plus")
let jSizeMinusSpriteNode = SKSpriteNode(imageNamed: "minus")
let setJoystickStickImageBtn = SKLabelNode()
let setJoystickSubstrateImageBtn = SKLabelNode()
let joystickStickColorBtn = SKLabelNode(text: "Sticks random color")
let joystickSubstrateColorBtn = SKLabelNode(text: "Substrates random color")

let moveJoystick = 🕹(withDiameter: 100)
let rotateJoystick = TLAnalogJoystick(withDiameter: 100)

var joystickStickImageEnabled = true {
    didSet {
        let image = joystickStickImageEnabled ? UIImage(named: "jStick") : nil
        moveJoystick.handleImage = image
        rotateJoystick.handleImage = image
        setJoystickStickImageBtn.text = "\(joystickStickImageEnabled ? "Remove" : "Set") stick image"
    }
}

var joystickSubstrateImageEnabled = true {
    didSet {
        let image = joystickSubstrateImageEnabled ? UIImage(named: "jSubstrate") : nil
        moveJoystick.baseImage = image
        rotateJoystick.baseImage = image
        setJoystickSubstrateImageBtn.text = "\(joystickSubstrateImageEnabled ? "Remove" : "Set") substrate image"
    }
}

override func didMove(to view: SKView) {
    /* Setup your scene here */
    
    let sprite = SKSpriteNode(color: .red, size: CGSize(width: 24, height: 24))
    sprite.position = CGPoint(x: 20, y: 20)
    self.addChild(sprite)
    
    backgroundColor = .red
    physicsBody = SKPhysicsBody(edgeLoopFrom: frame)

    let moveJoystickHiddenArea = TLAnalogJoystickHiddenArea(rect: CGRect(x: 0, y: 0, width: frame.midX, height: frame.height))
    moveJoystickHiddenArea.joystick = moveJoystick
    moveJoystick.isMoveable = true
    addChild(moveJoystickHiddenArea)
    
    let rotateJoystickHiddenArea = TLAnalogJoystickHiddenArea(rect: CGRect(x: frame.midX, y: 0, width: frame.midX, height: frame.height))
    rotateJoystickHiddenArea.joystick = rotateJoystick
    addChild(rotateJoystickHiddenArea)
    
    //MARK: Handlers begin
    moveJoystick.on(.begin) { [unowned self] _ in
        let actions = [
            SKAction.scale(to: 0.5, duration: 0.5),
            SKAction.scale(to: 1, duration: 0.5)
        ]

        self.appleNode?.run(SKAction.sequence(actions))
    }
    
    moveJoystick.on(.move) { [unowned self] joystick in
        guard let appleNode = self.appleNode else {
            return
        }
        
        let pVelocity = joystick.velocity;
        let speed = CGFloat(0.12)
        
        appleNode.position = CGPoint(x: appleNode.position.x + (pVelocity.x * speed), y: appleNode.position.y + (pVelocity.y * speed))
    }
    
    moveJoystick.on(.end) { [unowned self] _ in
        let actions = [
            SKAction.scale(to: 1.5, duration: 0.5),
            SKAction.scale(to: 1, duration: 0.5)
        ]

        self.appleNode?.run(SKAction.sequence(actions))
    }
    
    rotateJoystick.on(.move) { [unowned self] joystick in
        guard let appleNode = self.appleNode else {
            return
        }

        appleNode.zRotation = joystick.angular
    }
    
    rotateJoystick.on(.end) { [unowned self] _ in
        self.appleNode?.run(SKAction.rotate(byAngle: 3.6, duration: 0.5))
    }
    
    //MARK: Handlers end
    let selfHeight = frame.height
    let btnsOffset: CGFloat = 10
    let btnsOffsetHalf = btnsOffset / 2
    let joystickSizeLabel = SKLabelNode(text: "Joysticks Size:")
    joystickSizeLabel.fontSize = 20
    joystickSizeLabel.fontColor = UIColor.black
    joystickSizeLabel.horizontalAlignmentMode = .left
    joystickSizeLabel.verticalAlignmentMode = .top
    joystickSizeLabel.position = CGPoint(x: btnsOffset, y: selfHeight - btnsOffset)
    addChild(joystickSizeLabel)
    
    joystickStickColorBtn.fontColor = UIColor.black
    joystickStickColorBtn.fontSize = 20
    joystickStickColorBtn.verticalAlignmentMode = .top
    joystickStickColorBtn.horizontalAlignmentMode = .left
    joystickStickColorBtn.position = CGPoint(x: btnsOffset, y: selfHeight - 40)
    addChild(joystickStickColorBtn)
    
    joystickSubstrateColorBtn.fontColor = UIColor.black
    joystickSubstrateColorBtn.fontSize = 20
    joystickSubstrateColorBtn.verticalAlignmentMode = .top
    joystickSubstrateColorBtn.horizontalAlignmentMode = .left
    joystickSubstrateColorBtn.position = CGPoint(x: btnsOffset, y: selfHeight - 65)
    addChild(joystickSubstrateColorBtn)
    
    jSizeMinusSpriteNode.anchorPoint = CGPoint(x: 0, y: 0.5)
    jSizeMinusSpriteNode.position = CGPoint(x: joystickSizeLabel.frame.maxX + btnsOffset, y: joystickSizeLabel.frame.midY)
    addChild(jSizeMinusSpriteNode)
    
    jSizePlusSpriteNode.anchorPoint = CGPoint(x: 0, y: 0.5)
    jSizePlusSpriteNode.position = CGPoint(x: jSizeMinusSpriteNode.frame.maxX + btnsOffset, y: joystickSizeLabel.frame.midY)
    addChild(jSizePlusSpriteNode)
    
    let startLabelY = CGFloat(40)
    
    setJoystickStickImageBtn.fontColor = UIColor.black
    setJoystickStickImageBtn.fontSize = 20
    setJoystickStickImageBtn.verticalAlignmentMode = .bottom
    setJoystickStickImageBtn.position = CGPoint(x: frame.midX, y: startLabelY - btnsOffsetHalf)
    addChild(setJoystickStickImageBtn)
    
    setJoystickSubstrateImageBtn.fontColor  = UIColor.black
    setJoystickSubstrateImageBtn.fontSize = 20
    setJoystickStickImageBtn.verticalAlignmentMode = .top
    setJoystickSubstrateImageBtn.position = CGPoint(x: frame.midX, y: startLabelY + btnsOffsetHalf)
    addChild(setJoystickSubstrateImageBtn)
    joystickStickImageEnabled = true
    joystickSubstrateImageEnabled = true

    addApple(CGPoint(x: frame.midX, y: frame.midY))

    view.isMultipleTouchEnabled = true
}


func addApple(_ position: CGPoint) {
    guard let appleImage = UIImage(named: "apple") else {
        return
    }
    
    let texture = SKTexture(image: appleImage)
    let apple = SKSpriteNode(texture: texture)
    apple.physicsBody = SKPhysicsBody(texture: texture, size: apple.size)
    apple.physicsBody!.affectedByGravity = false
    apple.position = position
    addChild(apple)
    appleNode = apple
}

}


#2

В контроллер (MapViewController), где используете любые объекты SpriteKit (напр. GameScene), импортировали SpriteKit (import SpriteKit)?


#3

Да. Обязательно. Проект ведь без импорта Sprite Kit не соберется, а он собирается, но падает при запуске.


#4

А еще вот такой момент отметил: при создании APP - есть файл SceneDelegate
а при создании game на базе Sprite Kit такого файла нет. Может в этом дело?