Qt 5.2、欲望からグーグルプレイへ

こんにちは同僚。



Qt5.2と、AndroidおよびiOS用のクロスプラットフォームアプリケーションを迅速かつ簡単に作成する新しい機能について聞いたことがありました。 私は長い間Qtに精通していましたが、最近、この作業は他の技術と結びつき、少し開発を始めました。 これを知ってから、Qt Webサイトに行き、美しいビデオを見ました。10分で、HelloWorldアプリケーションがandroidとiosのすぐ下に作成されます。 印象は非常にポジティブでした。



モバイル開発を行うことが決定されました。 アプリケーションを作成したいという欲求から、Google Playでの公開までの計画がありました。 しかし、最初の段階では、これが残念なことではなく、どのような間違いを犯す可能性があるかを確認したかったのです。 そして、これはすべて新しいQt5.2で。





同じ頃、よく知られているFlappy Birdについて聞いたのですが、その作者は彼のアプリケーションを削除することにしました。 次の決定はこのゲームの別のコピーを作成することであることは既に明らかですが、主な目標は新しいQt機能を試すことです。



C ++またはjavascriptの選択



もちろん私はc ++が大好きですが、そのような些細なことをあえて書きませんでした。 C ++を使用すると、開発者は思慮深く書き、「自分の足を撃たない」ように非常に注意する必要がありますが、私はXPスタイルのプロジェクトを迅速かつ最も重要なこととして動作させたいと考えました。 選択はQMLとjavascriptにかかっていましたが、同時にこれらの高度なDigiaテクノロジーに対処する機会もありました。



初稿



Qtをすばやくインストールし、qmlのドキュメントを読み、Flappy Birdのゲームメカニズムを確認しました(これまで聞いたことはありませんでした)、ゲームの最初のドラフトが作成されました。 シンプルなNumberAnimationを使用して、鳥の飛行と柱の動きをシミュレートしました。 すべてうまくいきましたが、疑問が生じました:





物理学



上記の2つの問題に対する唯一の正しい解決策として、よく知られているBox2Dの使用を検討しました。 qmlのプラグインがすぐに見つかりました-github.com/qml-box2d/qml-box2d 数日間の実験、box2dのドキュメントの読み方、すべてが書き直され、うまく機能しています。 しかし、問題は未解決のままです。





私自身はバックグラウンドミュージックが好きではないので、バックグラウンドミュージックを拒否しました。 www.freesound.orgでは、翼の羽ばたき、衝突、新しいポイントの3つの音が拾われました。

AudioManagerを使用してV-playからFlappy Birdを作成する良い例が、再生に使用されました。 しかし、ファイルは完全ではありませんでした。

import QtQuick 2.2 Item { id : audioManager property QtObject effect1: Qt.createQmlObject("import QtMultimedia 5.0; SoundEffect{}", audioManager); property QtObject effect2: Qt.createQmlObject("import QtMultimedia 5.0; SoundEffect{}", audioManager); property int hit: 22 property int point: 33 property int silence: 44 property int wing: 55 property bool effectSwitcher: false; function play( sound) { var effect; if( !effectSwitcher){ effect = effect1; effectSwitcher = true; }else if( effectSwitcher){ effect = effect2; effectSwitcher = false; } if(effect == null) return; switch(sound) { case hit: effect.source = "audio/sfx_hit.wav" break case point: effect.source = "audio/sfx_point.wav" break case silence: effect.source = "audio/sfx_silence.wav" break case wing: effect.source = "audio/sfx_wing.wav" break } effect.play(); } }
      
      







複製:

 audioManager.play( audioManager.wing);
      
      







すべてがデスクトップマシンで機能し、電話でアプリケーションがクラッシュしました。 理由はささいなことが判明し、次を.proファイルに追加する必要がありました。

QT += multimedia







SoundEffectが2つあるのはなぜですか、また、sfx_silenceが発生するバグの説明で以下に明らかになるのはなぜですか。



スケーリング



スケーリングは標準として行われました。 基本は480x800の解像度でした(小さいですが、現時点ではおそらく最も一般的です)。 彼に関連して、鳥と柱の寸法は厳しく設定されました。 次に、参照に対する現在の解像度のスケーリング係数の計算が簡単に行われ、スケーリングが必要なすべてのサイズに単純に乗算されます。 この例はbitbucket.org/wearyinside/cute-planeによってこれらすべてを大いに助けられましたが、いつものように多くの問題はそこで解決されませんでした。

  width: Screen.width height: Screen.height property int defaultWidth: 480 property int defaultHeight: 800 property double measure: Math.min(Math.min(width, height) / defaultWidth, Math.max(width, height) / defaultHeight) property double textScale: Math.sqrt( measure)
      
      





すべての物理オブジェクトは線形的に安定化されますが、高解像度でこのような安定化が行われたテキストはすべてのフレームを壊しました。 彼のために、私は主要な倍率の平方根スケーリングをしなければなりませんでした。



設計



私はプログラマーなので、デザインは私にとって密林でしたが、私たちのインターネットはすべてであり、このトピックに関するさまざまな記事を読んだ後、ベクターグラフィックスとInkscapeエディターが選択されました。 漫画の鳥を描くのに1〜2日しかかかりませんでした。 最初に、紙にスケッチが作成され、いくつかの可能なオプションが描かれました。 その後、最高がsvgに転送されました。 さらに、他のすべての画像はベクター形式で作成されました。 .proファイルのqmlでsvgファイルを使用するには、以下を追加する必要があります。

 QT += xml svg QTPLUGIN += qsvg
      
      







収益化



主要部分が書かれ、収益化の問題が生じました。 このプロジェクトは、テスト用ですが、すでに収益化に対処したいと考えていました。 ad admobによる収益化が選択されました。 そして、最初の深刻な問題が始まりました。 qt / qmlには、admobを埋め込むためのプラグインがないことが判明しました。 廃止されたqadmob実装と閉じたV-play AdMobプラグイン実装が見つかりました。 雲が厚くなり、より良い時まで思考がQtを離れるように見え始めました。 インターネット全体を破壊し、Qtソースを検索し、それがAndroid用にどのように作られているかを把握する必要があることが明らかになりました。 そして、4日間の発掘の後、ゲーム内にテスト広告バナーが表示されました。 github.com/AlexMarlo/AdMob-Qt5.2-Exampleの方法の例を次に示します。 一般に、バナーの表示には1週間かかりました。





その後、すべての主要部分が作成され、後で延期されるマイナーなバグを修正する必要があることが明らかになりました。



メモリリーク



ゲームの1分あたり100 MBでメモリリークが発生しました。 qmlコードに定期的にコメントを付け、結果を確認した後、問題が見つかりました。 この割り当てによりメモリがリークすることが判明しました。

  linearVelocity.x = 220; linearVelocity.y = -420;
      
      





このオプションを変更する

  var flyImpulseVelosityY = -420 * measure; var flyImpulseVelosityX = 220 * measure; var impulse; impulse = Qt.point( flyImpulseVelosityX, flyImpulseVelosityY); applyLinearImpulse( impulse, getWorldCenter());
      
      





リークが停止しました。 これはqml-box2dの問題のように見えますが、私はこれ以上深く掘り下げませんでした。



音の損失



非常に頻繁にタップするため、非常に頻繁に再生すると、別のサウンドファイルを再生する前にサウンドが安定して消えていました。 次に、2つのSoundEffectが表示されました。 さらに、これはアンドロイドでのみ現れました。 この消失を防ぐため、SoundEffectが交互に再生されます。 私は経験だけでそのような決定に至りました。 どうやらこれはQt自体の何らかの問題です。



ズームが有効な状態でBox2Dでアサート時にアプリケーションが終了しました



  width: Screen.width height: Screen.height property int defaultWidth: 480 property int defaultHeight: 800 property double measure: Math.min(Math.min(width, height) / defaultWidth, Math.max(width, height) / defaultHeight)
      
      





問題は最初の2行にあります。 判明したように、Screen、Screen.width、およびScreen.heightが呼び出されるqml要素が構築されるまで、それらは0になります。物理オブジェクトのサイズをゼロにすることはできないため、スケーリング係数は最初0であり、box2dはアサート時にアプリケーションを終了します。

これは、スケーリング係数がゼロ以外の値をとる瞬間にオブジェクトを動的に作成することによってのみ修正できました。



操作不能な音量調節



判明したように、Android向けQtの現在のバージョンでは、音量調節ボタンは機能しません。 同じQtのフォーラムのすべてのヒントは、アクティビティでボタンクリックをインターセプトすることを提案しました。

  @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ( keyCode == KeyEvent.KEYCODE_VOLUME_UP) { AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); int index = am.getStreamVolume( AudioManager.STREAM_MUSIC) + 1; if( index <= am.getStreamMaxVolume( AudioManager.STREAM_MUSIC)) am.setStreamVolume( AudioManager.STREAM_MUSIC, index, 0); } if( keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){ AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); int index = am.getStreamVolume( AudioManager.STREAM_MUSIC) - 1; if( index >= 0) am.setStreamVolume( AudioManager.STREAM_MUSIC, index, 0); } return super.onKeyDown(keyCode, event); }
      
      







さまざまなデバイスでのテストと再びバグ



次に、さまざまなAndroidでのテストフェーズがありました。これはおおよそのデバイスのリストです。





サムスン



そして、すべての問題はサムスンで出て行き、電話が良いほどバグが強くなり、これらの統計www.appbrain.com/stats/top-android-phonesから判断すると、 サムスンにバグを残すことは不可能です。



最初の音を再生するときの遅れ



何らかの理由で、SoundEffectによる最初のサウンド再生がハングし、その後すべてが正常に機能しました。 これはSamsung Galaxy S3で特に顕著でしたが、他のSamsungでも顕著でしたが、それほど目立ちません。 他のメーカーのデバイスでは、この問題はありませんでした。 ここにsfx_silence.wavが登場しました。 これは基本的に、ゲームのロード時に再生される空のサウンドファイルです。



Box2Dオブジェクトを動的に作成する際の遅れ



次の問題は、正しいスケーリングのためにBox2Dオブジェクトが動的に作成されたためで、この作成はSamsung、特に同じSamsung Galaxy S3で非常に遅くなりました。

土地オブジェクトの作成:

ネクサスワン 97ミリ秒
Samsung Galaxy S Duos 986ミリ秒


違いは桁違いですが、qml-box2dとBox2D自体の実装の微妙な違いを理解していませんでしたが、ゲーム全体がロードされた時間に作成全体を転送しました。 ロードには時間がかかりますが、ゲーム中はブレーキがかかりません。



結論:



Qt for Androidは、多くの不明瞭なバグや欠陥があるにもかかわらず、開発に非常に適しています。 特に、すでにQtに精通している場合。 しかし、ネットワーク上で答えが得られない問題に遭遇するという事実に備えなければなりません。



解決できなかったマイナスの1つは、アプリケーションのサイズが大きいことです。



最も悲しいことは、約70%がQt自体のライブラリであり、これを我慢する必要があるということです。 一方、最新のデバイスでは、このサイズはそれほど重要ではありません。



PS:

結果のスクリーンショット:

スクリーンショット1






スクリーンショット2






スクリーンショット3






スクリーンショット4







All Articles