プログラミンでためしにゲーム作ってみた

文部科学省が「プログラミン」というマウス操作だけでゲームが作れるサービスを開始しましたね!
プログラミン | 文部科学省

パーツを組み立てるだけで、アニメーションとかキャラクター操作とか、色々出来るっぽいです。がんばればどんなゲームでも作れる?

ということで、私もためしに作ってみました。
プログラミン | 文部科学省

特にゲーム性はないよ!ジャンプの機能作るだけで一苦労。。。


また、非公式で作品ギャラリーがあるので、そっちを見るだけでも楽しいかも。
プログラミン作品ギャラリー 『プログラミンでつくったよ!』を集めるサービス

最近パーティクル崩しが熱いらしい

以前、私が作ったパーティクル崩しっていうちょっと変わったブロック崩しっていうのがあるんだけど、最近何度かそれをFORKしたやつがwonderflのランキングに上がってきてた。


このブログ自体のアクセス数も微妙に増える。てっきり前の記事が好評なのかなとか思ってたけど、「パーティクル崩し」とググって来てる人が多い。


パーティクル崩し・・・?結構前に作ったのになぜ今更。と、思ってググると謎がすぐに解けた。
うぉ!なんか、でっかそうなサイトに紹介されとる!
弾幕ブロック崩しがメチャクチャ気持ちいい! | Hiroiro
紹介されたおかげで、また、twitterにもいっぱいtweetされたらしいね!


紹介されすぎ!
弾幕ブロック崩し これはすごいです The Melancholy of なむ
パーティクル崩し | EffectSome
今までに無いボールの数を実現したブロック崩しゲーム パーティクル崩し : 銃とバッジは置いていけ
たれ込み情報 Vol.32:フラシュ - 無料ゲーム
パーティクル崩し: clown-crown(仮)の虹色工房
http://teruponblog.blog73.fc2.com/blog-entry-3423.html
http://papiyon-diary.cocolog-nifty.com/blog/2010/01/post-1.html
黒歴史の塊 弾幕ブロック崩しが意外と面白い件について

zoome.jp
音楽って重要だなって思った↑



FORKされたやつの一個紹介。
wonderfl build flash online | 面白法人カヤック
無限にパーティクルが復活するから、ずっと楽しめる!



ちなみにパーティクル崩しオープンソースだから誰でも改造して遊べるよ〜。
レッツwonderfl
私も時間と、やる気と、アイディアが出せれば改造して遊ぼうかな!

AS3の*型の問題点とその代替案 〜その3.解決策〜

解決策

オブジェクトリテラルのように書けて、静的型チェックもしたい。
そんな方法があるだろうか。


実は、クラスにちょっとした工夫を施すことによって解決できる。

//---Tweener.as---
class Tweener{
	public function addTween(obj:DisplayObject,args:TweenArgs):void{
		//code
	}
}

//---TweenArgs.as---
class TweenerArgs {
	public function $x(value:Number):TweenerArgs { x = value; return this; }
	public function $y(value:Number):TweenerArgs { y = value; return this; }
	public function $time(value:Number):TweenerArgs { time = value; return this; }	
	public function $alpha(value:Number):TweenerArgs { alpha = value; return this; }
	public function $delay(value:Number):TweenerArgs { delay = value;return this; }
	public var x:Number = 0;
	public var y:Number = 0;
	public var alpha:Number = 1;
	public var time:Number = 0;
	public var delay:Number=0;
}
//---呼び出し---
addTweener(obj,new TweenerArgs().$x(100).$y(100).$time(5));

$のついたメソッドは、引数をプロパティに代入して、thisを返すのもだ。
これをメソッドチェーンで呼び出すことによって、連続して変数の代入をしている。
これなら、余計な一時変数を作る必要も無いし、オブジェクトリテラルと比べても、そこまで長くは無い。
しかも静的型チェックもしてくる!


ライブラリ提供側にとっては、そういったクラスを作らないといけないというコストが掛かるが、
使う側にとっては、静的型付けの利点が生かせる。


完璧だ!
オブジェクトリテラルを使いたいと思ったら、まずこの方法で検討してみることをオススメするよ!

AS3の*型の問題点とその代替案 〜その2.オブジェクトリテラルの長所〜

目次

ではなぜ使う?

これらの問題があるのになぜオブジェクトリテラルと*型を使うのか?
まぁ理由があるからなのだが。

引数の多い関数では使いにくい

//---Tweener.as---
class Tweener{
	function addTween(obj:DisplayObject,x:Number=0,y:Number=0,alpha:Number=1,time:Number=0,delay:Number=0):void{
	//code
	}
}
//---呼び出し---
Tweener.addTween(obj,100,100,1,5);

addTween()の引数を*型にせず、一部羅列してみた例。
全部羅列しきれていない。
引数の順番を間違えないように注意深く使わないといけないし、途中の引数の省略ができない。
これでは使いにくすぎる。

型を用意して初期化しても余計な一時変数が増えてしまう

それならばクラスを用意してやって初期化すれば?

//---Tweener.as---
class Tweener{
	public function addTween(obj:DisplayObject,args:TweenArgs):void{
		//code
	}
}

//---TweenArgs.as---
class TweenArgs{
	public var x:Number=0;
	public var y:Number=0;
	public var alpha:Number=1;
	public var time:Number=0;
	public var delay:Number=0;
}

//---呼び出し---
var args:TweenArgs = new TweenArgs();
args.x = 100;
args.y = 100;
args.time = 5;
Tweener.addTween(obj,args);

擬似コード
静的型付けのOOPではよくやる例。
さっきよりはマシになったが、argsという変数を使わないといけなくなった。
addTween()を大量に使う場合には、いちいち変数を用意するというのが面倒になる。
あとTweenArgsというクラスを作らないといけないという手間が増えるが、これはライブラリ提供者としての手間なのでここでは目をつむることにする。

オブジェクトリテラルが一番シンプルにできる

//Tweener.as
class Tweener{
	public function addTween(obj:DisplayObject,args:*):void{
		//code
	}
}
//---呼び出し---
Tweener.addTween(obj,{x:100,y:100,time:5});

そう考えると、オブジェクトリテラルを使った例が、一番短く書けるというのがわかる。
しかしそれだと、静的型付けできない・・・。プログラマのジレンマ。


つづき
その3.解決策

AS3の*型の問題点とその代替案 〜その1.*型は問題点が多い〜

目次

長くなったので3部構成

静的に解決出来るところはすべてそうするべき

私は動的型付け言語は嫌いだ。どれくらい嫌いかというと、RubySchemeも、Pythonも、動的型付けという理由だけで、勉強しようとしないぐらい。
動的型付け言語なんて滅びればいいのに。

AS1のを使っていた頃に、嫌というほど味わったのが私の中では大きい。(しかもAS1は弱い型付けだ!)

AS2、AS3とバージョンが上がり、Javaのように静的型チェックをしてくれるようになった。
しかしながら、AS3では*型やオブジェクトリテラル、dynamicクラスを使うことによって動的型付けでもコーディングすることは可能だ。
これらは動的にしか解決できない場合に使用すると大きな効果が期待される。が、それ以外の場面では、型(クラス)をきちんと作り、静的に解決すべきた。

オブジェクトリテラルが使われている例

ProgressionTweenerPapervision3DなどAS3ライブラリの一部では*型が結構使われていたりする。
これはオブジェクトリテラルが短く書けるのでよく使われているのだが、動的型付けであるが故に弊害が出てくる。

Tweenerの例

package {
	import flash.display.Graphics;
	import flash.display.Sprite;
	import caurina.transitions.Tweener;
	public class FlashTest extends Sprite {
		public function FlashTest() {
			var box:Sprite = new Sprite();
			var g:Graphics = box.graphics;
			g.beginFill(0xFF0000);
			g.drawRect(0,0,10,10);
			g.endFill();
			addChild(box);
			Tweener.addTween(box,{
				x:100,
				y:100,
				delay:0.5,
				time: 1,
				scaleX:5,
				scaleY:4
			});
		}
	}
}

Tweener.addTween()の第二引数にオブジェクトリテラルが使われている。
ここにどのような問題が孕んでいるのか?

問題1.静的型チェックが行われない

オブジェクトリテラルを使用した場合、静的型チェックが行われない。
これはscaleXをscalexというふうにタイピングミスした時にはコンパイラはエラーを出してくれない。
また、scaleX:"10"のように、本当はNumber型を入れるべきところに、String型を入れた時もコンパイルエラーにならない。
つまりオブジェクトリテラルを使うということは静的型付けの一番の長所を使わないことになる。

問題2.*型では何を代入すればいいか分からない

function foo(obj:*):void{
	//code
}

こんなコードがあった場合、あなたはobjに何を入れればいいかわかりますか?
objに型さえついていれば、その型を代入すればいいということが理解出来るだろう。
しかし型が*の場合、ドキュメントを読まなければ理解できない。
Stringのメソッド(match)などの引数が*型のせいでいつもググって調べているのは私だけではないはず。

問題3.*型ではコード補完が出ない

コード補完の恩恵は美味しい。FlashDevelopを使っている人はよくわかっているだろう。
オブジェクトリテラルではそういった恩恵は受けられない。
どんなメンバがあったか、わざわざドキュメントまで探しに行かなければならない。

問題4.*型では実行速度が遅い

これは上の3つほどには気にならない問題。
だが、何千回もループして使用た場合パフォーマンスのボトルネックになりうる。


つづき
その2.オブジェクトリテラル

2009年やったことまとめ

全然まとまってないまとめ。
twitterやらwonderflやらいろいろ楽しんだ一年でした。
どっちとも今年入ってから始めたらしい。
果たして私は成長できてるのでしょうか?
まだまだ足りませんね。


来年はもっとはっちゃけたことするぞー!
いや、まだ、今年数時間残ってる!今年中にやるぞ!
うおおおお。