🍃このブログは移転しました。
3秒後、自動的に移動します・・・。

enchant.jsのRPGに、動くだけのNPCを追加する

JavaScriptの勉強に大変良いということで、最近触り始めました。
RPG風のサンプルが、ドラクエやらポケモンやらを彷彿とさせてとっても楽しい!w

サンプルだと主人公は自分だけ。
キャラ絵は3種類あるみたいなので、登場させちゃおうかと。

簡単な手順

  1. 新しいキャラを作る。
  2. ランダムで動くように設定する。

ソース

// game.onload() = function(){ 以下
        var npc = new Sprite(32, 32);
        npc.x = 3 * 16 - 8;
        npc.y = 3 * 16;
        var npc_img = new Surface(96, 128);
        npc_img.draw(game.assets['chara0.gif'], 192, 0, 96, 128, 0, 0, 96, 128);
        npc.image = npc_img;
        npc.isMoving = false;
        npc.direction = 0;
        npc.walk = 1;

        npc.addEventListener('enterframe', function() {
        	this.frame = this.direction * 3 + this.walk;
            if (this.isMoving) {
                this.moveBy(this.vx, this.vy);
 
                if (!(game.frame % 3)) {
                    this.walk++;
                    this.walk %= 3;
                }
                if ((this.vx && (this.x-8) % 16 == 0) || (this.vy && this.y % 16 == 0)) {
                    this.isMoving = false;
                    this.walk = 1;
                }
            } else {
		var dir = Math.floor(Math.random()*4+1);
		var move = Math.floor(Math.random()*10); 
                this.vx = this.vy = 0;
                if (dir == 4 && !move) {
                    this.direction = 1;
                    this.vx = -4;
                } else if (dir == 2 && !move) {
                    this.direction = 2;
                    this.vx = 4;
                } else if (dir == 1 && !move) {
                    this.direction = 3;
                    this.vy = -4;
                } else if (dir == 3 && !move) {
                    this.direction = 0;
                    this.vy = 4;
                }
                if (this.vx || this.vy) {
                    var x = this.x + (this.vx ? this.vx / Math.abs(this.vx) * 16 : 0) + 16;
                    var y = this.y + (this.vy ? this.vy / Math.abs(this.vy) * 16 : 0) + 16;
                    if (0 <= x && x < map.width && 0 <= y && y < map.height && !map.hitTest(x, y)) {
                        this.isMoving = true;
                        arguments.callee.call(this);
                    }
                }
            }

        });
        stage.addChild(npc);

当然ですが、難しいことはしてません。
でも、できた!←重要

キャラ絵を変える

npc_img.draw(game.assets['chara0.gif'], 192, 0, 96, 128, 0, 0, 96, 128);
// 最初の値を、0か96か192で切り替え

0なら男の子、96ならショートの女の子、192だとリボンの女の子です。

動かす

var dir = Math.floor(Math.random()*4+1);
// サンプルコードは矢印キーか、アナログパッドの入力。
// ランダムで動く方向(上下左右の4方向)を、乱数で決めます。

var move = Math.floor(Math.random()*10); 
if (dir == 4 && !move) {
} else if( // ・・・
// enterframeイベントにくっつけて動かします。
// このイベントはほぼ起きっぱなしなので、10回に1回動くようにしてます。
// それでもNPCにしては動きすぎなイメージw

hitTest関数も既存のままなので、障害物は乗り越えません。

プレイヤーと重ならないように

しようと思ったのですが、ここがイマイチわかりません・・。
できた方はぜひ教えてください。

正確には、ほぼできたけど、完璧にはできなかったです。
プレイヤーが移動する時に、移動先にNPCがいればキャンセルするようにしました。
ただ、NPCの移動のタイミングと被ると、重なる場合やらすり抜ける場合があったりやら。
intersect()もwithin()も使ってません。