2013年 12月

Stream API の復習

Java

来年の3月18日に Java 8 がリリースされるとあってこのところ日本語での情報もたくさんネット上に出回ってきました。

以前、「JDK8 Lambda その他いろいろ なんでもいいから動かしてみる」シリーズ、「もっと Lambda」シリーズのエントリーで適当に遊んでました。

少し API の変更などあって動かなくなってしまったサンプルもあります。

そこで Java Advent Calendar 2013 のエントリーで復習にぴったりの記事を見つけたので写経させていただくことにしました。

メッセージに「ラムダについて、○ん○出して考えてみた!」とあってビックリしました。

最初「ラムダについて、うんこ出して考えてみた!」と連想してしまい、なんだ!この人はと驚きました。

少ししてから「ラムダについて、ほんき出して考えてみた!」だよなって別解がでました。

まぁ、わざわざ伏せているところをみると作者の罠にまんまとはまったと思う。

ちなみに、○ん○出して考えてみた!というサイトは下記です。

ラムダ禁止について本気出して考えてみた – 9つのパターンで見るStream API

とてもいいですね。

ただ禁止度があるのですがこれはこのサイトの著者が独断で考慮して決められているようです。

プロフェッショナルプログラマの判断なのでおそらくこれに準ずるような企業が多くなるのでしょうかね。

私個人としては、女性と API は新しい方が良い!と言う人間なので

「8. stream中に元のオブジェクトを操作」 以外は使ってもいいんじゃない?

というよりは使いこなせるようになりたい!

Java Advent Calendar 2013 では時期が時期だけに Java 8 に関するエントリーがちらほらとみられます。

どのエントリーも非常に興味深いものばかりです。

それでは自分用のφ(..)メモメモ

おっと、まんま写経しても面白くないので解りやすく変更を加えてコーディングしました。

プログラムの解説はないので興味のあるかたはご自分でお調べくださいませ。

なお、プログラム中に出てくる人物やデータは実際の人物の正確なデータではありませんのであしからず。(なんのこっちゃ

実行結果は次のようになります。

<– MyFriends 全員表示 –>
柴田 恭平, 62歳, Gender: MALE, Breast Size: 90, Waist Size: 75, Hips Size: 80
小栗 旬, 30歳, Gender: MALE, Breast Size: 85, Waist Size: 68, Hips Size: 77
市原 隼人, 26歳, Gender: MALE, Breast Size: 88, Waist Size: 65, Hips Size: 76
壇 蜜, 33歳, Gender: FEMALE, Breast Size: 85, Waist Size: 60, Hips Size: 89
北川 景子, 27歳, Gender: FEMALE, Breast Size: 75, Waist Size: 54, Hips Size: 81
綾瀬 はるか, 28歳, Gender: FEMALE, Breast Size: 88, Waist Size: 61, Hips Size: 91
佐々木 希, 25歳, Gender: FEMALE, Breast Size: 80, Waist Size: 58, Hips Size: 82
剛力 彩芽, 21歳, Gender: FEMALE, Breast Size: 77, Waist Size: 58, Hips Size: 84
堀北 真希, 25歳, Gender: FEMALE, Breast Size: 78, Waist Size: 58, Hips Size: 83
武井 咲, 19歳, Gender: FEMALE, Breast Size: 76, Waist Size: 58, Hips Size: 82
深田 恭子, 31歳, Gender: FEMALE, Breast Size: 86, Waist Size: 62, Hips Size: 88
はるな 愛, 37歳, Gender: OKAMA, Breast Size: 90, Waist Size: 60, Hips Size: 89
マツコ・デラックス, 41歳, Gender: OKAMA, Breast Size: 150, Waist Size: 150, Hips Size: 150

<– 性別をキーにした Map を作りバストが 85 より大きい友達の人数を入れる –>
{FEMALE=2, MALE=2, OKAMA=2}

<– 性別をキーにした Map を作りバストが 85 より大きい友達の人数を入れる。(別パターン) –>
{MALE=2, FEMALE=2, OKAMA=2}

<– 性別が女性のバストの個数(ここでは友達の人数)、合計、最小値、平均値、最大値を取得。 –>
count: 8
sum: 645
min: 75
avarage: 80.625
max: 88

<– 女性だけをフィルタリングしてバストのサイズによって降順ソート。 –>
綾瀬 はるか: Breast: 88
深田 恭子: Breast: 86
壇 蜜: Breast: 85
佐々木 希: Breast: 80
堀北 真希: Breast: 78
剛力 彩芽: Breast: 77
武井 咲: Breast: 76
北川 景子: Breast: 75

<– 女性でバストが 80 より大きい友達だけをフィルタリングしてバストの値に 1000 を足して合計する。 –>
3259

<– 性別によってグルーピングして年齢の若い順に表示させる。 –>
MALE
市原 隼人 : 26
小栗 旬 : 30
柴田 恭平 : 62
FEMALE
武井 咲 : 19
剛力 彩芽 : 21
佐々木 希 : 25
堀北 真希 : 25
北川 景子 : 27
綾瀬 はるか : 28
深田 恭子 : 31
壇 蜜 : 33
OKAMA
はるな 愛 : 37
マツコ・デラックス : 41

<– 女性のバストの大きさでグルーピングして年齢の若い順に表示させる。 –>
< 貧乳 >
北川 景子 : 27 Breast: 75
< 巨乳>
綾瀬 はるか : 28 Breast: 88
深田 恭子 : 31 Breast: 86
< 乳 >
武井 咲 : 19 Breast: 76
剛力 彩芽 : 21 Breast: 77
佐々木 希 : 25 Breast: 80
堀北 真希 : 25 Breast: 78
壇 蜜 : 33 Breast: 85

<– 性別による平均年齢を計算。 –>
FEMALE : 26.125
MALE : 39.333333333333336
OKAMA : 39.0

<– 性別によるグルーピングをして人数の少ない順にソートする。 –>
OKAMA
MALE
FEMALE

<– 性別によるグルーピングをして人数の少ない順にソートする。人数も表示させる。 –>
OKAMA : 2
MALE : 3
FEMALE : 8

Hatena タグ:

JavaFX 3D 学習ついでに創った 3D ゲーム

JavaFX

このエントリーは、JavaFX Advent Calendar 2013, 10日目です。

昨日は @sk44 さんの JavaFX でページめくりアニメーション的ななにか でした。

明日は @kis さんです。

今日は私が最近グリグリしている JavaFX 3D について断片的ではありますがネット上で見つけることが困難なことについて書きたいと思います。

と言っても私は素人で本来このようなイベントで熱く語るようなスキルは持ち合わせていません。

よっておかしなことや間違ったことをしている可能性は極めて大きいのでコメントでご指摘いただけると幸いです。

そういうことで本来、3D の基礎であるカメラ、ライト、テクスチャ、モデルの移動、回転、スケーリング、そして SubScene といった必ず必要となることは割愛させていただきます。

基礎が知りたいと思われる方もいらっしゃると思います。

ここで耳寄りな情報を!

12 月 13 日に JavaFX 勉強会 & 忘年会 で @skrb さんが初心者にも分かりやすく 3D について解説される予定です。

都会に住まわれている方や、どうしても聞きたい方はこの機会に参加されてグリグリしましょう!(^_^)

残念ながら参加できない方は @skrb さんが 24 日の JavaFX Advent Calendar エントリーに 13 日の内容を紹介してくれる予定です。

 

このエントリーで紹介しているプログラムは JDK 8 Build b118 で創りました。

JDK のバージョンが上がると現在の仕様では動作しなくなるかもしれませんのでご容赦くださいませ。

なぜ 3D なのか? 今年の JavaOne でチェスボードの上を歩く Duke に感動して自分でも創れないかなと思いチャレンジしてきました。

 

その結果が次のようになりました。

 

JavaOne のようになめらかに綺麗に自由自在に動いているわけではありませんが目的は達成しました。Complete Success!! (^_^)

ごく一部の方に喜んでいただけたようなので、JavaFX Advent Calendar のエントリーに 3D ネタを持ってきたわけです。

現在ではネット上で Shape3D を利用したサンプルもけっこう出てます。

ご覧になられた方もけっこういらっしゃると思うのですが、それでは限界があります。

やっぱりモデリングツールで作ったモデルを読み込ませ動かしたい!

そこでこのエントリーではモデルの読み込みと位置情報の取得に焦点をあてていきます。

モデルの読み込みには 3DViewer ってのがあるそうですが動かないようです。(現在は不明です。

ちょっとググってみても使い方やサンプルもヒットしませんでした。(ググり方が甘いかも

そういう訳で私は Jim さんが作られた JFX3DModelImporters を使わせていただいてます。

// Thanks a million!
IntStream.rangeClosed(1, 1_000_000).forEach(i -> {
    System.out.println(“Thanks!”);
});

それではメタセコイアで作った Duke のモデルをインポートしてみます。

a1

 

 

obj ファイルをインポートしてます。

mtl ファイルやテクスチャファイルを忘れずにリソースディレクトリに obj ファイルと一緒にいれといてください。

他のファイル形式もサポートされているのがあるようですが試していないので誰か試してみてください。

読み込みだけだと問題はなさそうですがその後に一工夫いるようです。

MeshView[] にそれぞれのパーツが格納されてしまうのでそれを扱いやすくするために Group として管理します。

258 行目から 262 行目の処理です。

261 行目はドローモードをワイヤーフレームに変更するときにまとめて変更できるように苦肉の策としてついでにやってます。

さぁ、これであなたのキュートな 3D モデルをインポートすることが可能となりました!

私はモデルが管理しやすいようにモデルを複数に分けてインポートしました。

Duke、ボード、タイトル文字、GAMEOVER 文字、ブロックといった具合に。

このやり方が正しいかどうかは解りませんが一度にたくさんのモデルを含んだファイルをインポートしてしまうと管理不能になってしまいそうだから。

インポートしたモデルを解りやすく使いやすく Group として管理してしまえば楽です。

たとえばこの場面ではこの Group は表示させたくないなぁって思うときはこのように管理できるのでいいです。

 

 

これらのインポートしたモデルをノードとして扱えるようにしてしまえばあとは簡単です。

それぞれインポートしたモデルの位置情報さえ取得できればあとはお好きにグリグリ動かしてしまえばいいのです。

たとえば Duke の現在位置(Z 軸手前側の位置)を知るには次のようにすればいいようです。

 

 

Z 軸奥側の位置を知りたければ行末のメソッドを getMaxZ() にすれば OK です。

もちろん X 軸、Y 軸の位置情報も取得するためのメソッドが用意されてます。

同様にしてボードや他のモデルの位置情報を取得して、AnimationTimer や Timeline を使いちょっとした 3D ゲームのできあがりというわけです!

ここで注意が必要なのが getBoundsInParent()の他に getBoundsInLocal() メソッドと getLayoutBounds() があってこれらは現在位置を取得するためのものではないようです。

現在位置という表現をさっきから使っていますが動かして更新された位置というのが適切かもしれません。

ちょっと JavaDoc を見たのはいいけど、英語が難しくて翻訳ソフトに頼っても???でした。

1.transforms ObservableList
2.scaleX, scaleY
3.rotate
4.layoutX, layoutY
5.translateX, translateY

これら5項目に対応して位置情報を取得できるのは getBoundsInParent() メソッドだけのようです。

英語が問題ない方はすみませんがご自分でご確認くださいませ。m(_ _)m

 

 

このようにして初期位置から Z 軸マイナス方向(手前)に Duke を少しずつ移動させる [ dukeGroup.setTranslateZ(dukeGroup.getTranslateZ() -5); ] アニメーションを実行すると次のように出力されます。

getBoundsInParent(): -175.40234375
getBoundsInLocal():  -175.40234375
getLayoutBounds():   -175.40234375
getBoundsInParent(): -180.40234375
getBoundsInLocal():  -175.40234375
getLayoutBounds():   -175.40234375
getBoundsInParent(): -185.40234375
getBoundsInLocal():  -175.40234375
getLayoutBounds():   -175.40234375
getBoundsInParent(): -190.40234375
getBoundsInLocal():  -175.40234375
getLayoutBounds():   -175.40234375

使いどころを間違えると思わぬバグを仕込んでしまいます。

IDE のお気楽な補完技術に頼っているとやってしまいそうなミスですね。(経験者語る

さて、モデルをインポートして位置情報を把握することが可能となった今、モデルをあなたの意のままに制御可能になったわけです。

たとえば AnimationTimer の handle() メソッドを使って Duke を歩かせてみる。

 

 

このコードは X 軸、Z 軸の現在の位置にそれぞれ d_vx, d_vz 分だけ足した位置に移動させる。

次にボードの右または左に行き当たったら落ちないように反転させる処理はこうなる。(反転モーションは turn() メソッドで Timeline を使って別途処理させてます。)

 

 

このように位置情報さえ把握できてしまえばモデルの移動、回転、拡大、縮小などを AnimationTimer や Timeline を使って誰でも簡単にできます。

ここでちょっとした疑問がでてきます。

Group として扱ってきたのはいいけど個々の MeshView[] として扱うにはどうすればいいの? そうですよね!

Duke を歩かせるために手足のパーツをそれぞれ動かしたい!そこで MeshView[] として扱ってます。

 

 

MeshView[] が何か解らない場合は標準出力させて確認すればいいでしょう。

メタセコイアではモデルオブジェクトのパーツの順番通りになっているようです。

したがって、obj ファイルの順番通りになっていると思います。(あまり自信がない

歩行モーションはこれらを Timeline を使ってアニメーションさせています。

 

 

これで歩く Duke の歩行モーションは完成です。

あとは AnimationTimer で移動させれば OK です。

位置情報を取得できるのでお好きなように制御をすれば面白いことができるかもしれませんね!

あと MeshView[] として使っているのは音楽に合わせてスケーリングしている DUKEWALK という文字オブジェクトです。

やってることは単純だけどけっこうインパクトありますね。

 

 

JavaFX 3D API の基礎はなにも語らず断片的な内容となってしまいましたがいかがでしたでしょうか?

この学習用に作ったサンプルプログラムは下記アドレスからダウンロード可能となってます。

https://www.dropbox.com/sh/itmywi67zb5i3gq/zMn5vf5LPm

こちらはもともとカメラの学習用に移動、回転、拡大、縮小の制御がスライダーでできるようにしてあります。

カメラと言えばこのプログラムを組むときに悩んでいたカメラワークの答えを出してくれた方がいらっしゃいます。

下記サイトより答えをまるっといただきました。(日本語です!)

JavaFX 3Dを理解する

// Thanks a million!
IntStream.rangeClosed(1, 1_000_000).forEach(i -> {
    System.out.println(“Thanks!”);
});

さて、このプログラムのソースはおまじないをはじめ、ぐちゃぐちゃになってしまっているので隠蔽してます。( ̄。 ̄;)

と思ったけど心優しいプロの方もこのエントリーを見られていると思うので恥ずかしながら載せます。

優しく解りやすいアドバイスは大歓迎です!(^_^)

3DViewer が動き、ボーンの埋め込まれたモデルが自由自在になめらかに動かせる時代が来ればこんなことは必要なくなるかもしれませんね。

JavaOne の Duke がどのように作られたのか?

一般の開発者にも簡単にできることなのか?

いろいろ謎はあるけど待っているだけでは面白くないよね。

ちょっと古いけど 「いつやるの?」 「今でしょ!」

最後に一言

JavaFX 楽しい! (^_^)

Hatena タグ:

JavaFX で 3D ゲームを創ってみた。

JavaFX

生まれて初めてゲームを創ってみた。

JavaFX を今年の夏からかじりだして興味のあるところ優先で、あーでも無い、こうでも無いと悪戦苦闘しながらも

ぼちぼちと少しずつ学習してきた。

自分の無力さを棚に上げときながら twitter で泣きをいれると親切な JavaFX マン達が助けてくれた。

感謝感激です!

初期の頃のドタバタで JavaFX 大嫌いになっていたが今は好きになっている。

楽しい!(^_^)

最近調子ぶっこいて良く解らないのに 3D をグリグリしていた。

ある人が twitter で Duke のゲームをつくってみたいと呟いていた。

楽しみにしていたが待ちきれないし、ちょうど学習用素材のアプリにゲームを載っけちゃえってノリで創ってみた。

私はゲームは今まで一度も創ったことが無い!

しかも、ゲームは好きだけど上手くない!(>_<。)

不器用なので最近の凝ったシステムのゲームはほとんど途中でリタイアしてしまう。

バイオハザード5 だけはなんとかクリアできた。

とても疲れたのでその後のシリーズはパスしてます。( ̄。 ̄;)

そう言うことなので非常にシンプルで誰でも遊べるゲームにしました。

上の文章を翻訳すると「まともなゲームの作り方は解りません。」となります。(ヲヒ

なんだかんだで出来上がったのはこんな感じのものになりました。

UI がリッチな JavaFX のはずなのにちょっと残念なことになってますが学習用につくったものに付け足したから仕方ないってことで・・・(^_^;)

JavaFX (Java 8 Build b118) で創ってあるのでインストールされている勇者様は下記リンクにプログラムをダウンロードできるようにしてありますのでお楽しみくださいませ!

https://www.dropbox.com/sh/itmywi67zb5i3gq/zMn5vf5LPm

ソースは非常にぐちゃぐちゃになって酷くなってしまったので隠蔽してます。(;´Д`)

あっ、Duke の姿がちょっと変だとは言わないでね。

歩きやすいようにしっかりした足を付けてあげたんだ。

私ってなんて優しいんだろう(ヲヒ

Hatena タグ: