J2MEからAndroidへの汚いモバイル開発のトリック

携帯電話向けのゲームの開発を思い出す限り、すべてを適切に機能させるために、常にいくつかのトリックを発明する必要がありました。 15年前、この問題に直面して、彼らが白黒の携帯電話でもゲームを書いたとき、私たちは今直面しています。 デスクトップや、特にコンソール向けのゲームの開発には、こうしたトリックの巨大なセットが存在すると確信しています。 しかし、私は携帯電話をしているので、それらについて話しましょう。













J2me



J2MEの開発で最も汚いトリックは、ゲームのメインループ内に1つの一般的なtry-catchを配置することです。







public void run() { while(isGame) { try() { gameField.Update(); } catch (Exception ex) { } } }
      
      





その結果、例外はループ内でキャッチされます。 フレームは完全には処理されませんが、ゲームは落ちません-何も起こらなかったように、次のフレームが計算され始めます。 出撃禁止。

問題が非常に深刻で、すべてのフレームで発生する場合、副作用はゲームのフリーズです。

私はこの方法を一度使用しなければならなかったと告白します。 誰もがそうであるように、締め切りが迫っていて、バグはそうなることを拒否しました。













ほとんどすべてのプロジェクトで使用しなければならなかったトリックは、1つのレンダリングに対してロジックの2つの更新を呼び出すことです。

フリートの操作には多くのプロセッサ時間がかかるため、フレーム時間に応じてオブジェクトの更新を使用しないようにしました。 したがって、ロジックの複雑さとフレーム内のオブジェクトの数が増えて電話が対応できなくなった瞬間に、2つの更新を連続して実行しました。 ほとんどの場合、これはゲームの最終的なバランス調整前でも発生したため、実際には何の影響もありませんでした。

このような場合、なぜバランスが変わらず、フレームごとのオブジェクトがカバーする距離が長くなるのですか? まず第一に、おそらく衝突によるものです。 オブジェクトを長距離移動するには、より複雑な衝突ロジックを記述する必要があり、パフォーマンスに影響します。 また、長距離を走行するときのロジックが失敗することもあり、複雑になります。 まあ、一般的に、レンダリングはダブルボリュームでも処理ロジックよりもはるかに時間がかかったため、これが最も簡単でした。













J2MEが対処しなければならなかった別の問題は、メモリサイズでした。 さらに、RAMとビルド自体の供給の両方。 クラスの数を減らすことでかなり多くのことが節約できることが実験的に確立されました。 その結果、すべてのゲームロジックは1つのクラスに置かれました。 すべてのデータは配列にソートされました。 それらの1つにはオブジェクトのタイプ、もう1つにはそのロジックのタイプ、3番目にはロジックの状態、4番目と5番目にはX座標とY座標などがあります。 キットには、すべてをねじったオブジェクトのタイプによる大きなスイッチのあるサイクルがありました。 動的な割り当てと削除はなく、キャッシュミスが少なくなります。 それは非常に高速に動作しました。 メニュー、スプライト、タイルの背景、ゲームのメインサイクルのクラス。 その結果、ゲーム全体のJavaクラスは10個未満になります。 幸いなことに、私の「正しい」Java開発者の誰もこのコードを見たことはありません。







醸造









BREWの初期バージョンでは、画面を直接操作するためのAPIはありませんでした。 また、システムが提供するレンダリング機能は非常に低速でした。 画面バッファーは自分で見つけなければなりませんでした。 これを行うために、画面全体を赤色で塗りつぶし、空のスプライト(またはそれを呼ぶもの)を作成し、そのアドレスからメモリを双方向にスキャンしました。 画面領域より少し少ないバイト数で移動しました。 同様の組み合わせが見つかった場合は、画面を異なる色で塗りつぶし、いくつかの計算を使用してピクセル形式、画面バッファーの先頭、各行の後にインデントがあるかどうかを確認します。 すべては1秒もかからず、プレーヤーは何も気付かない時間を過ごしました。 画面上のプロセス全体の更新を含めなかったことは明らかです。







iOS(WoT Blitz)









iOSが対処しなければならなかった最も困難なことは、ゲームの起動時にメモリをクリアする必要があることでした。 状況によっては、すべての割り当てにカスタムアロケーターでメモリプールを使用しませんでした。 しかし、メモリ消費量は時々300 mbに近づいており、弱いデバイスでのアプリケーションの安定性にはあまり影響しませんでした。 本当の問題はiOS 7または8のリリースから始まりました。軸はピークメモリ負荷の瞬間に「ミスを犯し」、Blitzを閉じることがありました。 さらに調査した結果、iOSは1ティックで大量のメモリを割り当てることを本当に嫌うことがわかりました。 しかし、メモリを徐々に割り当てると、閉じられることを恐れることなく、制限をはるかに超えることができます。

すでに数十万人のプレイヤーがプレイしているプロジェクトでメモリ割り当てを再分配することは、長くて非常に危険です。 したがって、我々はわずかに異なる決定を下しました。 ゲームの開始時に、10 mbずつ、負荷がピークのときにゲームに必要な量のメモリを徐々に割り当てます。 そして、すぐにすべてをきれいにします。 1秒もかかりません。 また、ログで、軸が他のアプリケーションをどのように閉じるかを確認できます。 このトリッキーな方法で、ピークメモリ負荷中のゲームクラッシュを修正しました。













モバイルGPUの主な欠点の1つは、半透明のジオメトリのレンダリングが遅いことです。 そして、ゲームでは必死に茂みや木が必要です。 そして可能な限り。 問題は、プレイヤーが戦車の視界から直接発生するすべてをよく近似して観察するスナイパーモードがあるという事実によって複雑になりました。 時には、茂みや樹木の塗りつぶしが半透明のジオメトリの10スクリーンを超えました。

茂みの場合、解決策は非常に単純であり、それを思いついたのはプログラマーでもなく、アーティストでした。 ブッシュのほぼ近くでオンになり、1つのビルボードで構成された最も近いロッドを導入しました。飛行機は常にプレイヤーの方を向いていました。 これにより、比較的簡単に茂みに座り、敵の戦車を標的にすることさえ可能になりました。

木はあらゆる方向に地面に投げることができるため、木では少し複雑になることが判明しました。 彼らのために、プレイヤーがツリーに非常に近づいたときにオンになる特別なシェーダーを作成しました。 この庭師シェーダーは、余分な木の枝をすべて切り取り、カメラに最も近い3本だけを残します。 近くの枝はレビュー全体のほとんどを覆い隠しているという事実により、プレーヤーは他のレビューがないことに気づきません。 しかし、GPUは非常に注目に値します。







これらの解決策が問題から私たちを完全に救ったとは言いませんが、少なくともある程度の植生を許容できる量でマップに追加することができました。







狙撃モードでエフェクトを作成するときに同じ問題に直面しました。 スナイパーモードに加えて、カメラの近くにある種のパーティクルエフェクトがあり、FPSカウンターは約10でフリーズすることが保証されています(エンジンはそれ以下を許可しません)。 技術的にははるかに複雑でしたが、ソリューションは茂みに似ていました。 パーティクルの詳細レベルを導入しました。 そして、最も近い場所で、彼らは余分なものをすべて取り除きました(たとえば、ショットはフラッシュのように見えます)。 その結果、最大近似では、最も必要な効果のみが残ります。 逆説的ではありませんが、遠方のロッジは近くのロッジよりも詳細です。













ユーザー登録サービスで興味深い話が出ました。 それは兄の下で書かれており、クライアントがすべてを開始することを期待して良心のtwinがJavaScriptを送信することなく、すでにこのJavaScriptが次のhttp-requestを生成します。 モバイルWebビューはこれらの目的にはあまり適していませんでした。 私たちの場合、非表示にする必要があり、内部テストサービスでは、ユーザーに接続の確認を求めました。 さらに、これらすべてを別のスレッドでねじる必要がありました。 十分な時間はなく、必要な時間に登録サービスの変更を注文することはほとんど不可能でした。 そして、私たちの側のサーバーから来るスクリプトを解析し、それらに基づいて以下のリクエストを形成し、それらをサービスに送信する必要がありました。 後に、このプロセスの少しの標準化を可能にするいくつかの修正がありました。 奇妙に聞こえますが、それでも動作します。







Android(WoT Blitz)









Androidバージョンで作業している間、私たちは多くの重要なソリューションを探す必要がありましたが、それらは記事に値するものではありません。 パフォーマンステストを実施するために使用しなければならなかった非常に面白いことが1つあります。 実際、戦闘中、またはいくつかの戦闘中に、多くのAndroidデバイスが熱くなると、プロセッサの周波数は自動的に低下します。 これにより、FPSが低下します。 そして、毎日のパフォーマンステストの結果を多かれ少なかれ安定させたいと思っていました。 状況を調査した後、各テストの後にデバイスを再起動する必要があるという結論に達しました。 携帯電話はなんとか冷静になって心を変え、かなり予測可能な結果が得られます。 これにより、QAがアセンブリのプレイアビリティと品質をチェックするプレイテストがキャンセルされることはありませんが、デバイスのパフォーマンスの変化に気付き、対策を講じることができます。







そしてまた

また、ビルドを収集し、サーバーを更新し、トランクとユニットテストの状態を監視し、コードをレビューするプログラマーを割り当てる独自のSkypeボットもあります。 しかし、これはまったく異なる話です。







ご質問がある場合、またはモバイルライフハックを共有する準備ができている場合-コメントを書いて、私たちは議論します。








All Articles