2016-08-20 12 views
0

現在、Swift 3、SpriteKit、およびXcode 8 betaを使用してゲームを開発中です。私は静的な3Dタッチのクイックアクションをホームスクリーンからinfo.plistを通して実装しようとしています。現在のところ、アクションはホーム画面からうまく表示されますが、右には行かないSKScene - シーンが変更されていないことを意味する初期シーンまたは最後に開いたシーン(アプリケーションがまだ開いている場合)に移動します。私はswitch文の中でシーンを設定するさまざまな方法を試しましたが、SKSceneを線として表示するためには正しく動作しないようです。window!.rootViewController?.present(gameViewController, animated: true, completion: nil)はUIViewController上でのみ動作します。3D TouchクイックアクションがSpriteKitで正しく動作しない

このコードのさまざまな部分はさまざまなチュートリアルからのものですが、壊れた部分が(私が間違っていない限り)提示されているシーンであることはかなり確信しています。部品が壊れている。

AppDelegateからSKSceneを提示する方法や、switch文に基づいてオープニングシーンを設定する方法はありますか?

AppDelegate

import UIKit 
import SpriteKit 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate { 

    var window: UIWindow? 


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
     // Override point for customization after application launch. 

     guard !handledShortcutItemPress(forLaunchOptions: launchOptions) else { return false } // ADD THIS LINE 

     return true 
    } 
} 

extension AppDelegate: ShortcutItem { 

    /// Perform action for shortcut item. This gets called when app is active 
    func application(_ application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) { 
     completionHandler(handledShortcutItemPress(forItem: shortcutItem)) 

    } 
} 

extension AppDelegate: ShortcutItemDelegate { 

    func shortcutItem1Pressed() { 

     Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(loadShopScene), userInfo: nil, repeats: false) 
    } 

    @objc private func loadShopScene() { 
     let scene = ShopScene(size: CGSize(width: 768, height: 1024)) 
     loadScene(scene: scene, view: window?.rootViewController?.view) 
    } 

    func shortcutItem2Pressed() { 
     Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(loadGameScene), userInfo: nil, repeats: false) 
    } 

    @objc private func loadGameScene() { 
     let scene = GameScene(size: CGSize(width: 768, height: 1024)) 
     loadScene(scene: scene, view: window?.rootViewController?.view) 
    } 

    func shortcutItem3Pressed() { 
     // do something else 
    } 

    func shortcutItem4Pressed() { 
     // do something else 
    } 

    func loadScene(scene: SKScene?, view: UIView?, scaleMode: SKSceneScaleMode = .aspectFill) { 
     guard let scene = scene else { return } 
     guard let skView = view as? SKView else { return } 

     skView.ignoresSiblingOrder = true 
     #if os(iOS) 
      skView.isMultipleTouchEnabled = true 
     #endif 
     scene.scaleMode = scaleMode 
     skView.presentScene(scene) 
    } 
} 

3DTouchQuickActions.swift

import Foundation 
import UIKit 

/// Shortcut item delegate 
protocol ShortcutItemDelegate: class { 
    func shortcutItem1Pressed() 
    func shortcutItem2Pressed() 
    func shortcutItem3Pressed() 
    func shortcutItem4Pressed() 
} 

/// Shortcut item identifier 
enum ShortcutItemIdentifier: String { 
    case first // I use swift 3 small letters so you have to change your spelling in the info.plist 
    case second 
    case third 
    case fourth 

    init?(fullType: String) { 
     guard let last = fullType.components(separatedBy: ".").last else { return nil } 
     self.init(rawValue: last) 
    } 

    public var type: String { 
     return Bundle.main.bundleIdentifier! + ".\(self.rawValue)" 
    } 
} 

/// Shortcut item protocol 
protocol ShortcutItem { } 
extension ShortcutItem { 

    // MARK: - Properties 

    /// Delegate 
    private weak var delegate: ShortcutItemDelegate? { 
     return self as? ShortcutItemDelegate 
    } 

    // MARK: - Methods 

    /// Handled shortcut item press first app launch (needed to avoid double presses on first launch) 
    /// Call this in app Delegate did launch with options and exit early (return false) in app delegate if this method returns true 
    /// 
    /// - parameter forLaunchOptions: The [NSObject: AnyObject]? launch options to pass in 
    /// - returns: Bool 
    func handledShortcutItemPress(forLaunchOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 

     guard let launchOptions = launchOptions, let shortcutItem = launchOptions[UIApplicationLaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem else { return false } 

     handledShortcutItemPress(forItem: shortcutItem) 
     return true 
    } 

    /// Handle shortcut item press 
    /// Call this in the completion handler in AppDelegate perform action for shortcut item method 
    /// 
    /// - parameter forItem: The UIApplicationShortcutItem the press was handled for. 
    /// - returns: Bool 
    func handledShortcutItemPress(forItem shortcutItem: UIApplicationShortcutItem) -> Bool { 
     guard let _ = ShortcutItemIdentifier(fullType: shortcutItem.type) else { return false } 
     guard let shortcutType = shortcutItem.type as String? else { return false } 

     switch shortcutType { 

     case ShortcutItemIdentifier.first.type: 
      delegate?.shortcutItem1Pressed() 

     case ShortcutItemIdentifier.second.type: 
      delegate?.shortcutItem2Pressed() 

     case ShortcutItemIdentifier.third.type: 
      delegate?.shortcutItem3Pressed() 

     case ShortcutItemIdentifier.fourth.type: 
      delegate?.shortcutItem4Pressed() 

     default: 
      return false 
     } 

     return true 
    } 
} 

答えて

1

あなたのコードは、アプリのデリゲートにあなたがGameViewControllerの新しいインスタンスを作成しますので、作業の代わりに、現在の1

を参照していません
let gameViewController = GameViewController() // creates new instance 

私は2つのゲームで3dタッチのクイックアクションをしようとしています。私はappDelegateからシーンを直接ロードしますが、これのためにgameViewControllerシーンを変更しようとはしません。

私はこれに再利用可能なヘルパーを使用します。 info.plistですべてを正しく設定したと仮定します。 (私は列挙型の小文字を使用して、info.plistの.first、.secondなどでアイテムを終了します)、以前に3d touchのクイックアクションで使用していたアプリケーションデリゲートコードをすべて削除します。これは、迅速な3コードで、プロジェクト内の新しい.swiftファイルを作成し、このコード

を追加するより 。アプリデリゲートに比べ

import UIKit 

/// Shortcut item delegate 
protocol ShortcutItemDelegate: class { 
    func shortcutItemDidPress(_ identifier: ShortcutItemIdentifier) 
} 

/// Shortcut item identifier 
enum ShortcutItemIdentifier: String { 
    case first // I use swift 3 small letters so you have to change your spelling in the info.plist 
    case second 
    case third 
    case fourth 

    private init?(fullType: String) { 
      guard let last = fullType.componentsSeparatedByString(".").last else { return nil } 
      self.init(rawValue: last) 
     } 

     public var type: String { 
      return (Bundle.main.bundleIdentifier ?? "NoBundleIDFound") + ".\(rawValue)" 
     } 
    } 

    /// Shortcut item protocol 
    protocol ShortcutItem { } 
    extension ShortcutItem { 

    // MARK: - Properties 

    /// Delegate 
    private weak var delegate: ShortcutItemDelegate? { 
     return self as? ShortcutItemDelegate 
    } 

    // MARK: - Methods 

func didPressShortcutItem(withOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
    guard let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem else { return false } 
    didPressShortcutItem(shortcutItem) 
    return true 
} 


/// Handle item press 
@discardableResult 
func didPressShortcutItem(_ shortcutItem: UIApplicationShortcutItem) -> Bool { 
    guard let _ = ShortcutItemIdentifier(fullType: shortcutItem.type) else { return false } 

    switch shortcutItem.type { 

    case ShortcutItemIdentifier.first.type: 
     delegate?.shortcutItemDidPress(.first) 

    case ShortcutItemIdentifier.second.type: 
     delegate?.shortcutItemDidPress(.second) 

    case ShortcutItemIdentifier.third.type: 
     delegate?.shortcutItemDidPress(.third) 

    case ShortcutItemIdentifier.fourth.type: 
     delegate?.shortcutItemDidPress(.fourth) 

    default: 
     return false 
    } 

    return true 
    } 
} 

この方法で拡張機能を作成します(あなたのコードでこれを逃した)

extension AppDelegate: ShortcutItem { 

    /// Perform action for shortcut item. This gets called when app is active 
    func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) { 
     completionHandler(didPressShortcutItem(shortcutItem)) 
    } 

あなたはこの

のように見えるためにあなたのAppDelegateにdidFinishLaunchingWithOptionsメソッドを調整するために必要以上に
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
    // Override point for customization after application launch. 

    ... 

    return !didPressShortcutItem(withOptions: launchOptions) 
} 

最終的に、ShortcutItemデリゲートに確認する別の内線番号を作成する

extension AppDelegate: ShortcutItemDelegate { 

    func shortcutItemDidPress(_ identifier: ShortcutItemIdentifier) { 

    switch identifier { 
    case .first: 
     let scene = GameScene(size: CGSize(width: 1024, height: 768)) 
     loadScene(scene, view: window?.rootViewController?.view) 
    case .second: 
     // 
    case .third: 
     // 
    case .fourth: 
     // 
    } 
} 

func loadScene(scene: SKScene?, view: UIView?, scaleMode: SKSceneScaleMode = .aspectFill) { 
    guard let scene = scene else { return } 
    guard let skView = view as? SKView else { return } 

    skView.ignoresSiblingOrder = true 
    #if os(iOS) 
     skView.isMultipleTouchEnabled = true 
    #endif 
    scene.scaleMode = scaleMode 
    skView.presentScene(scene) 
    } 
} 

私は通常私がFUNCにビューを渡す理由は別のヘルパーを持っている負荷シーン方法。

これが役に立ちます。

+0

驚くばかりです。問題を申し訳ありませんが、それはすべて素早く3構文のものでした。私の答えに印をつけてください。なぜタイマーを使うのか覚えていない。あなたは遅れを好まない場合は時間を短縮しようとか、まったくいずれかを使用いけません。 – crashoverride777

+0

多くの作業をやり直す必要がある場合でも、AspectFillを使用するために他のシーンをやり直すことにします。私が話した私の2つのゲームは、私がそれを変更する前にResizeFillを使っていたことを信じています。すべてのデバイスで一貫性を持たせるのは悪夢でした。 – crashoverride777

+1

あなたは大歓迎です。シーンスケーリングに戻るために、ResizeFillを使用しないと、将来私の束に感謝します。これを非常に簡単にテストできます。新しいXcode Gameテンプレートを作成します。プロジェクトを実行する場合のデフォルト設定を使用すると、HelloWorldラベルはすべてのiPhone(5,6,6plus)で完全に拡大縮小されます。次に、GameViewControllerに移動し、スケールモードをResizeFillに変更して、すべてのデバイスで実行します。すべてのデバイスで同じように見えることはありません。私は手動でこれを行うヘルパーを使用して、これも物理的な衝動などのものを覚えています。それは狂気でした – crashoverride777

関連する問題