SPriteKitゲームにおける多重アスペクト比と解像度


また、4 KのApple TVに小さなiPhoneから任意の画面上で一貫して任意の画面で動作するようにしている複数の解像度とアスペクト比をサポートするピクセルベースのゲームを構築するかなりの挑戦です.特に、ゲームプレイの経験は、同じように、デバイスが有利な画面サイズのために優位性を取得し、公正なままにする必要がありますファクタリングするときにも、任意の画面上で偉大に見えることを確認します.
私はちょうどShoriteKitフレームワークを使用して迅速に開発しているシュート' emのゲームのためのこの課題に直面している.問題を解決しよう.

問題


それは敵の波は常に同じ時に画面を入力し、同じ位置に残っている必要があります同じようにデバイスのプレイヤーは、アスペクト比で4 : 3(計算された)から19.5 : 9(iPhone 11)までの範囲を使用することができます.もう十分です.
離れて、同じ位置に表示されるから別の速度、位置、サイズ、パスのノードの座標などのようなものを考慮して、各プレーの正確な同じ時間で別の解像度の間に同じままにする必要があります.スケーリングとすべてのゲームの座標とエンティティの動作属性を補償すると、潜在的な悪夢は、実際のデバイスの解像度とゲームの世界の間に抽象化しない場合は処理することができます.

オプション


つの簡単な解決策は、所定のサイズでゲームを作り、それがデバイス画面上でできるだけ多くを使用し、それがフィットしないデバイス上のゲームの周りに黒いバーを持っているようにスケールすることです.LetterBoxがAppleと人気がないので、黒いバーの代わりにオプションのGUI要素のためにDeadスペースを使用すると仮定すると、いくつかのケースで潜在的解決策でありえました.しかし、大きくない.
実際には、常にデバイスの画面をフルに活用し、実際の死んでいる領域を持っていない場合はどのようなアスペクト比は、少しトリッキーな取得します.まだこのゲームのためには、ゲームを実行することができます各デバイス上の画面全体を埋めるために、実際のゲームエリアをしたいが、まだ一貫性のあるゲーム体験の初期条件に該当します.それで、基本的なレターボックスの形は受け入れられません.
次のオプションは、可能な限り広いスクリーンのためにゲームを設計することになっていて、プレーヤーがスクリーンの上で全部の遊び域に合うことができない装置の上でクラフトを動かすので、パンをそうさせます.プレーヤーが画面の端に向かって移動すると、カメラはより明らかにするために沿ってパンする.それはそんなに悪くないでしょう、そして、我々はレターボックスを取り除きました.shmupと狭い画面を持つデバイスの場合、この解決策は、プレイヤーが左と右のパトロールを維持しない場合は、プレーヤーが敵をスポッティングミスする可能性があります.それは、ゲームのデバイス間で一貫性を保つために要件を満たすように契約ブレーカです.他のゲームの種類のためにこれは良い方法かもしれない.
番目のオプションは、私が行くことに決めたものは、ゲームのポイント、ベースサイズを決定することです.私はゲームの論理的なサイズとしてこのサイズを参照します.ゲームは、論理的なサイズは常にデバイスの画面に収まるようにスケーリングされ、これはすべてのゲームプレイが行われ、すべての動きと時間の計算に使用する一貫した値を提供する領域です.バックグラウンドアートワークは、論理的なゲームのサイズの外に追加のスペースを持っているデバイス上に表示される追加の余白を持っている必要がありますので、背景は、画面を充填し、すべてのデバイス上で美しく見えるでしょう.重要なアクションは、メインエリアのゲーム体験をデバイス間で一貫性を保つためにマージン領域で発生します.
私が作った結論は、実際にこのタイプのゲームのためのレターボックスを使用せずにさまざまなデバイス間で完全に同一の経験をすることは不可能です.番目のオプションは、しかし、まだ各デバイスの偉大な探しながら一貫性を維持する許容レベルに十分近くに近い私たちを取得します.だからこれらの種類のゲームの多くのケースで最高のオプション.
実際の実装をもっと詳しく調べましょう.

論理サイズ


私は16 : 9のアスペクト比を与える960 x 540ポイントの論理的なサイズを使用することを決めた.私は、ゲームのサポートされているデバイスの任意の画面からあまりにも遠く離れて、中間のどこかにある快適なサイズであることがわかりました.
このアスペクト比を維持するために、まだ私は、論理的なサイズの外に展開し、任意のデバイス上の画面全体を埋めることができるように大きな余裕を持っている背景のアートワークを作成している任意のデバイスの画面を埋めるために.
iPhoneの8シリーズまでのiPhoneのために、16 : 9はすでに完璧なフィット感です.当然のことながらApple TVは、私は個人的にゲームデバイスとして最も楽しんでいるデバイスであり、TVOはおそらく私が最初にゲームをリリースするでしょう.
iPhone Xと他の新しい携帯電話は16 : 9より広いので、バックグラウンド・アートワークの追加マージンが必要な場合です.

この追加のスペースは、部分的にちょうど背景が画面全体を埋めるために視覚的なキャンディです.実際のゲームプレイがデバイス間で同じままであることを保証するために、マージンで起こっている重要な行動が全くありません.
一方、HUDは追加のサイズを利用するでしょう.これは、いくつかの種類のレターボックスを使用するのと比較して、この解決策がかなり異なっています.HUDはデバイスのフルサイズを使用して、デバイスの画面がそれを可能にするときに、ゲームのプレイエリアからの方法の親指スティック、火災のボタンや他のラベルのようなコントロールを移動します.

それから、私たちはスペクトルの反対側を持っています.ほとんどのiPadは、わずかにより広い11インチのプロのようないくつかの例外で、4 : 3のアスペクト比にあります.
計算されたのは、私がゲームのために4 : 3の論理サイズで行くと考えた理由でした.そのサイズは、より広い装置の上であまりに多くの「死んだ」スペースを生み出しました、そして、あまりに妥協しすぎました.それで、結局、私は現在、満足している16 : 9の中間の地面で終わりました.
計算されたために私は計算された画面の16 : 9のセクション内に収まるように論理的なゲームエリアを絞り込むために追加の高さを追加する余白を使用してください.当初、私はセンターからそれを成長させて、計算された上で一番上と底のマージンを持っているつもりでした.

トップにマージンを追加することにより、計算された他のデバイスと比較して視力の増加線を取得します.それは彼らのほとんどはトップから来るとして、敵を先に見て計算された上でプレーヤーの利点を与える.(私は、iPhoneが以前に彼らに会う側から来ている少数の敵を持つかもしれません、しかし、それはよりわずかな利点です).
解決するためには、代わりに画面の下部に全体のマージンを配置することは、計算された上でプレーを確保するためにゲームを維持し、デバイス間の公正を維持する前に敵をスポットさせていないことを確認します.下にいくつかの余分な部屋を得る最小限の余分な利点を追加する必要があります.

計算された上で余分な高さはまた、アクティブな再生エリアからの一部のタッチコントロールを移動するために使用されているので、サムネールと火災のボタンが可能なときにマージンに位置しています.

実装


実装は非常に複雑ではありません.私はゲームのコンフィギュレーション定数でenumを保ちます.そこで、私はサイズに基づいてどんな計算もする必要があるときはいつでも、私が言及することができるゲームの論理的なサイズのために定義を置きました.
enum GameConfiguration {
    enum Core {
        static let gameWidth: CGFloat = 960
        static let gameHeight: CGFloat = 540
    }
}
場面が提示されるとき、私はview.frame.sizeから実際の装置サイズを得て、論理的なサイズと一緒にそれを使用して、論理的サイズをビューに完全にフィットさせ、マージンを使うために必要とされるときにマージンを追加するシーンのサイズを得るために、デバイスサイズを分割するのに必要な要素を計算します.
class GameManager {
    func presentScene() {
        var factor = view.frame.size.height / GameConfiguration.Core.gameHeight

        if view.frame.size.width / factor < GameConfiguration.Core.gameWidth {
            factor = view.frame.size.width / GameConfiguration.Core.gameWidth
        }

        let sceneSize = CGSize(width: view.frame.size.width / factor,
                               height: view.frame.size.height / factor)
        let scene = LevelScene(size: sceneSize)
        scene.scaleMode = .aspectFit

        view.presentScene(scene)
    }
}

安全地帯


レベルのデザイン中に、敵の動きとその産卵とトリガーの位置を定義する私は重要なゲームプレイが発生する16 : 9セーフエリアで働いている.
私のレベルエディタの最新バージョンでは、私は別のデバイスのための安全な領域のオーバーレイを追加しましたので、私はトリガと位置は、任意のデバイス上で偉大に見える領域内にあることを確認し、同時に私はまた、背景のアートワークを適切に画面を埋めることができます.

これはまた、敵が突然16 : 9よりも他の比率でデバイス上に入力または終了しないことを確認することができます.レベルのデザインがどんなサポートされたスクリーンサイズででもうまく働くことを確実とするために、レベルの実体の位置決めの間、必要な調整を加えることができます.

資産決議


ゲームが論理的なサイズからスケーリングされたとき、私はアカウントを作成するときにアカウントにそれを取ると、彼らはゲームシーンの後に鮮明なままになります解像度でそれらを設計し、それが表示される実際の解像度に論理的なサイズからスケーリングされます.
私は960 x 540ポイントの所定のサイズで動作し、54ポイントのサイズでプレーヤーの工芸品を定義する可能性がありますが、実際のピクセルの解像度は、さまざまなデバイスのためにかなり異なります.54ポイントの資産は、完全にシャープで鮮明なままでいるために、4 kのアップルテレビの216ピクセルのピクセル解像度である必要があります.同じ54ポイントの資産は、完全に鮮明であるために、iPhone 8上で75ピクセルを必要とするだけです.
私はすぐに私は古い信頼スプレッドシートを使用している資産のピクセルサイズを計算するために.開発中に異なるものを追跡するとき、スプレッドシートがどれくらい便利であるかについて、私はしばしば忘れます.それで、私はポイントで資産サイズを変えることができて、迅速に各々の関連する装置のために完全なピクセルサイズを見る数でこの文書をつくりました.
必要な最高解像度はApple TV 4 K用です.スクリプトはまた、両方の作物のタイルと別のデバイス用のタイルを変更する背景のアートワークを処理します.
一度私は資産カタログジェネレータスクリプトを微調整した後、私はおそらくソースをオープンし、それをGithubに置くでしょう.