2014年12月28日日曜日

マッハこうもりのプレイ動画を公開しました

今日はゲーム制作やプログラミングではありませんが、ちょっと書きます。


 


あの YouTube についに私も動画をあげることができました!


まー、そんなの小学生でもやってるよと言われたらそうなのかもしれませんが、


YouTube なんて今までは


・検索して再生


・お気に入りにいれて


・繰り返し見たかったら URL に repeat いれて


といった初心者スキルしかありませんでした。


そんな私が、自分のチャンネルを作成して、動画を投稿することができました。


なんかちょっと大人になった気がします。


 


最初に大変だったのが撮影です。


ウェブカメラはノートPCの画面の上のほうについているものがあるのですが、それだと3DSの画面をうまく撮影しながらゲームをやるのがとても大変でした。


そこで、デジカメで動画撮影を試みたのですが、ぴんぼけしまくりで、文字はおろかスプライトもなんかぼんやりとした塊にしか映りませんでした。


ぐぐってみると、半田ごてなどを使って電子工作をすれば3DSの映像を外部出力できるようなのですが、リスクもあるしお金もかかるしそこまでやる情熱がわかなかったので却下しました。


あれやこれやとやって、結局デジカメでオートフォーカスを何度も試してちょうどよいところで固定するやり方で撮影しました。


ズームをちょっとずつずらして、半押しでオートフォーカスをしていくとたまに文字も読めるくらいのピントの合わさり具合になったので、それで固定して撮影。


まわりのものが映りこまないように暗くしてカメラにぶつからないように気をつけながらプレイして動画を撮影しました。


 


その後、 YouTube にアップするときに現れたのがアカウントの壁です。


なんか実名とか出たらやだなーとか思いながら、アカウントを設定してチャンネルを作成しました。


ぽちっとボタンひとつで世界に発信するようなものは、誰も見てねーよと思っていてもびくびくしてしまいます。


心の準備なども含めてこれでたっぷり2時間使いました。


そして、アップロード。


タイトルや説明文やタグを書いて公開。


 



[プチコン3号][petitcom]自作ゲーム マッハこうもり(MachBat1) - YouTube


 


最初はサムネイルをシステムから提案された3つから選ぶしかできないようです。


そこらへんは信頼と実績に応じてカスタムが使えるようになるらしいです。


そんないっぱい投稿することはないと思いますが、何か作品ができたらこうやって気軽に公開できるというのはよいことだと思います。


 


 


2014年12月27日土曜日

プチコンでミニゲーム Mach Bat マッハこうもりを公開

お久しぶりです。以前の日記から3ヶ月近くたちました。


 


タイトルに書いたように、プチコンミニゲームを作りました。


タイトルはマッハこうもりです。


ジャンルは強制横スクロール壁よけゲームというありきたりなものですが


テストでやってみると意外と難しく「あっー」と声が漏れることもありました。


 


そもそもプチコンてなんだよという人はぐぐればたくさんでてくるので、拙い自分の説明よりもそちらを参考にしてください。


ベーマガを読んでいた人ならばなつかしい気持ちになれるかもしれません。


私もBASICを下手の横好きでやっていました。


私の技量では、AAを動かしたり、ドット絵を時間をかけて表示したり、グラフィック命令で絵を描くのが関の山でした。音楽は楽譜どおりに打っても、オマージュにも程遠い原型をとどめない不協和音になる始末でした。


 


ところが、プチコンBASICはそんな私でも簡単にこんなゲームが作れてしまいます。


f:id:SakuraCrowd:20141226193039p:plain


f:id:SakuraCrowd:20141226195006p:plain


とはいっても、Mk2 のころからちまちま勉強したりしていたので、一朝一夕といったら嘘になります。


しかし、思いついて試作をかねて作り始めたのが昨日で、今日はテストプレイがメインだったので、これを具体的に作るために要した時間は6時間くらいだと思います。


 


プチコンの良いところは、なんといっても3DSやDSという実際のゲーム機で自分が思ったゲームを作って公開してプレイできることだと思います。


プリセットのリソースを使うことで絵心がない私でも簡単にキャラクターを表示して動かすことができます。


音楽もたくさん入っているので、BGMPLAY にBGMの番号を設定するだけですぐに再生されます。


 


えらそうに思いつきをいうと、私はゲームは総合力だと思います。


インターフェースだけでも、プログラムだけでも、絵だけでも、音楽だけでも、シナリオだけでもだめで、うまくバランスがとれたときに魅力が出てくると思っています。


そのためのさまざまなリソースがすでに入っていて、すぐに試すことができることもプチコンのいいところだと思います。


別にプチコンのほうから金銭を得ているわけではないのですが、そう思います。


不満としては、以前できたQRコードが廃止されて、サーバ頼みになってしまったことと、あいかわらずのエディットのしづらさですが、自分の思いつきをコードにして、それがさくさくと形になっていく快感はプチコンならではだと思います。


あと、ハングアップも最初はショックです。要するに昔から言われているセーブはこまめにしろということです。


 


上のプレイ画像のようなマップもプチコンに最初から入っている SBMAP によって4層構造のマップが簡単に編集できます。


まだSBMAP にはバグがあるようですが、修正予定のようです。


 


プチコンの手先のようなブログになってしまいましたが、もし気が向いたらダウンロードして、やってみてほしいと思います。


KEY は VK38YJAY です。


フォルダの中の MACH_BAT1 プログラムを実行するとプレイできます。


初めての公開なので無事にいけたか心配ですが、暖かく見守ってください。


 


Miiverse にもなんとか投稿し、プチコン3号のまとめwiki にも投稿しました。


マッハこうもり - プチコン3号まとめWiki


wiki とか共用のものは編集する際に緊張しました。


いろんな作品があって、もっと自分もいろんなゲームを作ろうと思いました。


2014年9月9日火曜日

ccui の GUI は便利!だけど資料が少ない

前回は、cc.Menu を使った手抜きボタンを作成しました。


ccui は TextField を一度使ったのですが、 cc.EditBox のほうが便利だし、 ccui は検索しても資料が少ないから便利そうだけどしばらくは保留だな('∀`)と思っていました。


ところが(・`ω・´)!


ccui はすごく便利なライブラリでした。


私が便利だな~(´∀`)と思ったベスト3を発表します。


(1) Widget


入れ物として優秀。さまざまな部品を組み合わせてひとつの GUI としてまとめるのに便利です。


内部でサイズを設定するときに _updateContentSizeWithTextureSize という関数を使っていることにちょっと違和感があるのと、 getSize という getContentSize との違いが微妙なインターフェースがあることがちょっと不満ですが、 GUI を作るときはこれをベースにするとよさそうです。


(2) Button


画像と文字列を組み合わせたボタンを簡単に作れる。「あれ?前回のは?」と思っても口に出さないのが優しさだよね(´・ω・`)


イベントの設定も addTouchEventListener でさくさくです。


サイズの変更を setSize ではなく setContentSize でやるとうまく動かなくなることがありましたが、それ以外はさくさくです。


(3) ListView


Widget をぽんぽんと放り込むといい感じにクリッピングしてスクロールできるリストを表示してくれる素敵なウィジェットです。


なんか、アイテムの選択イベントも送ってくれるらしいのですがつかってません。


 


逆に数時間を使っても何これだめじゃんヽ(`Д´)ノとなった要注意 GUI はこんなかんじです。


(1)ScrollView


なんか TMXTiledLayer とスプライトの上で配置したりすると、クリッピング表示がだめだめになる。


そのうち ScrollView はクリッピングしないのかなとか混乱しだして、 ClippingNode と組み合わせるも、表示が意味不明になってしまう。


その後 cc.ScrollView でコンテンツくわせてサイズ設定したら、クリッピングも完璧にやってくれたので、 ccui よりも cc のほうが良い GUI もあるんだね(´・ω・`)と思いました。ブランドがいいからってその商品がなんでもいいわけじゃないのと同じだよね。そういうことだね。


(2)TextField


冒頭でも書いたとおり、 cc.EditBox のほうがお手軽で思ったとおりなことをさくっとできるので、あまりいじり倒す前に飽きました。


(3)Text(Label)


とりあえず ccui のほうがすごいから、 ccui のラベルつかおーぜーと思ってたら、 TextField などと同じだったパターンです。色の設定のインターフェースが見つからない。cc.LabelTTF なら簡単に設定できる。じゃー、 cc のほうでいいねという感じ。


作業の報告


とにかく ccui も使うことで、さくさくと GUI が作れるようになってきて、 MazeChat の UI まわりがだいぶ素敵になりました。


仮想スライドパッドとチャットウィジェットは自作の GUI でちょっと自信作なのです(*´σー`)エヘヘ


もっと整理できたら gist とかに載せようかなと思いつつ、冒頭の思いつきで書き始めた ccui ランキングで疲れたので、今回はここらへんにしようと思います。


あと、NPCとの対話もできるようになりました!選択肢による分岐もできて自分で作った会話パターンで会話してにやりとしてしまったときは、俺ってさびしがりなんだなって思ったよ(´・ω・`)ノシ<マタノー


f:id:SakuraCrowd:20140908195234p:plain 


素材はフリー素材のぴぽや倉庫さんの画像と魔王魂さんの音楽を使っています。フレームワークは cocos2d-js 3.0 rc1 を使っています。


 


2014年9月2日火曜日

cocos2d-js 3.0 rc1 で MenuItemSprite と LabelTTF を組み合わせた簡易ボタンの作成

簡易ボタンの作成関数を作った

cocos2d-js ではボタンを作る際に Menu と MenuItem を使うことがあります。


他にボタンのクラスもありますが、イベント処理の設定など MenuItem のほうが使い勝手が良いように思います。


 


MenuItemImage でボタン用の画像を読み込んで作っていたのですが、いちいちボタンの文字を画像として入力するのはとても面倒でした。


例えば、同じ背景なのに「ヘルプ」と「閉じる」という名前の違いだけで画像を2種類も作らないといけないのは手間がかかります。


 


そこで、背景画像の上にラベルを重ねたボタンを作りました。


f:id:SakuraCrowd:20140901195726p:plain


絵心があまりありませんが、がんばって茶色いボタンの背景画像を書きました。


茶色いボタンの背景として通常(normal), 押下(selected),非活性(disabled)で用意します。


背景画像には「閉じる」のような文字列は書かれていません。


文字列はボタン作成関数で指定します。


サイズも実行時に指定できるので、ひとつベースの背景画像があればいろいろなサイズでいろいろなテキストを付加して利用できます。



gist222c8099d1427be0b905


 


その他の近況

NPC の会話処理は、ある範囲に入ったらプレイヤーが会話を選択できるようにする処理を作りました。


ごちゃごちゃしてきたのでシーケンス図にまとめたいと思っています。


今は会話そのものを表現するための GUI 部品を cocos2d のクラスを継承して作っています。


今日紹介した関数もその一環で作りました。


 


TMX のタイルの隙間に関する対策はまだできていません。


サンプルでは正しく表示されている tmx でも、自分のプログラムに移すと隙間ができてしまうので、プログラムの問題なのですが、位置やサイズを整数にしたりプロジェクションの設定を2Dにしただけではうまくいかず、こちらは気長に少しずつ調べようと思います。


 


2014年8月30日土曜日

TMX のタイルの隙間対策、連続移動のかくつきの対策

TMXTiledMap のタイル間の隙間については setProjection で 3D を 2D に変更するらしい。


ver2.2.2 のとは


cc.Director.getInstance().setProjection(cc.DIRECTOR_PROJECTION_2D);


だったが、 ver3.0 では


cc.director.setProjection(cc.Director.PROJECTION_2D);


とする。関数が API リファレンスに見当たらず core/CCDirector.js を見てやってみた。


それでもまだ隙間があるが、対策前よりは隙間が少なくなった。


他の原因で隙間がまだ残っているようだ。 TMXTiledMap の位置を小数値から整数値にすることもネットに書いてあったので試したが、他の原因があるようでまだ隙間が残っている。


これについては保留する。この切り替えができるようになったのが最近の進歩だと思う。


 


連続移動のときにキャラクターが前後にかくつくことと、それにともない追跡してスクロールする画面が前後にぶれる対策を行った。


原因は sprite を MoveTo アクションで移動させるときに、さらに移動が発生した場合に、以前の MoveTo アクションを停止しないで新しい MoveTo アクションを行ったためだった。


そこで、以前のアクションを覚えておき、それを停止する処理を追加した。


また、アクション完了後に位置を設定するため scheduler で設定したカリー化した関数オブジェクトもアクションと同じように覚えておき、新しい移動をする前にすぐに実行するようにした。


移動がスムーズにできるようになってきもちいい(*´ω`*)


 


2014年8月29日金曜日

MazeChat 開発中

jsonId から1ヶ月たちました。


このままフェードアウトしそうなので、今月のうちに近況報告をしようと思います。


 


少しずつですが jsonId を作るきっかけになったゲーム制作を続行していました。


今はやりのタブレットなどにも対応しているフレームワーク cocos2d を勉強しながら作っています。


 


jsonId に関して思い出すと、


以前に言われたことのある「実現したいことは何か?」という言葉を思い出します。


手段が目的になり、よもや手段以上のあいまいな機能を作ろうとして座礁する。


それを繰り返さないために、実際に使うのかを常に考え、もっと簡単に実現できないかということを複雑になりはじめたら自問するようにしました。


それでも、すごいモジュール思いついたwwwという甘い妄想に飲み込まれそうになることが今までどおりありましたが、それでも1日進まなかったら他の手段を考えるようにすることにしました。


 


そもそも jsonId は TMX というタイルマップで、オブジェクトを参照するための拡張機能として作りました。


しかし、そもそもそこまでする必要はないということに気づき jsonId はあまりブラッシュアップしないまま アルファ版のままで終わりそうです。


 


今は、そもそも作りたいと思っていた登録なしで気軽にアクセスできるRPGのような仮想世界を作っています。


f:id:SakuraCrowd:20140828194119p:plain


キャラクターとマップチップの画像はフリー素材を公開してくださっている「ぴぽや」さんの画像を使っています。


フレームワークは cocos2d-js 3.0 rc1 です。


プレイヤーキャラクターの移動、それに伴うスクロール、マップ切り替えができています。


画像だけではわかりませんが、音楽もマップごとに再生されます。


音楽はフリー素材を公開してくださっている「魔王魂」さんの BGM を使っています。


フリー素材のおかげで、絵も音楽もさっぱりな私でもなんとかここまで形にすることができました。感謝です。


 


あまり、がちゃがちゃと機能をつけず、シンプルでとっつきやすいインターフェースを心がけようと思います。


チャットをしない人でも仮想世界をぶらついて楽しめるようなゲーム性をもっと出そうとは思います。


とりあえずは、移動のかくつきの解消、マップのちらつきの解消、NPCの会話処理の実装をしたいと思っています。


それができたら、 ver0.1 としてリリースしてみたいです。


今はいろいろな人がゲームを作って発表していますが、ゲームとしての体裁を整えるというのも大変だなぁと思います。


あまり変なこだわりで暴走しないで、肩の力を抜きながらしっかりと作りたいです。


2014年7月16日水曜日

JSON のオブジェクトを ID でリンクする(5)

JSON のオブジェクトを ID でリンクする(4) - SakuraCrowd’s blog の続きです。


jsonId を利用しようとしていた仕様が変わってしまい、必要なくなったのでいったん保留します。


とはいっても、 {"$ref":"id1"} などの ID から、その ID を持つオブジェクトの参照への変換、逆変換の簡単なテストをクリアする実装もできたので、記念として gist にしました。長いので最後にはっときます。


 


jsonId の実装について


gist のコメントに書いてありますが、循環参照は jsonId の置換では問題にならないのでエラー検出はしないことにしました。


JSONPath でルートの "$" のときに jsonPath.eval の第一引数を対象にしたかったのですが、空の配列が返されてしまっていたので、その部分だけ条件文で特別に処理しました。


"$[0]" などはルート配列の1番目の要素の参照を取得できるので、 jsonPath.eval(...)[0]を使っています。


反省点


jsonId を使わない仕様をなぜ最初に気づけなかったか。


それは、なるべく作成する機能に汎用性を持たせたいという悪いくせがでたためだと思います。


tmx のプロパティの編集がやりづらいので、他の json ファイルに細かい設定を書いてそれを参照させようというのがきっかけでした。


しかし、実際に自分が必要とする設定は tmx のプロパティに CSV などで4つくらいのパラメータを書くだけですむものでした。


それがなぜか、もっと複雑なものも簡単に設定したいというあいまいな仕様になってしまいました。


実際に使うデータを処理できるだけで十分だということを念頭において仕様を考えるようにしたいです。


 


cocos2d-js-3.0-rc0 


が使えるようになりました(∩´∀`)∩ワーイ


setup.py をいちいち管理者権限で呼び出すのが面倒なのでバッチファイルを作りました。


2.2 のころと違って html を起動するだけというわけではなく、 cocos コマンドで実行するのが微妙に面倒ですが、ノードの親子関係に依存しないで奥行きを設定できたりするのが便利です。


project.json の module に extensions を追加しないと使えないのがわからず苦戦しましたが、ScrollView で簡単にスクロールできるようになってよかったです。


 



jsonId の実装とテストケース


2014年7月13日日曜日

JSON のオブジェクトを ID でリンクする(4)


gistb28ba8146f829f3f3254


JSON のオブジェクトを ID でリンクする(3) - SakuraCrowd’s blog の続きです。前回まではテストケースをクリアする実装までいけていたのですが、今回はテストケースを書いたまでで、それを満たす実装は勉強中です。


いつもどおり、仕様の説明は gist のコメントに書いてあります。


簡単に言うと、複数のオブジェクトが集まっている構造の中で一部だけを処理できるようにしました。


それだけならば、その一部のオブジェクトを引数にくわせりゃいいじゃんと思うんですが、 ID からデータに置換するには JSONPath の絶対パスを利用しています。


そのためルートが変わってしまうと ID からデータに置換できなくなってしまうのです。


 


JSONPath とか XPath とかパスもいろいろあるね(`・ω・´)


そんなかんなで jsonPath を使って処理を開始するノード要素を取得する処理を追加しました。


最初にはまったのはルートは "$" だから jsonPath.eval(target, "$") とすれば target の値が返されると思ったところでした。


実際は空の配列が返って来ます。


XPath の仕様などの説明を読んだところ、どうやらルートノードとルート要素というものは別物らしいです。


そして JSONPath でルート要素を表す場合は "$.*" とします。


これで target の値が取得できました。


 


eval だからって、えばる(eval)な!←いってみたかっただけです><


しかし、今度は ret = jsonPath.eval(target, "$.*") が ret == target ですが ret !== target になっています!


これでは、共通のオブジェクトへリンクする処理ではなく、同じ値を持つ別のオブジェクトへのリンクとなってしまいます。


どうすればいいのかなー。


現状はそんなところです。


 


2014年7月11日金曜日

JSON のオブジェクトを ID でリンクする(3)


gist8e9a924f3090183b6a41


JSON のオブジェクトを ID でリンクする(2) - SakuraCrowd’s blog の続きです。


詳しくは上記の gist のコメントに書きました。


前回は参照→オブジェクトへの変換だけでしたが、逆の変換の機能も追加しました。


参照とオブジェクトが混ざった状態から、オブジェクトだけに置換してしまうので、その後、どれがもともとオブジェクトだったのかわかりません。


そのため、変換の結果でそれを記録しておき、逆変換のときに利用します。


ない場合は、最初にみつけたオブジェクトの位置以外を参照に置き換えます。


 


git 苦手だったけどちゃんとできたよ(`・ω・´)


subversion も使いこなしてたってわけではありません。


しかし git はもっとわからなかったしやってませんでした。


そんなでしたが、いい機会だしとやってみると以外に簡単にやれました。


tortoiseGIT っていうコンテキストメニュー拡張のソフトを使いました。


バージョン管理したいファイルの置いてあるフォルダを選んで、「Git ここにリポジトリを作成」を選ぶ。


管理したいファイルを選択して Git > 追加 メニューで追加する。


あとはコミットすればOK。


ついテンパったりめんどくなるとコピーして日付つけて「どきっ!コピーだらけの開発フォルダ///」になってしまうのですが、なるべく git とかで管理しようといつも思っています。


 


jasmine-node が動かないヽ(`Д´)ノウワァァァン!!


以前に、 npm install -g jasmine-node でちゃちゃちゃっとインストールしておいて、以前はたしかコマンドプロンプトから jasmine-node でいけたはずなのに、「cannot find module」とか「ファイルとして認識されません」とかでちゃった(∀`*ゞ)テヘッ


なんか、いじっちゃったかなー、って環境変数とか確認してたけど、よくわからないまま3時間経過ヽ(`Д´)ノウワァァァン!!


自分の中ではこういう問題を「環境系バグ('∀`)」と呼び恐れています。


環境様を怒らせたらもう何がなんだかわからないバグがいっぱいでて(゚∀゚)アヒャヒャヒャヒャヒャヒャとなってしまうのですよ。


怖いですね(´・ω・`)


そんなときは思い切って再インストールすればいいんだよ!って思って node.js はしてみたんだけど、 npm のほうは残ってしまいました。


そこでたまたま見つけた node.js メニューの node.js command prompt を起動してみました。


Visual Studio の command prompt みたいに環境変数をちょこちょこと追加したコマンドプロンプトでした。


これで jasmine-node と実行するとちゃんと認識できたー(∩´∀`)∩ワーイ


 


next ('∀`)'s hint


ID で JSON のオブジェクトをリンクさせる機能は sakuraCrowd.jsonId という名前で作成したので、これを使う上位の関数 loadTmx(仮)を作ろうと思います。


loadTmx は node で動くので jasmine-node を動かそうといろいろやってたのです。


おおざっぱにいうと tmx を読み込んで、オブジェクトレイヤーのオブジェクトに jsonId を適用します。他にそのオブジェクトを拡張するのですが、それはまた今度書こうと思います。


2014年7月9日水曜日

JSON のオブジェクトを ID でリンクする(2)


gistcf43df70ff1d946640af


 


JSON のオブジェクトを ID でリンクする - SakuraCrowd’s blog の関数のテストケースの作成と実装を行いました。


関数の説明は gist のコメントに書きました。


 


JSONPath でいいんじゃね?->やっぱり ID もいるよね!


リンクを展開していく際に、循環参照を検知したらエラーにして、発生した場所をメッセージで伝える仕様にしました。


その場所の表し方を検討していたところ、 JSONPath という XPathJSON 版がみつかりました。


「あれ? ID とか独自仕様作らないで JsonPath でリンクすればいいんじゃね?(`・ω´・)」と思い始めました。


実際、それですんだら独自仕様なんて面倒なものから解放されるのでよいと思ったのですが、ぐぬぬと思う残念なところがあって、先日の提案どおり ID によるリンクにしました。


残念なところとは、上位へのアクセスを指示する .. が使えないことです。


.. 自体はあるのですが、再帰の指示で使われていて意味が異なりました。


これがないと、同じ階層にある他のオブジェクトを指すために絶対パスが必要になると思います。


ID はプロパティを割り振る手間や重複などのデメリットがありますが、ユーザが簡単にオブジェクトを指すことができます。


もともと、この機能は TMX の中のオブジェクトの設定を簡単にするために作っています。


TMX 自体は XML で表されていて、それを tmx-parser で JavaScript のオブジェクトに変換します。


TMX の編集中に JSONPath を意識するのは難しいので、 ID によるリンクでよいと思いました。


 


開発環境とかコーディングルールとか


実際のところ、関数の作成よりも開発環境や基本的な書き方の勉強に時間がかかりました。


しかも、まだふわふわしています。


 


JavaScript のライブラリの書き方 (まだふわふわ)


JavaScript によるライブラリの書き方は underscore.js を参考にしました。


無名関数の中で、ライブラリ用のプロパティをグローバル変数に追加します。


同じ名前の変数がすでにある場合は直前まで割り当てられていた値に戻せる関数 noConflict も underscore.js や jQuery を参考にしてやろうと思いましたが、まだ必要性がないと思いやってません。


最低限の機能として、 node.js の場合は exports 変数にライブラリ用の変数を設定するようにしました。


 


テストフレームワーク Jasmine を使ってみた


Jasmine についてはサンプルを適当にいじっただけです。


Jasmine-standalone はダウンロードして specrunner.html を起動するだけでサンプルが動くし、その中を見れば直感的にカスタマイズできる感じでわかりやすいです。


 


IDE になじめず軽くへこむ


aptana とか VS express 2013 for web などの IDE も使ってみたのですが、インテリセンスやブレークポイントがうまく使えませんでした。


「俺、向いてないのかな(´・ω・`)」とまじで落ち込むくらいに、正しい使い方がわかりませんでした。


 


ブラウザのデバッガがすごい


結局、デバッガは FireFox の F12「要素を調査」を使いました。


chrome の「要素を検証」でもよかったのですが、 cocos2d のサンプルが chrome ではなぜか動かず FireFox では動いたので、 FireFox でやっています。


Jasmine でテストして、失敗したとこだけ、ブレークポイントをはって実行というパターンがわかりやすくてデバッグしやすかったです。


 


テスト駆動のにわかの感想


テスト駆動だと、修正確認を短いサイクルで行えるので不安要素が少なくなっていじりやすいです。


2014年7月6日日曜日

JavaScript のテストフレームワーク Jasmine の勉強

Jasmine というテストフレームワークを勉強中です。


Jasmine を選んだ理由



  • クライアントサイドだけでなくサーバサイドもサポートしている

  • クライアントサイドは jasmine standalone 、サーバサイドは jasmine-node が提供されている。
  • わりと人気がありそう

  • 主観ですが、検索すると結構使われていそうでした。よらば大樹の陰。

Jasmine standalone を使ってみる


バージョン 1.3 と 2.0 系があったので 2.0 系をダウンロードしてみました。
SpecRunner.html というそれっぽいのを起動すると、同梱しているサンプルのテストの実行結果が表示されました。
SpecRunner.html 内で、フレームワークの .js とテスト対象の .js とテストコードの .js を指定して利用します。


jasmine-node を使ってみる


jasmine-node のバージョンは 1.14.3 となっていて、standalone と足並みそろってないのかなと思いました。
こちらは実行対象をファイル単位で指定せず、ディレクトリ単位です。


クライアントサイドのテストコードとの大きな違い




    • クライアントサイドでは script タグで読み込むファイルを require で読み込む。

    • テスト対象の関数の代入先が違う。

    • クライアントサイドでは単純に関数を定義するだけでした。 var func1 = function(){...}



      jasmine-node では、 exports.func1 = func1; としたりして、 exports のプロパティに設定する必要がある。

      これは Jasmine というよりクライアントサイドと node.js の違いかもしれません。


できたらクライアントサイドもサーバサイドもコードを共用したい


クライアントサイドとサーバサイドでそれぞれネットで見つけた FizzBuzz のテストケースを実行できました。
できましたが、まだ不満があります。前述した違いを除くと、テストコードが同じであることです。


同じようなコードをクライアントサイドとサーバサイドの両方で書くことは、DRY のポリシーに反するような気がします。


そこで、同じファイルで実行できないか模索中です。


これは、 Jasmine というよりもクライアントサイドと node.js の話になり、まだまだ難航しているので別に書きたいです。
ぐぐってみると、 typeof window === 'undefined' という条件で分岐させるなどの方法がでているのですが、やり方が悪いらしくうまくいっていません。
クライアントサイドと node.js でコードとそのテストケースを共用できるようにもう少し調べてみます。


2014年7月2日水曜日

JSON のオブジェクトを ID でリンクする

複数のプロパティに同じ値のオブジェクトを設定するのは面倒だし同じであることがわかりにくい。


{"prop1":{"value":12345},


 "prop2":{"value":12345},


 "prop3":{"value":12345}}


 


いちいち同じ値のオブジェクトを記述しないで、共通のオブジェクトを参照したくなりました。


あれ={"value":12345}


{"prop1":あれ, "prop2":あれ, "prop3":あれ}


 


 そこで、 ID というプロパティを持たせて、オブジェクトを ID で表せないか考えました。


共通のオブジェクトを指定したい場合は、そのプロパティにオブジェクトの ID を指定します。


{"id":"hoge", "value":12345}


{"prop1":"hoge", "prop2":"hoge", "prop3":"hoge"}


 


ID といってもただの文字列なので、読み込み側でオブジェクトが指定されるはずのプロパティで文字列があったら、その文字列を ID とするオブジェクトを割り当てる処理が必要です。


 「オブジェクトが指定されるはずのプロパティ」かどうかを判別する手段として、あらかじめ読み込み側に教えておくか、プロパティ名にプレフィックスなどをつけて表すことが考えられます。


さらに何かないかと調べていると、JSON のハイパースキーマ仕様には参照型というものがある事を知りました。


JSONだってハイパーメディア -- JSONハイパースキーマ仕様をなんとかしたい - 檜山正幸のキマイラ飼育記


URL をただの文字列ではなく "$ref" というプロパティの値として指定することで、その文字列が参照であることを表します。


 


これを先ほどの例に適用すると、さきほどよりも参照であることが明確にわかるようになりました。


{"id":"hoge", "value":12345}


{"prop1":{"$ref":"hoge"}, "prop2":{"$ref":"hoge"}, "prop3":{"$ref":"hoge"}}


 


$ref をいちいち打つのが面倒とか思ってしまいそうですが、今後も特別な意味を持つ文字列を扱いたい場合などにこの方法は有効だと思いました。


直接の関係はありませんが、ECMA script 5 の property descriptor も値をオブジェクトに包んで情報を付加しています。


 


これならば読み込み側でプロパティによって処理を変える必要はないので、扱うデータによって読み込み側を変更する必要はありません。


「$ref プロパティだけのオブジェクト」が値の場合は参照として処理すればよいだけです。


 


今日は仕様をある程度形にできました。明日は実装までいきたいです。


JavaScript 自体まだ不慣れなところがありますが、テストケースのフレームワークがあればそれを使ってみたいです。