Processing.js製 弾幕シューティングを、enchant.jsに移植してみた
wise9で連載されていた弾幕シューティング作成講座がかなり面白かったですね。
第四回目の記事で、ついに弾幕が出た時は興奮ものでした!
ちょうど、enchant.jsの習作としてなにか作りたいなーと考えていたので
これの移植に挑戦してみたいと思います。
元記事一覧
http://wise9.jp/category/連載-processing-js-で初めてのゲームプログラミング
障害になるような違いはありません
Processing.jsや、ゲームのロジックは元記事を参照していただくとして
移植するには、文法的な違いを理解する必要がありそうですが
Processing.jsは、そもそもJSライブラリなので大きな違いはありません。
JSにはあまりなじみのない、型宣言とクラス定義さえおさえてしまえば簡単です。
Processing.jsのクラス定義の例
class Example { int x; Example(int dx) { x = dx; } void method(int dy) { x = x + dy; } }
それぞれの意味はこんな感じ
class クラス名 { 型 プロパティ; コンストラクタ(型 引数) { //初期化時によばれる関数 } 型 メソッド() { //戻り値がないならば、型はvoid } }
つまり例示の変数 x はint(整数)型であることを宣言し
method()は戻り値をもたない関数ということになります。
これをenchant.jsで書くならば
var Example = Class.create({ initialize: function(dx) { this.x = dx; }, method: function(dy) { this.x = this.x + dy; } });
Class.createにクラスの定義内容をオブジェクトで渡します。
initialize()は、継承または生成時に自動的に呼び出されるので
これをコンストラクタとして使います。
それから、型宣言はないので消してしまいます。
実際に書き直す
試しに次のソースコードを移植してみました。
サンプルプログラム03-2
enchant.jsに移植
//enchant.jsを初期化 enchant(); var mousePressed, mouseX, mouseY; var game, tama, stage, canvas; //setup()にあたる処理 window.onload = function() { game = new Game(320, 320); game.fps = 30; noCursor(); tama = new Tama(160, 0, 10); //描画用canvasを追加 stage = new Sprite(320, 320); stage.image = new Surface(320, 320); game.rootScene.addChild(stage); game.addEventListener(enchant.Event.ENTER_FRAME, draw); canvas = stage.image; //開始 game.start(); }; function ship(x, y) { stroke(255, 255, 255); triangle(x, y - 7, x - 10, y + 7, x + 10, y + 7); if (mousePressed) { line(x, y- 7 , x, 0); } }; var Tama = Class.create({ initialize: function(x, y, r) { this.tx = x; this.ty = y; this.tr = r; }, update: function() { this.ty += 10; stroke(255, 0, 0); ellipse(this.tx, this.ty, this.tr, this.tr); if (this.ty > game.height) { this.ty = 0; this.tx = Math.random() * game.width; } } }); function draw() { clear(); ship(mouseX, mouseY); tama.update(); }; //------------------------------------------------------------------------------ // Processing.jsのメソッドを簡易的に再現 // @see http://processingjs.org/ //------------------------------------------------------------------------------ /** * Base64形式の透明GIFを表示させて、デフォルトカーソルを消す */ function noCursor() { game.rootScene._element.style.cursor = "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto"; }; /** * クリア */ function clear() { canvas.context.fillStyle = "rgb(0, 0, 0)"; canvas.context.fillRect(0, 0, 320, 320); }; /** * 線の色 */ function stroke(r, g, b) { canvas.context.strokeStyle = "rgb("+ r +", "+ g +", "+ b +")"; }; /** * 三角形を描く */ function triangle(x1, y1, x2, y2, x3, y3) { canvas.context.beginPath(); canvas.context.moveTo(x1, y1); canvas.context.lineTo(x2, y2); canvas.context.lineTo(x3, y3); canvas.context.closePath(); canvas.context.stroke(); }; /** * 線を描く */ function line(x1, y1, x2, y2) { canvas.context.beginPath(); canvas.context.moveTo(x1, y1); canvas.context.lineTo(x2, y2); canvas.context.closePath(); canvas.context.stroke(); }; /** * 円を描く */ function ellipse(x, y, r) { canvas.context.beginPath(); canvas.context.arc(x, y, r, 0, 2 * Math.PI, false); canvas.context.closePath(); canvas.context.stroke(); }; /** * マウス座標 */ document.addEventListener("mousemove", function(e) { mouseX = e.pageX; mouseY = e.pageY; }, false); /** * マウスダウン */ document.addEventListener("mousedown", function(e) { mousePressed = true; }, false); /** * マウスアップ */ document.addEventListener("mouseup", function(e) { mousePressed = false; }, false);
コードの流れと関数名や変数をそのままになるように置き換えました。
前半部分のコードは、見た目的にサンプルと大きな違いはないと思いますが
構造的には、図形を描画するためのcanvas要素を生成して追加しています。
Processing.jsには、canvasを直感的に操作できる
triangleやellipseといった描画メソッドがあります。
後半部分は、このProcessing.jsの描画メソッドを必要な分だけ簡易的に追加してます。
これをenchant.jsとともに読み込ませると、サンプルと同じように動いてると思います。