Javascriptゲームエンジンのまとめと自作
HTML5とJavascriptは、次世代ブラウザの中心的技術となった。
それは、iphoneがフラッシュのサポートをうち切ったことで、ますます明確になった。
フラッシュ以外でゲームを作成する方法はいくつかある。
- Objective-Cでネイティブアプリの開発
- JavascriptとHTML5とCSS3によるWEBアプリの開発
実際のゲーム開発におけるコストを考えたとき、開発しやすさや、更新しやすさを考えたとき、Javascript+HTML5+CSS3の開発はObjective-Cに勝る場合がある。
そして、ブラウザの性能やiphoneを始めとするスマートフォンの速度も大幅に向上してきている。
ひょっとしたら最後に笑うのは標準化されつつある
Javascript+HTML5+CSS3
かもしれない。
そこで、JavascriptとHTML5とCSS3によるゲーム開発ライブラリを調べてみた。
JavascriptとHTML5、CSS3によるゲームの開発
現在いくつものライブラリが出てきている。
どれもsprite機能を持ち、Map機能も持ち、ゲームループを実装した本格的なものだ。
enchant.js
ARCといういかにもかっこいい名前の大学生チームが作成した、Javascriptでゲームを作るライブラリ。
UEIがバックについてそのサポートを行なっているらしい。
- UEIによるenchant.js
- 作者本人によるプレゼン
- 公式サイト
このライブラリでのゲーム開発は、例えば以下のようになる
( 公式サイトのサンプルより抜粋)
enchant(); window.onload=function(){ var game = new Game( 230 , 320 ); gamefps = 24; game.preload('chara1.gif'); game.onload = function(){ var bear = new sprite( 32 , 32 ); bear.x = 9; bear.y = 9; bear.image = game.assets('chara1.gif'); bear.addEventListener( 'enterframe' , function(e){ if( game.input.right ){ bear.x += 2; } if( game.input.left ){ bear.x -=2; } if( game.input.up ){ bear.y -=2; } if( game.inputdown ){ bear.y +=2; } }); game.rootScene.addChild( bear ); var pad = new Pad(); pad.x = 0; pad.y = 224; game.rootScene.addChild(pad); game.rootScene.backgroundColor = '#ffffff'; }; game.start(); };
なるほど、美しい。
ちょっとpadの意味が一見して分からないが、再生してみると、画面左下に自動的にpadの画像が出た。
どうやら使えるイメージ、マップ、ドット絵を同梱しているらしい。
アイデアを即座にゲームにする事に重点を置いたゲームライブラリであると思う。
enterframeにバインドしているのは、各フレームが始まる時に、この関数を呼び出すためだ。
ちなみに、他のライブラリも見てみよう。
GameQuery
jQueryをゲームように拡張したライブラリだ。
- 公式サイト
http://gamequery.onaluf.org/tutorials/1/step1.php
記法がjQueryの記法であるので、非常にDOM的にかける。
しかし、直感的に、オブジェクティブ指向的に記述できるのはenchant.jsの方かもしれない。
crafty
ソース例:(Demoのソース)
window.onload = function() { Crafty.init(550, 440); Crafty.sprite(64, "images/fruit.png", { banana: [0,0], apple: [1,0], watermelon: [2,0], orange: [3,0], coconut: [4,0], lemon: [5,0] }); Crafty.background("url('images/bg.png') no-repeat"); var scoreEnt = Crafty.e("2D, DOM, Text").attr({x: 5, y: 5, w: Crafty.viewport.width, h: 50}).text("Score: 0"), score = 0; Crafty.c("fruit", { _choice: ["banana", "apple", "watermelon", "orange", "coconut", "lemon"], _xspeed: 0, _yspeed: 0, init: function() { var index = Crafty.randRange(0, 5), fruit = this._choice[index], rotation = Crafty.randRange(8, 12), direction = Crafty.randRange(0, 1); this.addComponent(fruit).origin("center"); this.y = Crafty.viewport.height; this._yspeed = Crafty.randRange(15, 18); this.z = 1; if(direction) { this.x = 0; this._xspeed = Crafty.randRange(3, 5); } else { this.x = Crafty.viewport.width; this._xspeed = -1 * Crafty.randRange(3, 5); } this.bind("enterframe", function() { this.rotation += rotation; this.y -= this._yspeed; this.x += this._xspeed; if(this._y > Crafty.viewport.height) { this.destroy(); if(!this.hit) { score -= (index+1) * 10; scoreEnt.text("Score: "+score); } } }); this.bind("mouseover", function() { this.sprite(index, 1); this.hit = true; score += (index+1) * 10; scoreEnt.text("Score: "+score); Crafty.e("2D, DOM, "+fruit).attr({z:0, x: this._x, y: this._y, alpha: 0.2}).sprite(index, 2); this.unbind("mouseover"); }); } }); Crafty.e().bind("enterframe", function(e) { var sparsity = Crafty.randRange(10, 50); if(e.frame % sparsity == 0) { Crafty.e("2D, DOM, fruit, Gravity, Mouse").gravity("floor"); } }); };
ソース例をみるかぎり、enchant.jsほど直感的でないにしても、enchant.jsに似ている。
- 公式サイト
その他cocos2Dとかもある。
非常に面白い。
そこで、無謀にも自分でもつくってみようと思った!
自分用ゲーム開発ライブラリの要件
- ゲームループを自分でかける
- 表示する各部品ごとに設定をかける
- 表示する各部品に対して、簡単に操作をかける
- タッチ(iphone)とクリックを拾える(その位置も簡単に取得できる)
とりあえずここまで出来ました。
berry_gameです。
$( function(){ berry_game.setField( 'scratch' ); // オブジェクトの作成 var ball = berry_game.make( "<div>" , {} ,false ) .setStart( function(ts){ return true; } ) .setEnd( function(ts){ return this.data.ef == true ; } ) .setInit( function(ts){ this.setPos( this.arg.x , this.arg.y ); this.flag = true; this.data.d = 10 ; this.moon(); var color_list = ["red" , "black" , "orange" , "pink" , "blue" ]; this.setBo( color_list[berry_game.random( 0 , 5 )] , 3 , 'solid' ); //this.setBg( color_list[berry_game.random( 0 , 5 )] ); this.setW(10); this.setH(10); this.data.ef = false; this.show();} ) .setLoop(function(ts){ if( this.explode( this.data.d , 20 ) == false ){ this.data.ef = true; } }) .setDestroy( function(ts){ this.remove(); } ); // メインループ berry_game.loop = function(){ if( berry_game.flag.push ){ berry_game.add( ball , {"x":berry_game.point.x , "y":berry_game.point.y } ); } }; berry_game.start(); } );
様々な処理が面倒なので、内部的なDOM操作はjQueryで行なっています。
setFiledで動作範囲をセットします。
makeで内部動作させるオブジェクトをメイクします。
- setStartでこのオブジェクトの動作条件を
- setEndでこのオブジェクトの終了条件を
- setInitでこのオブジェクトの初期化処理を
- setDestroyでこのオブジェクトの終了処理を
- setLoopでこのオブジェクトの動作を設定します。
◎this.dataにこのオブジェクト内固有で使用できる様々なデータを格納しつつ、それぞれの処理を記述します。
そして、berry_game.loopに全体のループ処理を記述します。
この例のソースコードでは、花火ができます。
iphoneでもできるように、タッチでも反応します。
しかし花火をクローンして、複数描画すると処理速度が追いつかないようです。
花火をクローンしないことによってiphoneでも処理できます。
次はスプライト機能をつけ、マップ処理簡単に行えるようにしたいと思います。