Flashでゲームキャラを動してみる2。オンラインゲームが作りたい(4)
前回に引き続きキャラクターを動かす。
前回の記事はこっち(そろそろ同一ウィンドウ内でリンクしたい)
今回はちょっと変わってます。ポイントは以下の3つ。
- RPGツクール2000用のキャラクターチップを読込む
- 一枚の画像からキャラクターアニメーションを作成
- キャラクターが止まってるときは、ちゃんと足をそろえる。
RPGツクール2000用のキャラクターチップを読込むってのが特にポイント。
ドット絵描けない自分にとって、フリーでゲーム用素材を提供してくれる職人様は神様です。
でも、ネット上で配布されているフリーのゲーム素材のほとんどがRPGツクール2000ベースで作成されています。
たまに、XP用などもありますが、2000の方が「RPGツクール以外のゲームでも使って良いよ」素材が多いので今回は2000のキャラクターチップからロード出来るように作成しました。
こういう画像を読込みます。
素材はあらかじめ透過色を指定しておいてください。
配布元によっては複数のキャラクターが一枚の画像にまとめられている場合があります。
その場合はフォトショでアクションでも組んでください。
3つのクラスで構成されています。
NetworkGame.as
package { import flash.display.*; import flash.events.*; import flash.utils.*; public class NetworkGame extends Sprite { // プレイヤー private var player:Character; // キーコード private var keyCode:Number; public function NetworkGame() { // プレイヤー作成 player = new Character(); addChild( player.getMovieClip() ); // イベントリスナーの追加 stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownEvent); stage.addEventListener(KeyboardEvent.KEY_UP,keyUpEvent); // タイマーの追加(100m秒間隔、無制限) var timer:Timer = new Timer(100,0); // イベントリスナーの追加(発生時に) timer.addEventListener(TimerEvent.TIMER,timerEvent); // タイマーの開始 timer.start(); } // キーダウンイベント private function keyDownEvent(event:KeyboardEvent):void { // キーコードを代入 keyCode = event.keyCode; } // キーアップイベント private function keyUpEvent(event:KeyboardEvent):void { // 静止アニメーション if (keyCode == 37) { player.stopLeft(); } else if (keyCode == 38) { player.stopUp(); } else if (keyCode == 39) { player.stopRight(); } else if (keyCode == 40) { player.stopDown(); } // キーコードを空にする keyCode = 0; } // タイマーイベント private function timerEvent(event:TimerEvent):void{ // 移動 ←↑→↓ if (keyCode == 37) { player.moveLeft(); } else if (keyCode == 38) { player.moveUp(); } else if (keyCode == 39) { player.moveRight(); } else if (keyCode == 40) { player.moveDown(); } // 攻撃 space if (keyCode == 32) { player.actionAttack(); } } } }
Character.as
package { import flash.display.*; import flash.events.*; import flash.utils.Timer; import mx.core.ButtonAsset; public class Character extends Sprite { // 素材クラスの定義 [Embed(source='images/character/player/0202.png')] private var char0202:Class; // MovieClip private var mc:MovieClip; // 移動スピード private var x_speed:Number;//X座標 private var y_speed:Number;//Y座標 private var reverse_flg:Boolean; // // RPG2kConverter public var converter:RPG2kConverter; //コンストラクタ public function Character() { // 変数の初期化 x_speed = 7;//X座標移動スピード y_speed = 7;//Y座標移動スピード // RPG2k用画像からプレイヤーMCの作成 converter = new RPG2kConverter(char0202); mc = converter.getMovieClip(); // 配置位置の初期化 mc.x = 0; mc.y = 0; } public function moveUp():void { var position:Number = converter.getPosition(); if(position == 12){ if(reverse_flg){ converter.changeMovieClip(13); reverse_flg = false; }else{ converter.changeMovieClip(11); reverse_flg = true; } }else{ converter.changeMovieClip(12); } mc.y -= y_speed; } public function moveRight():void { var position:Number = converter.getPosition(); if(position == 22){ if(reverse_flg){ converter.changeMovieClip(23); reverse_flg = false; }else{ converter.changeMovieClip(21); reverse_flg = true; } }else{ converter.changeMovieClip(22); } mc.x += x_speed; } public function moveDown():void { var position:Number = converter.getPosition(); if(position == 32){ if(reverse_flg){ converter.changeMovieClip(33); reverse_flg = false; }else{ converter.changeMovieClip(31); reverse_flg = true; } }else{ converter.changeMovieClip(32); } mc.y += y_speed; } public function moveLeft():void { var position:Number = converter.getPosition(); if(position == 42){ if(reverse_flg){ converter.changeMovieClip(43); reverse_flg = false; }else{ converter.changeMovieClip(41); reverse_flg = true; } }else{ converter.changeMovieClip(42); } mc.x -= x_speed; } public function stopUp():void{ converter.changeMovieClip(12); } public function stopRight():void{ converter.changeMovieClip(22); } public function stopDown():void{ converter.changeMovieClip(32); } public function stopLeft():void{ converter.changeMovieClip(42); } public function actionAttack():void { trace("攻撃"); } public function getMovieClip():MovieClip{ return mc; } } }
RPG2kConverter.as
package { import flash.display.*; public class RPG2kConverter extends Sprite { private var mc:MovieClip; private var position:Number; public function RPG2kConverter(source:Class){ // 元画像MC生成 var image:MovieClip = new MovieClip(); image.addChild(new source()); image.name = "image"; // マスク生成 var mask:MovieClip = new MovieClip(); mask.graphics.beginFill(0x000000); mask.graphics.drawRect(0,0,24,32); mask.graphics.endFill(); mask.name = "mask_mc"; mask.alpha = 0.5; // 合体!! mc = new MovieClip(); mc.addChild(image); mc.addChild(mask); mc.mask = mask; mc._x = 0; mc._y = 0; //初期画像 mc.getChildByName("image").x = -24; mc.getChildByName("image").y = -64; } public function getMovieClip():MovieClip{ return mc; } public function getPosition():Number{ return position; } public function changeMovieClip(n:Number):void{ // 位置を記憶 position = n; switch (n){ case 11: mc.getChildByName("image").x = 0; mc.getChildByName("image").y = 0; break; case 12: mc.getChildByName("image").x = -24; mc.getChildByName("image").y = 0; break; case 13: mc.getChildByName("image").x = -48; mc.getChildByName("image").y = 0; break; case 21: mc.getChildByName("image").x = 0; mc.getChildByName("image").y = -32; break; case 22: mc.getChildByName("image").x = -24; mc.getChildByName("image").y = -32; break; case 23: mc.getChildByName("image").x = -48; mc.getChildByName("image").y = -32; break; case 31: mc.getChildByName("image").x = 0; mc.getChildByName("image").y = -64; break; case 32: mc.getChildByName("image").x = -24; mc.getChildByName("image").y = -65; break; case 33: mc.getChildByName("image").x = -48; mc.getChildByName("image").y = -64; break; case 41: mc.getChildByName("image").x = 0; mc.getChildByName("image").y = -96; break; case 42: mc.getChildByName("image").x = -24; mc.getChildByName("image").y = -96; break; case 43: mc.getChildByName("image").x = -48; mc.getChildByName("image").y = -96; break; default: mc.getChildByName("image").x = -24; mc.getChildByName("image").y = -66; position = 32; break; } } } }
まったく関係ないけどRPGツクールアドバンスは名作だと思う。
次回はそろそろサーバーと連携。
今回使用しているドット絵はREFMAP様が配布しているフリー画像素材を使用してます。ゲームからデータを取り出しての2次使用は禁止されています。詳しくはこちらを参考ください。