ビリビリ魔人さん製作過程1:キャラの移動と回転

2009/11/12

矢印キーで移動、マウスカーソルの位置に合わせてキャラが回転します。
反応しない場合はムービーのどこかを一度クリックすると動くかも。
なんかドット絵を回転させたものが汚くなるけど気にしない。
(2009/11/15追記:ライブラリに読み込んだビットマップを右クリック→プロパティ→スムージングにチェックを入れることで、ドットが綺麗なまま回転させることができました。)

更新のネタもないので、製作中のビリビリ魔人さんの製作過程でも載せていこうかと。
今回は主人公キャラの移動と、マウス位置に合わせた回転を実装。
移動は以前の「キーボード操作でムービークリップを動かすテスト」のasファイルを改造して使っています。
最初はmouseXとかが未定義のプロパティ扱いされて困ってたけど、MovieClipクラスを継承させることで一応解決はしました。
ただ、この状態でソースにstageとか書くとエラーが出るのが謎すぎる。

まずはasファイルのソース。
package {
	import flash.ui.Keyboard;
	import flash.display.*;
	import flash.events.*;
	//
	public class plymv extends MovieClip {
		var keyflg:int = 0;
		const KY_U:int = 0x01;
		const KY_D:int = 0x02;
		const KY_R:int = 0x04;
		const KY_L:int = 0x08;
		var chara:MovieClip;
		var dmax:uint = 15;
		var dv:int = 1;//加速度
		var dx:Number = 0;
		var dy:Number = 0;
		var w:uint=0;
		var h:uint=0;
		var theta:Number=0;//回転角[rad]
		//コンストラクタ
		public function plymv(mc:MovieClip) {
			chara = mc;
			//ステージ境界
			w=chara.stage.stageWidth;
			h=chara.stage.stageHeight;
			//
			mc.stage.addEventListener(KeyboardEvent.KEY_DOWN,kdwn);
			mc.stage.addEventListener(KeyboardEvent.KEY_UP,kup);
			mc.stage.addEventListener(Event.ENTER_FRAME,mv);
		}
		//
		//矢印キーを押したときにフラグを立てる
		function kdwn(event:KeyboardEvent):void {
			if (event.keyCode == Keyboard.UP) {
				keyflg |= KY_U;
			}
			if (event.keyCode == Keyboard.DOWN) {
				keyflg |= KY_D;
			}
			if (event.keyCode == Keyboard.RIGHT) {
				keyflg |= KY_R;
			}
			if (event.keyCode == Keyboard.LEFT) {
				keyflg |= KY_L;
			}
		}
		//矢印キーを離したときにフラグを潰す
		function kup(event:KeyboardEvent):void {
			if (event.keyCode == Keyboard.UP) {
				keyflg &= ~KY_U;
			}
			if (event.keyCode == Keyboard.DOWN) {
				keyflg &= ~KY_D;
			}
			if (event.keyCode == Keyboard.RIGHT) {
				keyflg &= ~KY_R;
			}
			if (event.keyCode == Keyboard.LEFT) {
				keyflg &= ~KY_L;
			}
		}
		//キャラの移動・回転
		function mv(event:Event):void {
			//キャラ移動
			if (keyflg & KY_U) {
				dy -=dv;
				if (dy<-dmax) {
					dy =-dmax;
				}
			} else if (keyflg & KY_D) {
				dy +=dv;
				if (dy>dmax) {
					dy =dmax;
				}
			} else {
				dy*=0.8;
				if (dy*dy<0.01) {
					dy=0;
				}
			}
			if (keyflg & KY_R) {
				dx +=dv;
				if (dx>dmax) {
					dx =dmax;
				}
			} else if (keyflg & KY_L) {
				dx -=dv;
				if (dx<-dmax) {
					dx =-dmax;
				}
			} else {
				dx*=0.8;
				if (dx*dx<0.01) {
					dx=0;
				}
			}
			chara.x+=dx;
			chara.y+=dy;
			//キャラ回転
			if (mouseX-chara.x>=0) {
				//右向き時
				chara.scaleX = 1
				//現在のキャラの座標とマウスの位置から回転角を出す
				theta = Math.atan2(mouseY-chara.y,mouseX-chara.x);
				
				//rotationの単位的に考えて、角度をラジアンから度に変換してます
				chara.rotation = theta/Math.PI*180;
			}else{
				//左向き時も同様に角度を計算し、単位を変換してから回転させてます
				chara.scaleX = -1
				theta = Math.atan2(mouseY-chara.y,chara.x-mouseX);
				chara.rotation = -theta/Math.PI*180;
			}
			//境界
			if (chara.x <0) {
				chara.x=0;
			} else if (chara.x > w) {
				chara.x =w;
			}
			if (chara.y <0) {
				chara.y=0;
			} else if (chara.y > h) {
				chara.y =h;
			}
		}
	}
}
次はflaファイル。
今回はキャラをライブラリからリンケージ書き出ししています。
「プレイヤー」という名前のムービークリップを作り、リンケージプロパティにてクラスを「player」、基本クラスを「flash.display.MovieClip」としています。
「ActionScriptに書き出し」と「最初のフレームに書き出し」にチェックを入れます。
経験上、「最初のフレームに書き出し」はチェックを入れない方がWEB上での表示がスムーズにできます。最初にローディング画面を入れるときなんかは特に。
文字通り一番最初のフレームにどばっと書き出しているのでしょう。チェックが入ったインスタンスが多いほど最初の画面が表示されるまでに時間がかかるようになるようです。
ただ今回のゲームはWEB上での公開ではなくCDに収録してもらうことを前提にしているので、ローティング画面を必要としません。
そういう場合は「最初のフレームに書き出し」にチェックがあった方が楽な気がします。

次に、タイムライン上に以下のソースを書きます。
var ply:player = new player();
ply.x=320;
ply.y=180;
addChild(ply);
これで画面上にキャラが表示されるようになります。
表示されるだけでは意味がないので、もう一手間。
先ほど作った「プレイヤー」というムービークリップのタイムライン上(ここでは1フレーム目に書きました)に、以下のソースを書きます。
var pmv:plymv = new plymv(this);
これでキャラがasファイルを読み込んでくれて、動かせるようになりました。

ここに書いたことは、あくまで「自分がこうやりました」という記録であって、これが正しいやり方というわけではありません。
なんかもっといいやり方があると思います。
むしろ自分が教えて頂きたいものです。
「こうした方がいい」等の意見がありましたら、よかったらブログの方にコメントしてください。

戻る。