東京工業大学 ロボット技術研究会

東京工業大学の公認サークル「ロボット技術研究会」のブログです。 当サークルの日々の活動の様子を皆さんにお伝えしていきます。たくさんの人に気軽に読んでもらえると嬉しいです。
新歓特設ページ        ロボット技術研究会 HP        ロボット技術研究会 twitter公式アカウント

ゲーム

「ロボット技術研究会」通称「ロ技研」は、その名前の通りロボットの制作や研究はもとより、電子工作や機械工作、プログラミングなどの幅広い分野にわたるものつくり活動を行っています。

カテゴリ一覧: loading

JSでスライドを作るツールを作った話

おひさしぶりです、phi16です。
今回第9回rogyゼミで「もふもふ」というタイトルで発表させていただきました。内容はゲームなどに用いられる「morph」についてです。
資料は ここ にあります。Enterで進めます。本来は画像や動画などがかなり入っていたのですが抜いてあります。
その時に作ってしまったJSでプレゼンもどきを動かすプログラムについて、なかなか放置するにはもったいないので解説等を書いておこうと思った次第です。
JSのプログラムではあるんですけど関数型的知識をかなり利用しているので多少理解が難しいかもしれません。
そのプログラムは ここ にあります。これを用いて書いた、上のスライドの内部コードが これ です。

何故作ってしまったのか

今回の発表ではまさに「morph : 変形」についての話で、ゲーム・アニメなどでの変形表現やモーション、動きなどについて実例とともに解説しました。
実例を出す方法として、自由に「動き」を表現するにはさすがに既存プレゼンツールでは厳しいということと、だからといって自由にプログラムを書いていては大変すぎるということで、JSでEDSLのような形式で記述し、そのままブラウザ上で表示できるようなものがいいと考え実際に実装した次第です。
結果的にはスライド自体は良いものができたと思っていますが、内部EDSLの表記がかなり残念になっているので設計的には失敗だと感じていますが、後述。

基礎

0. Style

まず、私のJSの書き方について。
このコードには、いわゆる「クラス」が存在しません。全てただのObjectとして管理しています。
が、それは何でも入っているというわけではなく、(人間によるチェックとして)全て同じ「型」を持ちます。
元々JSは関数が第一級オブジェクトなのでオブジェクトにクロージャとして生やせば簡単にオブジェクト指向ができます。
全く問題がありません。privateもpublicも自由に作れます。pに予め別オブジェクトを入れておけば継承もできます。
残念なのはブラウザのデバッガで型が表示されないくらいです。thisの闇にとらわれるよりマシです。
オブジェクト指向の本質はカプセル化だと思っています。そういう意味でこういう二次元座標はオブジェクト指向に「向いていない」のだと思ったりもしますが別の話です。
要は、オブジェクトとクロージャを全力で使っていくということです。

1. Color

簡単な例として内部で使っているColor「オブジェクト」について見ていきます。
これは色と色を補間できるようになっています。最初に「コンストラクタ」としてt=0の色、次に「第二コンストラクタ」としてt=1の色を与えるとtを受け取ってCSS的色を返すファンクタ(C++用語)を得ます。
関数だけですがちゃんとそれっぽく動作するのです。クロージャは神。

2. Easing

スライドの最初の方で言っているEasingですが、もちろんスライド自体でも大量に使われています。
Easing「オブジェクト」として利用しているのは、Ease.easingの戻り値です。これはEasingに利用する関数を渡すとそれに沿って動かしてくれるようなものです。
最初にtを渡すのはアニメーション部分との整合性のためです。
valはそのまま[0,1]の値、ファンクタとして呼び出すと線形補間を行います。
メンバのquadはEase-in Quadな補間関数です。これはEasingオブジェクトではありません。
reflect()は「その後に続く命令をIn-OutのInとして解釈」するEasingオブジェクトを返します。
最終行はEase-inOut Quintの[1,2]補間なので1.5というわけです。

設計としては、元々のEase-inな基本関数群を固定してEasingを加工したいという目的の為に、reflectやmirror、invなどの「新しいEasingオブジェクトを返すメンバ」を持たせて自由に関数を組み合わせられるようになっています。
特にIn-OutっていうのはInとInの180度回転をくっつけたものに他ならないので。わざわざ用意するよりも組み合わせとして書けるようにするあたり関数型思想っぽいですかね。
実装ですが、これは単純には実現できるものではありません。quintに渡す値はメンバ関数で好きにいじれるのですが、その結果はいじることができないので「片方を[0.0.5]にする」みたいなことがやりにくいです。つまりquintそのものを線形補間オブジェクトにする前にどうにかしてやる必要があります。
そこで内部的には「継続」を保持しています。分かる人ならもうわかるかもですが。
Ease.easingの第二引数として継続を取り、quintの結果は勝手に継続を通します。Lensにつながるものを感じる。
結果的にEasingオブジェクトのメンバ関数内で「基本関数を通す前」と「基本関数を通した後」に好きに関数を与えられるのでreflectも実装が簡単にできるというわけです。

また、連続的複数Easingのために、indexという関数を持っています。これは位置、全体量、1つに用いる幅を指定することで位置をずらした時にEasingもずれる便利なやつです。
これによって最初の「もふもふ → morph」やEasing一覧などのアニメーションが簡単に描けます。こういうコンビネータ的発想よい。

実装読んでわかるタイプの人はそのほうが速いですね。どうだかわかんないですけど。
関数型やるとわかるようになる気がします。

3. Graphics-1

ふつう、描画するときに座標を指定すると思うのです。
ですが、基本的にこのコードは描画時に座標の直指定を行いません。
その代わりに、「平行移動命令」が別で用意されています。その中で描画すると平行移動された状態になるのです。
同様に「回転命令」「拡大縮小命令」が用意されています。circleの半径は本質的には不要なのですが一応ある。
この方式の便利なところは、「全ての位置が相対的に表示される」ということです。何らかの絵を描く命令組み合わせを頑張って作ったとして、それをちょっとでも移動などしようと思ったら全ての命令の全ての座標を書き換えるしかありません。
この相対方式であれば、外側をg.translateで囲むだけです。
これによってプレゼンツールに「いつでも好きな場所のサムネを表示できる」みたいな機能を一瞬で実装できました。

ちなみに描画は全部HTML5 Canvasで出来ています。video要素を簡単に取り込めるのすごい楽だった。
g.translateはsave → translate → restoreするだけだし。かんたん。

4. Graphics-2

もう一つ面白い特徴として、「全ての描画部品は統一」されています。具体的には
を等しく持ちます。
これによってオブジェクトの色からの分離ができ、構築に時間が掛かるポリゴンデータなどを適切にキャッシュすることが容易になります。
clipではそのオブジェクトの形状でクリッピングを行い、外に描画しないようにできます。これもサムネ機能で使われています。
要は全部書き方がおなじなのです。

特に文字描画についてもそうで、普通はfill(brown)とするところ、stroke(1)(brown)とやれば幅1の線で枠がでます。
ちなみに文字描画はg.text("ぽよ").left.fill(brown)みたいな書き方をします。
原点の指定方法が9種類用意されていて、位置指定に役立つのです。個人的に便利。

なおHTML5 Canvasには文字をPathにする方法が存在しません。なのでopentype.jsでPathを取得して自分で曲線を書いています。
この時最大最小を計算できるのでleftUp~rightDownを適切にoffset付きで計算できるわけです。

アニメーション

1. 設計思想

まず、スライドの状態はfloat1個。
アニメーションを1つ増やすとその状態が1増える。その増え方はアニメーションにかかる時間に依存。
EDSLとしてはアニメーションのタイミングと描画を綺麗に共存できるのが目標。

2. 書き方

pがアニメーション全体の管理を行っているオブジェクトです。
p.in(duration,function(t){f})で、その場所に1イベントを発生させます。
p.inOut(d1,d2,function(t){f})で、その場所と、内部のfが完了した時点に1イベントずつ発生させます。
tは今いくら経ったのかを表すEasingオブジェクトです。durationはアニメーションする時間。
p.inOutのときは0 → 1 → 0のようにtが変化します。
p.outはただ単にtが[1,0]になるだけです。
p.inをネストさせることで連鎖的なアニメーションを書くことができます。
任意のタイミングでp.draw(f)を行ってGraphics系関数を呼ぶようにできます。

3. 内部処理

この書き方自体は非常に直感的だと思っています。ネストさえどうにかなれば。
が、直感的であるということはコンピュータにとって辛いということです。実際このままで目的機能を果たせるとは思えないですよね?
内部では結構面白い処理を行っています。具体的には関数を事前実行してイベントを全部調べるようになっています。

アニメーションに用いるpというオブジェクトは、実はRenderのコンストラクタの引数の関数の引数です。
つまり、本来はここに管理オブジェクトのpがくるはずだけど、そうでないpを入れることもできるということです。Visitorパターンに近いものです。
そして、前処理として、pに「イベント検出オブジェクト」を渡します。これはクロージャになっていて、p.in(d,f)が呼ばれるたびに内部のリストに必要アニメーション時間を記録していきます。
ついでにイベント数カウントも増やしたり、引数として与えるべきEasingオブジェクトの開始時間を記録します。
gはnullだけどp.draw内でしか呼べないようになっているのでだいじょうぶ。
そうすると全てのイベントのタイミングを把握できます。あとはこれに沿って唯一の状態floatを動かしていけばもはやdurationを無視しても良いのです。
こういう「コードの再解釈を行う」という意味でEDSLになっているのです。

実際に描画する際には前処理で検出したイベントタイムラインを平行して追跡して、
「inの引数関数の引数として渡すべきEasingオブジェクト」を追跡によって得られた「Easingオブジェクトの開始時間」にもとづいて計算し与えることで目的の動作を得ることができます。

ちなみに前処理のときにvideoやimageのロードも行うようになっています。通常実行の際は保存しといたDOMを読みだして操作できます。
あとinOutがなければ多分Easingオブジェクトの開始時間を保持する必要はなかったですね。本来はinOutをもっと使うと考えていたので作ったのですが結局全くつかってないです。後述。

4. 状態管理

このプレゼンツール、左/右キーで前と先に移動ができます。が、最初は右に移動できないです。
内部はブラウザの遷移と同じようにhistoryとfutureを記録してあって、進んだことでhistoryが増え、過去に戻れるようになっています。
またそれらは時間がかかるイベントですが、複数回要求があっても全てキューに保持してあるので適切に動作させることができます。
ちなみにキューに要素があるとイベントの速度が0.1秒になるので遷移が速くなります。戻るだけなのに毎回アニメーションついたら邪魔ですし。
その辺はsetTimeoutでいい感じに実装しました。やるだけなんだけど実装量が重いタイプ。

ちなみにこうなっている元の理由は状態をfloat1個じゃなくて分岐もできるようにしようと思っていたからで、過去に戻った状態でEnterですすめると未来が消えます。

その他

p.global

普通のゲームとかでもなんですが、位置を1px単位で調節したいというニーズはかなりあります。
実際スライド書いていて0.142とか0.045とかのいい感じの値を求めるのが大変でした。
そこで、「毎フレーム処理の評価をしなおしている」「ブラウザには便利なデバッグツールがついてる」ことから、デバッグツール内で変数書き換えできればいいなとおもいまして。
書き方は、決めたい定数値の部分にp.global(name,value)って書くだけです。
そうするとvalueを初期値としてnameの名前でObjectに登録されて、ブラウザからはrender.global(name)でアクセスできます。
実装は自明。

でも結局手で書きなおしたほうが慣れてるあたり速かったりしました。

p.configure

Canvasはデフォルトでは左上(0,0)で右下が(w,h)です。でもアニメーションとかするには中心が(0,0)、単位は1なのがありがたいです。
というわけで、それを常に(-r/2,-0.5)から(r/2,0.5)にしたかったのです。でもデフォルトにするには微妙なので自分で書いたほうがいい気がするのですね。
でもg.translateやg.scaleはp.draw内でしか許されていません。なのでアニメーションを描くたびに書きなおすことになります。つらい。
ということでつくったのがp.configureという機能で、
と書くことで、なんとそれ以降の描画実行がsave()の場所で行われるようになります。まぁまさしく求めていたものなのですが。見た目すごい綺麗じゃないですか。
限定継続っぽさを感じるけどちょっと違うのかな。まぁ。

実装には必見の価値があります。うん。

タイムラインの闇関数

下のバーにでてる円の位置を計算してくれる関数です。
クリックした場所を検出するために逆関数をつくるはめになりました :
もっと綺麗ななにかがあった気がしなくもないです・・・

失敗

タイムラインと描画を混ぜるコンセプトはいいとおもうんですけど実現方法が間違っていた気しかしないです。
inOutを使いたいシチュエーションはいっぱいあったけど諸々の制限で使えなかったり。
ネストを防ぐためにわざわざp.preserve.inというイベントを発生させない機能を追加したり。
これについては「スライド1枚」という単位を状態に入れておくべきだったかなといまは考えていますが。

ちなみに私的には「ネストは全く問題ない」派なのですが、今回のイベント管理は本質的にネストするべきではない記述なのでどうにかするべきだったという印象です。
問題は変数のスコープなんですよね。ただこの辺は考えてもあまり解決しないような気がしなくもないです。

あとこれは関係ない話なのですが、自分は完全に理解しているんですけど動作原理を書くのがすごく難しいですね。
関数の引数の関数の引数の関数の引数みたいなことをたまにやるのですけどちょっといろいろと厳しいものを感じます。
でもきっと関数とかクロージャと戯れていれば理解できるとおもうので がんばってください(丸投げ)。

まとめ

HTML5 Canvasを用いてアニメーションが書き放題なプレゼンツールを製作しました。ブラウザ上でものを作るのはデバッガツールが完璧に揃ってるのですごいやりやすいです。
設計的にはEasingやGraphicsなどの最終形にはかなり満足していて、その辺りの知見を得ることができました。
アニメーション管理についてはまだまだ至らない点もありますが、JS上でEDSLのような形式で諸々描けるという点は結構おもしろいとおもっています。
またコード内でクロージャを「乱用」している感じもありますが、むしろこういうのは積極的に使っていいと思っているので、もっと広まっていってほしいと考えています。

あと線形は、ダメです。

ゲーム製作者交流会GAME^3を開催しました

こんにちは、14のまーぼう(@mabo_207)です。
今回は9月13日に東工大で行ったイベント「GAME^3(げーむきゅーぶ)」についての記事です。 今回は2回目の開催となりましたが、1回目と内容は同じなのでどんなイベントなのかはこちらをご覧下さい。
 
今回は大岡山キャンパスの南2号館のS223を用いて開催しました。今回は、60人程の方が来場していて、総展示ゲームブース数が24。皆さん楽しくゲームを遊びつつも議論も活発に行われていました。


当日の様子2
↑当日の会場の様子です。

今回も多くのサークルに参加していただきました。
東京工業大学 アマチュア無線研究会
東京工業大学 traP
首都大学東京 AR会
東京工科大学 Creative Staff
神奈川大学 GameCreatorsCircle
千葉大学 電子計算機研究会
早稲田大学 早稲田コンピュータエンタテインメント
法政大学 計算技術研究会
敬称を省略しましたが、上記の団体さんにゲーム展示をしていただきました。
これらの大学の方以外にも様々な人が展示を見に来ていました。参加してくださった人、運営を手伝ってくださった人達に感謝です。

運営側として反省・改善すべき点はありましたが、多くの方に満足してもらったようでよかったです。アンケート等も参考にして、今後の運営に役立てたいと思います。また開催する時はよろしくお願いします。

WebGLとnode-webkitでminecraftを作る

13の抹茶です.

抹茶おいしい抹茶!


明日は新歓展示ですね!!!!!
新歓ページ
ぜひ来てください!!!!!!!


それはさておき、だいぶ前ですが、2/22のGAME^3というロ技研主催のゲーム製作者の交流イベントに参加しました.

GAME^3については、以下を参照.
ゲーム製作者交流会「GAME^3」レポート

WebGLとnode-webkitで作ってるminecraft的なものの作りかけを展示しました.

明日の新歓展示にも出します.

すらいど


ゲームとしては機能的にまだまだなのですが、WebGLというもの、node-webkitというものの技術紹介になればいいなーと思います.

GAME^3でも展示していて、初めて知ったという方が多くいらっしゃいました.

今の時代、いろんな技術が次々生えてくるので、全てに注目するのは大変ですよね.

ロ技研では、様々な分野に関心をもって活動している人がたくさんいます.

ロ技研には、新しい知識や技術を共有できる環境があると思います.


それはさておき、私はminecraftというゲームが好きです.
さくらVPSを借りてサーバー建てるぐらい好きです.
サークルの人達とマルチプレイできる、これもまたサークルのいいところですね.

おしまい

GAME^3参加記(ゲーム製作進捗報告)

こんにちは。やむどぅさん(@ymduu)です。
ゲームの話ではなかった前回とは異なりゲームの話です。ロボット技術研究会ではロボットだけでなくゲームも作れる(ステマ)
去る2/22にGAME^3なるイベントが開催され、僕もそこに横スクロールアクションゲーム「Tech World」を展示してきました。
同じジャンルである横スクロールアクションゲームも多く参考になった他、音楽ゲーム(SP五段には難しかった)もあってめっちゃ良いイベントでした。
開催したまーぼうとりむこに圧倒的感謝。
では進捗報告です。
・ゲーム紹介
banban
Tech Worldはテックちゃん(主人公)を操作して敵を倒しつつゴールを目指し、時にはボスと勝負といった感じの横スクロールアクションゲームです。世間は厳しいので左上に存在するライフゲージがなくなると死です。
・敵
and-kun
かわいい。僕がANDゲートを見て生み出したラクガキに基づいてアカテツくん(@aktzk)が描いてくれました。感謝。刺さると体力が1減少します。
・電池
item1
「電池」で適当に画像検索して出てきた画像とにらめっこしながら自分でドット打ちました。かわいい。取ると体力が1回復します。
・進捗
左右移動にジャンプ、弾を発射して敵を倒し、敵に当たったらダメージを受け、電池で回復できる、といったゲームとして必要最低限のことができるようになったところです。基本機能実装フェーズは終了といった感じ。
・展望
ゲームとして必要最低限のことができるようになったといっても、敵は1種類しか居ない、ボス戦はない、マップは通れない壁だけと非常に質素なゲームになっているので、今後は
・ボスの実装
・マップギミックの実装(通り抜け床とか水とか)
・敵の種類を増やす
の三点を詰めて「面白いゲーム」を目指して行きたいと思っています。
新歓展示までにはボス戦を一つ実装したいですね。

・おしまい
ロボットだけでなくゲームも作れるロボット技術研究会に興味が湧いたら部室に来たりするといいです。
先輩とかが居て何を使ってどんなものを作ったとか説明してくれるはずです。
ちなみに僕が使っているのはVS2013でC++を書いており、画像の描画はDxlibにおまかせです。

お疲れ様でした。

ゲーム製作者交流会「GAME^3」レポート

こんにちは、14年度入学のりむこ(@Rimko_san)です。

2/22(日)にゲーム製作者交流会「GAME^3」が開催されました。
今回はその様子をお伝えします。

長くなりそうなので概要をお伝えしますと、
総来場者数はおよそ70名ほど、展示ゲームブース数はおよそ38
活発な議論ができ、初開催にして非常に濃いイベントとなりました!


 BOKASHI
当日の会場の様子(かなりぼかしを入れています)。 
イベントの目的は「ゲームの展示と製作者同士の交流」で、3つのタームに分かれて発表時間を分けてゲームを展示します。
ゲームを見る側は「こんなゲームもあるのか」「これどうやって動かしてるんですか?」など、製作者との対談ができ
展示する側はプレイした人からすぐに感想・フィードバックがもらえ、今後の開発に活かせる!
BOKASHI2
まーぼう君の影の活躍により、実に38ものゲームの展示にこぎつけることができました。
団体からの参加としては私たち東京工業大学 ロボット技術研究会の他に
東京工業大学 アマチュア無線研究会
慶應義塾大学 GAPCOM
千葉大学 電子計算機研究会(CCS)
千葉大学 トドノアツマリ
東京工科大学 クリエイティブスタッフ

敬称略させていただきましたが、上記の団体さんに参加していただけました!
社会人の方によるサークルや個人参加もたくさんしていただけて、とても楽しかったです。
 
さて、当日のアンケートで人気だった ゲームを数点紹介させていただきます。

人気投票3位は、社会人サークル「TeamDRC2nd」KAGEさんによる「重力の国のアリス」
雑誌にも掲載されたという傑作パズルゲームで、素晴らしい完成度でした。

 人気投票は1位タイ、14票
東京工科大学 クリエイティブスタッフマドラムさんによる
「双狗」 
迫力満点の3Dアクションゲーム、難しいチーム製作での参加でした。
東京工業大学 ロボット技術研究会Lineaさんによる「ARMED CORE」 
こちらも3Dアクションゲーム、素晴らしい再現度と作りこまれた3DCGでした。

他にも
東京工科大学 クリエイティブスタッフの南都海輝さんによるアクション「海鼠戦士ゼーグルケ」 
東京工業大学 yuinoreさんによる音ゲー「Heart Beats」 
東京工業大学ロボット技術研究会 塩谷凛さんによるパズルアクション「Gimick」
東京工業大学アマチュア無線研究部 紅蓮さんによるRPG「女神と迷宮」
などが注目を集めました。

アンケートによるイベントの満足度も非常に高く、色々な点を改良しつつまた開催できたら良いなと思っています。
次回もより多くの参加者を集めて、みなさんでイベントを盛り上げていけたらと思いますのでよろしくお願いします。

Twitterアカウント:@GAME3_Staff
ギャラリー
  • ABUロボコン結果報告
  • スマホから部屋の電気をつけてみた
  • MakerFaireTokyo2017に出展します
  • MakerFaireTokyo2017に出展します
  • MakerFaireTokyo2017に出展します
  • MakerFaireTokyo2017に出展します
  • MakerFaireTokyo2017に出展します
  • MakerFaireTokyo2017に出展します
  • たのしいロボット帝国 製作物紹介
記事検索
最新コメント