ラベル アプリ の投稿を表示しています。 すべての投稿を表示
ラベル アプリ の投稿を表示しています。 すべての投稿を表示

2018年4月9日月曜日

cocos2d-xを始めてみる。

HSPでプログラム作っていたんだが、ちょっと浮気して、
別の言語を試してみようと思い立つ。

Windowsでゲームが作れるものといえば、Unityとか思いつくが、
ライセンスであったり、ロゴ表示の問題もあるので、
フリーで使用できるという観点で、cocos2d-xに決定。

スマホアプリを作るイメージがあるが、当然、Windows用も作れる。
導入から解説しているページを見て、サクッと作るぜ!

…。
…。

と思い立ってから、サンプルを実行するまで、5時間もかかったわ!!

VisualStudioはインストールしていたものの、C++での開発環境入れてないとか、
他にもcocosをビルドするのに足りないパッケージがあるとか、
導入について解説している内容では全然足りないって!

という過程を経て、ビルド環境と実行環境を得る。
30分でサンプルが動くHSPとはえらい違いだ。

まあ、その分、C++(っぽいもの)で開発できる、実行速度が速い、というメリットはあるが…。

そもそも、AndroidやiOSで動くものも作れるという時点で、
素のC++ではなく、覚える作法(APIとか)はいっぱいあるわけで、
その点については、HSPから乗り換えるメリットは薄い。

逆に、ゲームを作るのに覚える量は変わらないので、乗り換えによるデメリットもないとも言える。
とりあえず1週間ほど触ってみて、無理ゲーだったら、HSPでがんばろう。

2017年7月21日金曜日

Androidカメラとバーコード

以前作っていたカメラアプリを、最新の自前フレームワークに対応させて復活。

と言っても、カメラのプレビュー映像が表示されるだけだが、
Androidでカメラ使ったアプリの開発経験があれば、それだけでかなり大変だと分かるはず。

で、これをバーコード読み込みに対応させるのが今回の目的。
元々は、秋葉原で購入したUSBのバーコードリーダーを800円でゲットし、
OTGケーブルで接続して使っていたのだが、
カメラでさっと読み込みしたいじゃない?

幸い、GooglePlayサービスに、バーコード読み込みのAPIがあるってことだし、
試してみることに。

実際に、カメラアプリを作ったことがあれば、
http://dev.eyewhale.com/archives/1372
ここをさっと流し読みするだけで、30分でできるはず。

まあ、実際には、足りないSDKをダウンロードしたりの時間も含まれるわけですが。
(API21、Android5.0以上じゃないと使えないっぽいです)

で、早速組み込んだアプリを実機テスト。
実機テストでおなじみの nuuX4の登場です。

いやあ、想像していたのより、さくさく読めますね。
バーコードの読み取りが成功する度に、コールバックが呼ばれるので、
ずっとバーコードをかざしていると、毎フレーム呼ばれます。
なので、自前で排他処理とかが必要。

とか、そんなのは、どうでも良し!
もっと深刻な問題が!

ネット検索すると、同じようにGooglePlayサービスでバーコード読み取りしている人はたくさん居て、皆、読み取りがすごいと、感心しているのですが…。

これ、超高性能カメラ専用APIだった!?

サンプルでは、デフォルトで背面カメラをしているのだが、
私は、正面カメラ(自撮用、フロントカメラ)で読み込みたいのです。

しかしこれが全く読み込めない。
極たまに1フレームだけ読み込めるときがあるので、プログラムが間違っているわけでは無いと思う。

実際に表示されるプレビュー映像を見れば分かるのだが、
フロントカメラの場合、バーコードの線が潰れて読み取れないような映像になっている。
バックカメラ二すると、ものすごく綺麗なプレビューが表示されて、さっと読み取れる。

nuuX4のカメラは、相当良いものだ。
バックカメラは1300万画素だし、フロントカメラも500万画素ある。
この画素で潰れて読めないとか、ありえなさ過ぎる…。

カメラの設定かもと思ったが、用意されているカメラの設定APIには大したものがない。

https://developers.google.com/android/reference/com/google/android/gms/vision/CameraSource

プレビュー解像度は、1920x1080にしているし、オートフォーカスも trueだ。
後はマクロ撮影があればいいのだが、カメラが対応していても、APIがない。

バーコード関係なく、nuuX4標準でついてるカメラアプリでも、フロントカメラは同じように潰れているので、もはや設定ではどうしようもないのかもしれないが、
そうすると、このGooglePlayサービスのバーコード読み取りAPIは、1300万画素程度ないと、使えないということか?

読み取れないって人がたまにいるけど、もしかしたら、この問題と同じなのかもしれない…。


2017年3月9日木曜日

昔の俺ぇえええ!!

ラターシュ名で、ずいぶん昔にゲームを公開していた。
今は死語だが、昔は「ホームページ」で「Javaアプレット」が動いていたんだ。

というわけで、当時のソースを引っ張りだしてきた。
(探さなくても、メインPCにずっと入ったままだのだが)

しかし、残念ながら、今時のブラウザでは、Javaアプレットは動作しない。
だが、コマンドラインから、appletviewerを使うことで問題なく動作する。

今でもそうだが、なるべくコマンドラインで全部済ますようにしていたため、
各ゲームのフォルダに入っている、コンパイル用バッチと起動用バッチで、さくっと操作できる。

ソースも、ちょっと見れば、思い出した。

なんで今さらそんなものを…?
Androidアプリを作るのに、昔のゲームを移植してみようと思ったわけだ。

ホームページ公開時には、(無料で配布していたこともあって)それなりに人気シリーズだった。
で、日の目を見なかった未公開シリーズもそれなりに数があるのだ。

それらを再度検証して、使えればみっけもの。
と思ったのだが…。

なんだこれは!!
昔の俺、すごすぎるじゃないか!
今遊んでも十分面白いミニゲーム群。

ゲームとゲームの間の演出効果、テンポ、センス。
どれも今の俺に足りないものばかりじゃないか!

これは、みっけものどころじゃないぞ。



2017年1月11日水曜日

MOVERIO カメラアプリを真面目に考えてみる / その2

MOVERIOは、自分で色々作らないと話にならない…。
ということで、まずは、カメラアプリから、作ろうということにしたんだが。

音量が小さい問題とか、Androidでタッチが認識されない問題とか。

検証アプリ作ったりで、時間取られまくったけど、ようやく本来のカメラアプリが開発できる…?

かと思いきや、MOVERIOは、やはりコントロールBOXの入力がトリッキーらしい。
こちらの記事でも書きましたが、まずは、タッチパッドで長押しすることから始まる。

実際、ギャラリーなど、Androidで共通で使われるアプリを操作してみると、正しく操作できているように思える。

例えば、タッチパッドを長押しして、カーソルが○⇒●に替わった瞬間に、左にはじくと、左フリックになる。
(ホーム画面が右にスクロールする)

だが同じことを自作アプリでやっても、Activityの onTouchEvent() にブレークが来ない!
カーソルが○のまま移動する、HOVERに関しては、がんがんブレークに引っかかってくるのだが、onTouchEvent() には、全く来ない。

と思いきや、たまに来る。

コントロールBOXは特殊な操作なので、HOVERの内部で、タッチイベントを発行しているのではないかと推測できるが、これまた検証だよ…。

ついでに、サイドの物理ボタンも検証するか。
技術資料によると…。

お、トラックパッドで取得できるイベント一覧もあるぞ。

onTouchEvent 発生することになってるな。いや発生はするけど、タイミングおかしいんだけど。

まあ、それは検証に回して、キーに関しては、

Volume Up
Volume Down
Back Key
Up
Down
Left
Right
Enter Key

通知されるのは、これくらいか。
Back Keyは使いにくいので、それ以外だな。


2016年12月20日火曜日

MOVERIO カメラアプリを真面目に考えてみる

今年こそは、Google Playに何か公開するぞー、と正月くらいに言った気がするが、もう12月も終わりだ。

Google Playにあるフリーのアプリも充実してきているので、色々なアイディアを詰め込まないと、目に留まる事すらないだろうな。

今回趣味で、エプソンのMOVERIO BT-300を購入したのだが、アプリが非常に少ない。
プリインアプリも少ないし、専用の AppStoreにも、アプリは少ない。

 ←これ

さらに操作しにくいなどの問題もあるので、たとえ、AmazonAppをインストールしても、
普通のアプリをするのにも、正直向かないと思う。

ガジェットのブログで、MOVEIRO BT-300 のレビューを書いていて、
http://latache-gadget.blogspot.jp/search/label/MOVERIO

そこでも解説しているとおり、プリインのカメラアプリがいけてない

現在、MOVERIO App Store にある、普通のカメラアプリは、PIPカメラくらいしかない。
これは、写真に任意の画像を重ねて撮影できるというもの。

ホワイトバランスなどの一部の機能は使えるようになっているが、撮影操作や、画面UIなどに一部気になる点がある。

というわけで、これらを踏まえ、ふつーのカメラアプリを AppStore で公開することを目標として、企画(仕様)を考えてみよう。
今回、動画の撮影については、対象外とする。

まず、カメラアプリに必要な機能と、操作、MOVERIOの実際のスペックなどをリストアップする。

必要な機能
 写真を撮影する操作
 ズーム
 メニュー(設定)を呼び出す操作
 アプリを終了する操作

カメラのプレビュー映像が表示されている、アプリの基本画面で必要な操作は、この4つ。
メニューの中にアプリ終了を内包してもいいが

メニュー詳細
 ホワイトバランス切替
 シーン切替
 エフェクト切替
 設定
 戻る


これらを誤動作しないようなUIで操作したい。

使用できる機能
 コントロールボックス
  ボタン3つ
  タッチパッド
  十字ボタン
 ジャイロ
 ミュートタップ

このうち、ミュートタップは使えたものではないので、却下。
やっぱり、タッチパッドか…。

2016年12月16日金曜日

GLSurfaceViewを使ってみる3

ゲームの演出に必要なので、テクスチャを回転させてみる。

ポリゴンの回転は普通にできたのだが、それにテクスチャを張ると、絵柄が潰れてしまった。

縦長の画像を張って90°回転したのだが、微妙に潰れたのだ。

その潰れ方の比率からすると、おそらく、ディスプレイのアスペクト比の問題だろう。
OpenGL系では、座標はピクセル単位ではない。

F-10Dのディスプレイサイズは、720x1280 だが、
それを -1.0~1.0 という数値で指定する。

その辺りを考慮して、ビューポートの設定をしてみた。

gl.glViewport(0, 0, H, H);

H:画面の縦ピクセル数

この設定で回転させると、90°でも、ゆがまずに回転した。

それはそれで良かったのだが。

今回用いたのは、128x512 という縦長の画像。
ところが、他の解説サイトを見ていたら、次の一文が載っていた。

「OpenGL ESでは、正方形の画像データしかテクスチャマッピングの元画像として受け入れてくれない。」

表示できているけども…?

----追記

上記のビューポート設定だと、横画面(Landscape)の時に座標が狂ったので修正。

if ( landscape ) { // 横画面 (LandScape)
gl.glViewport(0, H -W, W, W);
} else { // 縦画面 (Portrait)
gl.glViewport(0, 0, H, H);
}

 W:画面の横ピクセル数
 H:画面の縦ピクセル数

2016年10月20日木曜日

GLSurfaceViewを使ってみる2

私が使用しているスマホが、4年前のF-10Dなので、OpenGL ES 1.0 にしか対応していない。
今時、1.0で作るのもどうかとは思うが、テストで作ってるだけだし。

でもソースコードに、

GL10

という記述をしているため、あとでバージョンを上げると、この辺りを全部差し替える作業が発生するな…。

などと思いつつ、背景部分の移植完了。
背景は、良く使う手として、小さい画像をタイル状に敷き詰めて、スクロールさせている。

Canvasを用いた描画では、画像を何枚も並べて描画していたが、GLを用いると、1枚のポリゴンに、UVを設定するだけでいい。

具体的には、u = 0.0 ~ 1.0 とすれば、1枚分が表示されるが、
u = 0.0 ~ 5.0 にすれば、5枚分が表示される。

ところが、パターンが細かい画像を使用したので発覚したのだが、フルスクリーンのうち、数か所がたまにちらついて見える。

これは…いわゆる、ダブルバッファを使わないといけない案件か?
しかし、OpenGL ES1.0には、フレームバッファはなく、
1.1のextensionを使わないといけないらしい。

しかも extensionだから、どの端末でも実装されているという保証はない。
いやまあ、1.0で作ってるのが悪いんだけど。

ところが、だ。
テストを重ねると、どうやら、描画が追い付かずにちらついているわけではないらしい。

スクロールさせるために、uvをそれぞれ、0~1の範囲で動かしているわけだが、

u= 0.184f;
v = 0.816f;

と設定すると、描画が崩れる。

これは…単なる float誤差か?

しかも、全体の一部の描画のときだけ??

面倒くさいのきたー。

2016年10月14日金曜日

GLSurfaceViewを使ってみる1

基本、2Dのゲームしか作らないので、ずっとSurfaceViewを使っているが、実行速度を上げようと思い、試しにOpenGLを使ってみることにした。

ネットを見てみると、SurfaceViewとViewの速度について、ハードウェアアクセラレーションやら GPU使用やら、条件でどちらが速いか変わるし、デフォルトの設定がどうなっているかも機種によって違うとか何とか。
面倒くさいのう。

手持ちのメイン機種 F-10D (4年前のモデル)では、SurfaceViewの方が速かった。
GPUのON/OFFでも比べたが、OFF(デフォルト)の方が速い。

SurfaceView では、40FPS程度のものが、GPU使用使用にすると、30FPSくらいに落ちる。
ほぼ何も表示しない状態でも、50FPSを超えるかどうか、というのが最速。

それに対し、それよりももっと負荷が高い表示(128x128の画像100個)でも、GLSurfaceViewは、60fps前後を維持できた。
やはり高速だ。

ただ問題もあって、GL系だと、フォント表示が面倒になる。
そもそも、画像1枚表示するにも、テクスチャバッファ作って、頂点バッファ作って…とか、色々面倒だし。

この辺りの手順、どうせ誰が作っても一緒なんだし、そろそろスマートになってもいいと思うんだけど…ならないねぇ。

逆にGLで楽になるのは、タイルパターンの描画かな。

通常のdrawBitmapでタイルペイントすると、始点の変更ができないが、GLだとuvをいじるだけで表現できるしね。

2015年1月22日木曜日

カメラのプレビューとSurfaceViewのサイズ

カメラのプレビューサイズと、SurfaceViewのサイズについては、カメラアプリを作るときに必須の知識で、すでに多くのサイトで解説がなされているので、さらっとおさらい。

カメラのプレビューサイズは、任意に決定できない
サポートされているサイズセットの中から選ぶ

プレビューサイズは、端末の画面サイズと同じとは限らない
(というか、一致しない方がデフォルト)

プレビューサイズを設定しても、最終的には、SurfaceViewのサイズになる
(viewのサイズに、ViewGroup.LayoutParams.WRAP_CONTENTを指定した場合など)

なので、16:9のアスペクト比を持つ画面いっぱいのViewに、4:3のプレビューを表示すると、横に伸びた映像になる。
この辺りを、どう解決するかで、みんながググる事になる。

一般的な解決方法は、SurfaceViewを作って、レイアウトにaddView() する際に、
プレビューの比率に合わせてサイズを指定することである。

しかしこのSurfaceViewのサイズ、一旦決めたら、変更するのがなかなか難しい。
もし、画面サイズが変わる端末があったら、プレビューが見切れたりしてしまう。

そんな、恐ろしい端末が、s5110bである!


画面下のアクションバーを(アプリ起動中でも)いつでも出し入れできるのだ。
アクションバーが消えているときは、画面一番下を横にスワイプすることで出てくる。

アクションバーが表示された状態。⏬をタッチすると消える。

アクションバーが消えた状態。背景画像も隠れていた部分が表示されている。

ちなみに画面サイズは、[800x480] [800x432]で、アクションバーの高さは48ピクセル、
割合にして、10%も変化してしまう。

アクションバーを出した状態で、カメラアプリを起動し、アクションバーを消すと、変な空白が生まれる。

この微妙な見た目に対応するためには、どうにかしてSurfaceViewのサイズを更新する必要がある。

画面サイズが変更されるので、onSizeChanged()が呼ばれるが、名前の通り、サイズが変更"された"ときに呼ばれるメソッドで、ここで何をしても、何も変化は起こらない。

そこで、見つけたのが、onMeasure() だ。

これは、画面サイズ更新時(だけではないが)に呼ばれ、
各Viewのサイズを算出して設定するメソッドだ。
ここで更新後の新サイズが取得でき、かつ、まだ反映される前のタイミングで取得できる。
試しに100x100を設定したら、そのサイズで反映された。

まあ、自力で算出しろってことだ。

そんなこんなで、実際のコード。
カメラのプレビューは、アスペクト比4:3から変更するつもりがないので、固定で書き込んでいる。


@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  int widthMode= MeasureSpec.getMode(widthMeasureSpec);
  int heightMode= MeasureSpec.getMode(heightMeasureSpec);
  //新サイズ
  int w = MeasureSpec.getSize(widthMeasureSpec);
  int h = MeasureSpec.getSize(heightMeasureSpec);
  //変更後のサイズ
  int dw = w;
  int dh = h;

  switch(widthMode) {
  case MeasureSpec.EXACTLY:// 確定
    break;

  case MeasureSpec.UNSPECIFIED:// 自由
    dw = h *4 /3;
    break;

  case MeasureSpec.AT_MOST:// 以下
    dw = h *4 /3;

    if ( dw > w ) {
      dw = w;
    }
    break;
  }

  switch(heightMode) {
  case MeasureSpec.EXACTLY:// 確定
    break;

  case MeasureSpec.UNSPECIFIED:// 自由
    break;

  case MeasureSpec.AT_MOST:// 以下
    dh = dw *3 /4;
    if ( dh > h )
     dh = h;

    break;
  }

  //サイズ反映
  setMeasuredDimension(dw, dh);

}