In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

本気でダンジョンRPG作る step3-(マップを立体化する)

LIVE CODING 2010/04/24	10:30-23:35
LIVE CODING 2010/04/25
wonderflでがんばってダンジョンRPGを作ってます。
ソースがどんどん膨らんでく。
ファイル分割したい。
とりあえずステップ3終了。このペースだと、
3000行は超えるだろうか。
マップ
緑:部屋 または 通路
赤:敵
ピンク:主人公
水色:階段
通ったことのない場所の階段,敵は見えません
操作方法
移動:方向キー
足踏み: A
階段を下りる: 階段上でSpace
今のところB2階までしかありません
English
I make a RPG.

step2:  move charactors
walk: arrow keys
step in place: A
go down stairs: Space
map
green: room or passage
red: Enemy
pink: player
light blue: staire
制作過程を残していきたいのでforkを重ねて制作してます。
PREVIOUS http://wonderfl.net/c/tFGr
NEXT http://wonderfl.net/c/oDmN
前のステップの差分は,上の[diff()]をクリックするとみることができます
/**
 * Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/t3qt
 */

// forked from shohei909's 本気でダンジョンRPG作る step2-(主人公、敵を動かす)
package{
	//LIVE CODING 2010/04/24	10:30-23:35
	//LIVE CODING 2010/04/25
	
	//wonderflでがんばってダンジョンRPGを作ってます。
	
	
	
	
	//ソースがどんどん膨らんでく。
	//ファイル分割したい。
	
	
	//とりあえずステップ3終了。このペースだと、
	//3000行は超えるだろうか。
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	//マップ
	//	緑:部屋 または 通路
	//	赤:敵
	//	ピンク:主人公
	//	水色:階段
	//通ったことのない場所の階段,敵は見えません
	
	
	//操作方法
	
	//移動:方向キー
	//足踏み: A
	//階段を下りる: 階段上でSpace
	
	//今のところB2階までしかありません
	
	
	
	
	
	//English
	
	// I make a RPG.
	// 
	// step2:  move charactors
	
	// walk: arrow keys
	// step in place: A
	// go down stairs: Space
	
	// map
	//	green: room or passage
	//	red: Enemy
	//	pink: player
	//	light blue: staire
	

	
	
	//制作過程を残していきたいのでforkを重ねて制作してます。
	
	//PREVIOUS http://wonderfl.net/c/tFGr
	//NEXT http://wonderfl.net/c/oDmN
	
	//前のステップの差分は,上の[diff()]をクリックするとみることができます
	
	import flash.display.*;
	import com.bit101.components.FPSMeter;
	
	[SWF(backgroundColor="#000000", frameRate="30",width="465",height="465" )]
    public class Game extends Sprite{
        public function Game() {
        		var back:Bitmap = new Bitmap(new BitmapData( 465, 465, true, 0xFF000033 ) );
			
			stage.addChild(back);
           	stage.addChild( new RPG() );
           	stage.addChild( new FPSMeter(stage) );
           	
        }
    }
}
import flash.display.*;
import flash.events.*;
import flash.ui.*;
import flash.utils.*;
import flash.text.TextField;
import flash.net.URLRequest;
import flash.system.*;
import flash.geom.*;
import org.papervision3d.view.*;
import org.papervision3d.materials.*;
import org.papervision3d.objects.primitives.*;


class RPG extends Sprite{
	private var map:Map;
	public function RPG(){ addEventListener( Event.ADDED_TO_STAGE, init );}
	public function init(e:Event):void{
		removeEventListener( Event.ADDED_TO_STAGE, init );
		
		map = new Map(30,30);
		while(this.numChildren>0){  this.removeChildAt(0);  }
		
		map.bitmap.scaleX = 3;
		map.bitmap.scaleY = -3;
		
		map.bitmap.x = 340;
		map.bitmap.y = 440;
		
		addChild(map.view);
		addChild( new Shadow(GameData.SWF_WIDTH,GameData.SWF_HEIGHT));
		addChild(map.bitmap);
		
		stage.addEventListener( "enterFrame", map.man.onFrame );
		stage.addEventListener( "keyDown", map.man.onKeyDown );
	}
}

class MapView extends BasicView{
	public var map:Map;
	
	private var plane:Plane;
	private var loader:Loader;
	public var load:Boolean =false;
	
	public var sourceImg:BitmapData;
	
	public var floorPlanes:Vector.<Vector.<Plane>>;
	public var hWallPlanes:Vector.<Vector.<Plane>>;
	public var vWallPlanes:Vector.<Vector.<Plane>>;
	public var manShadow:Plane;
	public var enemyShadows:Vector.<Plane>;
	
	public var viewW:int = 11;
	public var viewH:int = 11;
	
	public var centerX:int = 5;
	public var centerY:int = 4;
	
	public var lookX:Number = 0;
	public var lookY:Number = 0;
	public var cameraX:Number = 0;
	public var cameraY:Number = 0;
	
	public var images:Array;
		
	public function MapView(m:Map):void{
		super(465,465,false);
		map = m;
		
		loader = new Loader();
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
		loader.load(new URLRequest(GameData.IMAGE_URL),new LoaderContext(true));
	}
	
	private function loadComplete(e:Event):void{
		loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loadComplete);
		sourceImg = new BitmapData(loader.height,loader.width,true);
		sourceImg = Bitmap(e.currentTarget.loader.content).bitmapData;
		images = new Array();
		for each(var i:Object in GameData.IMAGE_ARRAY){
			images[i.name] = new BitmapData(i.w,i.h,true);
			images[i.name].draw( sourceImg, new Matrix(1,0,0,1,-i.x,-i.y), new ColorTransform(), BlendMode.NORMAL, new Rectangle(0,0,i.w,i.h) );
		}
		init();
	}
	
	public function init():void{
			floorPlanes = new Vector.<Vector.<Plane>>(viewW);
			for(var i:int=0; i<  viewW ;i++){
				floorPlanes[i] = new Vector.<Plane>(viewH);
				for(var j:int=0; j < viewH; j++){
					var material:BitmapMaterial = new BitmapMaterial(new BitmapData(50,50,false,0x000000));
					var fp:Plane = new Plane(material ,50,50);
					floorPlanes[i][j] = fp;
					fp.useOwnContainer = true;
					fp.x = 50 * i - 50 * centerX;
					fp.y = 50 * j - 50 * centerY;
					scene.addChild( fp );
				}
			}
			hWallPlanes = new Vector.<Vector.<Plane>>(viewW);
			for(i=0; i<  viewW ;i++){
				hWallPlanes[i] = new Vector.<Plane>(viewH+1);
				for(j=0; j < viewH+1; j++){
					material = new BitmapMaterial(images["wall"]);
					material.oneSide = false;
					var hwp:Plane = new Plane(material ,50,50);
					hWallPlanes[i][j] = hwp;
					hwp.useOwnContainer = true;
					hwp.x = 50 * i - 50 * centerX;
					hwp.y = 50 * j - 50 * centerY -25;
					hwp.z = -25;
					hwp.rotationX = -90;
					scene.addChild( hwp );
				}
			}
			vWallPlanes = new Vector.<Vector.<Plane>>(viewW+1);
			for(i=0; i<  viewW+1 ;i++){
				vWallPlanes[i] = new Vector.<Plane>(viewH);
				for(j=0; j < viewH; j++){
					material = new BitmapMaterial(images["wall"]);
					material.oneSide = false;
					var vwp:Plane = new Plane(material ,50,50, 1, 1);
					vWallPlanes[i][j] = vwp;
					vwp.useOwnContainer = true;
					vwp.x = 50 * i - 50 * centerX-25;
					vwp.y = 50 * j - 50 * centerY;
					vwp.z = -25;
					vwp.rotationZ = -90;
					vwp.rotationX = -90;

					scene.addChild( vwp );
				}
			}
			enemyShadows = new Vector.<Plane>();
			manShadow = map.man.shadow;
			manShadow.useOwnContainer = true;
			manShadow.z = -12;
			scene.addChild( manShadow );
			
			
			cameraX = 0;
			cameraY = -200;
			camera.z = -400;
			camera.zoom = 70;
			
			load = true;
			floorUpdate();
			addEventListener(Event.ENTER_FRAME, onFrame);
	}
	
	public function onFrame(evt:Event):void{
		for each(var e:Enemy in map.enemys){
			if(e.shadow.visible){
				e.motion.update();
				e.shadow.x = 50 * ( e.motion.x - map.man.x );
				e.shadow.y = 50 * ( e.motion.y - map.man.y )-7;
			}
		}
		
		
		map.man.motion.update();
		manShadow.x = 50 * ( map.man.motion.x - map.man.x );
		manShadow.y = 50 * ( map.man.motion.y - map.man.y )-7;
			
		camera.target = manShadow;
		camera.x=cameraX+manShadow.x;
		camera.y=cameraY+manShadow.y;

		renderer.renderScene(scene, camera, viewport);
	}
	public function floorUpdate():void{
		for each(var shadow:Plane in enemyShadows){
			scene.removeChild( shadow );
		}
		for each(var e:Enemy in map.enemys){
		 	enemyShadows.push( e.shadow );
		 	e.shadow.visible = false;
		 	e.shadow.useOwnContainer = true;
			e.shadow.z = -12;
			scene.addChild( e.shadow );
		}
		update();
	}
	public function update():void{
		for each(var e:Enemy in map.enemys){
			if( e.x-map.man.x < viewW-centerX && map.man.x-e.x < centerX && 
				e.y-map.man.y < viewH-centerY && map.man.y-e.y < centerY){	
			 		e.shadow.visible = true;	
			}else{e.shadow.visible = false;}
		}
		
		for(var i:int=0; i<  viewW ;i++){
			for(var j:int=0; j < viewH; j++){
				var mapI:int = i - centerX + map.man.x;
				var mapJ:int = j - centerY + map.man.y;
				var fp:Plane = floorPlanes[i][j];
				if(mapI < 0 || map.width <= mapI || mapJ < 0 || map.height <= mapJ ){
					fp.material.bitmap = images["roof"];
					fp.z = -50;
				}else{
					var f:Floor = map.floors[mapI][mapJ];
					switch(f.name){
						case "route" :	case "room":
							if(f.isStair){	fp.material.bitmap = images["staire"];}
							else{			fp.material.bitmap = images["floor"];	}
							fp.z = 0;
							break;
						default:
							fp.material.bitmap = images["roof"];
							fp.z = -50;
							break;
					}
				}
			}
		}
		for(i=0; i< viewW ;i++){
			for(j =0; j < viewH+1; j++){
				mapI = i - centerX + map.man.x;
				mapJ = j - centerY + map.man.y-1;
				var hwp:Plane = hWallPlanes[i][j];
				hwp.visible = false;
				if( (mapI < 0 || map.width <= mapI || mapJ < 0 || map.height <= mapJ)==false ){
					f = map.floors[mapI][mapJ];
					switch(f.name){
						case "route" :	case "room":
							if( map.floors[mapI][mapJ+1].name == "wall"){	hwp.visible = true;		}
							break;
					}
				}
				mapJ = j - centerY + map.man.y;
				if( (mapI < 0 || map.width <= mapI || mapJ < 0 || map.height <= mapJ)==false ){
					f = map.floors[mapI][mapJ];
					switch(f.name){
						case "route" :	case "room":
							if( map.floors[mapI][mapJ-1].name == "wall"){	hwp.visible = true;		}
							break;
					}
				}
			}
		}
		for(i=0; i< viewW+1 ;i++){
			for(j =0; j < viewH; j++){
				mapI = i - centerX + map.man.x-1;
				mapJ = j - centerY + map.man.y;
				var vwp:Plane = vWallPlanes[i][j];
				vwp.visible = false;
				if( (mapI < 0 || map.width <= mapI || mapJ < 0 || map.height <= mapJ)==false ){
					f = map.floors[mapI][mapJ];
					switch(f.name){
						case "route" :	case "room":
							if( map.floors[mapI+1][mapJ].name == "wall"){	vwp.visible = true;		}
							else{	vwp.visible = false;}
							break;
					}
				}
				mapI = i - centerX + map.man.x;
				if( (mapI < 0 || map.width <= mapI || mapJ < 0 || map.height <= mapJ)==false ){
					f = map.floors[mapI][mapJ];
					switch(f.name){
						case "route" :	case "room":
							if( map.floors[mapI-1][mapJ].name == "wall"){	vwp.visible = true;		}
							break;
					}
				}
			}
		}
	}
} 

class Shadow extends Bitmap{
	public function Shadow(w:int,h:int){
		var bmd:BitmapData = new BitmapData( w,h,true );
		bmd.lock();
		var cx:int = w/2;
		var r:int = 150;
		var cy:int = h/2;
		for(var i:int = 0;i<w;i++){
			for(var j:int = 0;j<h;j++){
			var rx:int = i-cx;
			var ry:int = j-cy;
			var r2:int = rx*rx+ry*ry;
				if(r2 > r*r){
					var d:int = ( Math.sqrt(r2) - r )*1;
					if( 0xFF < d){d=0xFF}
					var color:uint = 0x01000000 * d;
				}else{	color = 0x00000000;	}
				bmd.setPixel32(i,j,color);
			}
		}
		bmd.unlock();
		super(bmd);
	}
}


class DropShadow extends BitmapData{
	public function DropShadow(){
		super( 50,50,true );
		var cx:int =25;var r:int = 20;var cy:int = 25;
		lock();
		for(var i:int = 0;i<50;i++){
			for(var j:int = 0;j<50;j++){
			var rx:int = i-cx;var ry:int = j-cy;
			var r2:int = rx*rx+ry*ry;
				if(r2 < r*r){
					var d:int = r2 * 0xA0/(r*r);
					if( 0xA0 < d){d = 0xA0}
					d = 0xA0 - d;
					var color:uint = 0x01000000 * d;
				}else{ color = 0x00000000; }
				setPixel32(i,j,color);
			}
		}
		unlock();
	}
}




//マップデータのクラス
class Map{
	public var bitmap:Bitmap;
	public var view:MapView
	public var textField:TextField = new TextField(); 
	
	public var rank:int = 0; //階層
	public var width:int;
	public var height:int;
	
	
	//マップの内容 0:壁、1:部屋 2:通路 3:アイテム 4:敵 5:自分 6:階段
	public var data:Vector.<Vector.<int>>;
	//マップに関する詳細なデータ
	public var floors:Vector.<Vector.<Floor>>;
	
	//部屋のサイズは6×6固定になります
	public static var ROOM_SIZE:int = 6;
	
	public var rooms:Vector.<Room>;//部屋のデータ
	public var routes:Vector.<Route>;
	public var enemys:Vector.<Enemy>;
	public var items:Vector.<DropItem>;//床に落ちているアイテム
	
	public var man:Man = new Man();
	
	//wとhには21以上を指定してください。
	public function Map(w:int = 50,h:int = 50){
		if(w < ROOM_SIZE *3 +2){w = ROOM_SIZE *3 +2;}
		if(h < ROOM_SIZE *3 +2){h = ROOM_SIZE *3 +2;}
		width = w;
		height = h;
		init();
	}
	
	//現在のサイズでマップを初期化
	public function init():void{
		bitmap = new Bitmap(new BitmapData( width, height, true, 0x00000000 ) );
		rank = 0;
		makeFloor();
		view = new MapView(this);
		
	}
	
	public function makeFloor():void{
		rooms = new Vector.<Room>();
		routes = new Vector.<Route>();
		enemys = new Vector.<Enemy>();
		items = new Vector.<DropItem>();
		
		data = new Vector.<Vector.<int>>(width);
		data.fixed = true;
		
		floors = new Vector.<Vector.<Floor>>(width);
		floors.fixed = true;
		
		for(var i:int=0; i<width; i++ ){
			data[i] = new Vector.<int>(height);
			data[i].fixed = true;
			
			floors[i] = new Vector.<Floor>(height);
			floors[i].fixed = true;
			for(var j:int=0; j<height; j++ ){
				data[i][j] = 0;
				floors[i][j] = new Floor(i,j,this);
				floors[i][j].wall(0);
				if( i==0 || j==0 || i==width-1 || j==height-1 ){
					floors[i][j].routeable = false;
					floors[i][j].roomable = false;
				}
			}	
		}
		if( generate() ){ update();  }
		else{  makeFloor();  }
	}
	
	//ランダムマップの生成をします
	public function generate():Boolean{
		var missCount:int = 0;
		while(missCount<10){
			if( requestRoom( 1+Math.random()*(width-ROOM_SIZE-2), 1+Math.random()*(height-ROOM_SIZE-2) ) == false){
				missCount++;
			}else{ missCount = 0; }
		}
		if(rooms.length<2){
			if(width >= ROOM_SIZE*2+3 && height >= ROOM_SIZE*2+3){ return false; }
		}else{
			var c:int = 0;
			while(connect() == false){
				var i:int = c%rooms.length;
				exit( rooms[i] );c++;
				if(c>rooms.length*100){return false;}
			}
		}
		for each(var route:Route in routes){ cutRoute(route);	}
		setParts();
		return true;
	}
	
	//指定された位置に部屋を作成を試みます
	//成功したかどうかをbooleanで返します。
	private function requestRoom(x:int,y:int):Boolean{
		if(width < ROOM_SIZE*2+3 || height < ROOM_SIZE*2+3){ return false; }
		var miss:Boolean = false;
		for(var i:int = x; i< x+ROOM_SIZE; i++){
			for(var j:int = y; j< y+ROOM_SIZE; j++){
				if( floors[i][j].roomable == false ){
					miss = true;
				}
			}
		}
		if(miss){ return false; }
		else{ makeRoom(x,y); }
		return false;
	}
	//部屋を作成します。requestRoom以外から呼び出さないでください。
	private function makeRoom(x:int,y:int):void{
		rooms.push(new Room(x,y,ROOM_SIZE,ROOM_SIZE,rooms.length,this));
		for(var i:int = x-1; i< x+ROOM_SIZE+1; i++){
			for(var j:int = y-1; j< y+ROOM_SIZE+1; j++){
				if(x <= i && i< x+ROOM_SIZE && y <= j && j < y+ROOM_SIZE ){
					data[i][j] = 1;
					floors[i][j].room(rooms.length-1);
				}else if( (x+1<=i && i<x+ROOM_SIZE-1) || (y+1<=j && j<y+ROOM_SIZE-1) ){
					floors[i][j].roomable=false;
				}else{
					floors[i][j].roomable=false;
					floors[i][j].routeable=false;
				}
			}
		}
	}
	//すべての部屋がつながってるか調べます
	private function connect():Boolean{
		var ok:Boolean = true;
		var v:Vector.<int> = rooms[0].getConnect();
		for(var i:int=0; i<rooms.length; i++){
			if(v.indexOf(i)==-1){ok=false;}
		}
		return ok;
	}
	//rに出口となる部屋をまっすぐ伸ばします。
	private function exit(r:Room):Boolean{
		var a:int = Math.random()*4;
		var c:int; var x:int; var y:int;
		var dx:int=0;
		var dy:int=0;
		switch(a){
			case 0://上に道を伸ばす
				x = r.x+1 + Math.random()*(ROOM_SIZE-2);
				y = r.y-1;
				dy = -1; 
				break;
			case 1://下に道を伸ばす
				x = r.x+1 + Math.random()*(ROOM_SIZE-2);
				y = r.y+r.height;
				dy = 1; 
				break;
			case 2://左に道を伸ばす
				x = r.x-1;
				y = r.y+1 + Math.random()*(ROOM_SIZE-2);
				dx = -1; 
				break;
			case 3://右に道を伸ばす
				x = r.x+r.width;
				y = r.y+1 + Math.random()*(ROOM_SIZE-2);
				dx = 1; 
				break;
		}
		if(floors[x][y].routeable == true){
			var route:Route = new Route(routes.length);
			route.rooms.push(r);
			c = 0; 
			while(c<height){
				if(floors[x][y].routeable == true){
					data[x][y] = 2;
					floors[x][y].route(route.index);
					route.floors.push(floors[x][y]);
					x += dx;
					y += dy;
				}else if(data[x][y]==1){
					close(dx,dy,r);
					close(-dx,-dy,rooms[floors[x][y].index]);
					rooms[ floors[x][y].index ].exits.push( route );
					r.exits.push( route );
					route.rooms.push( rooms[floors[x][y].index] );
					routes.push(route);
					break;
				}else if(data[x][y]==2){
					close(dx,dy,r);
					r.exits.push(route);
					routes[ floors[x][y].index ].connect(route);
					break;
				}else if(c>0){
					close(dx,dy,r);
					r.exits.push(route);
					routes.push(route);
					break;
				}else{
					break;
				}
				c++;
			}
		}else{
			return false;
		}
		return true;
	}
	//rの一面を出口にできなくする。
	private function close(dx:int,dy:int,r:Room):void{
		for(var i:int = r.x+dx; i< r.x+r.width+dx; i++){
			for(var j:int = r.y+dy; j< r.y+r.height+dy; j++){
				floors[i][j].routeable=false;
			}
		}
	}
	//行き止まりを消す。
	public function cutRoute(r:Route):void{
		var loop:Boolean = true;
		while(loop){
			loop = false;
			for each(var f:Floor in r.floors){
				var c:int = 0;
				var side:Floor = floors[f.x + 1][f.y];
				if( ( side.name == "route"  && side.index == r.index ) || side.name == "room"){c++;}
				side = floors[f.x - 1][f.y];
				if( ( side.name == "route"  && side.index == r.index ) || side.name == "room"){c++;}
				side = floors[f.x][f.y - 1];
				if( ( side.name == "route"  && side.index == r.index ) || side.name == "room"){c++;}
				side = floors[f.x][f.y + 1];
				if( ( side.name == "route"  && side.index == r.index ) || side.name == "room"){c++;}
				if(c == 1){
					loop = true;
					data[f.x][f.y] = 0;
					floors[f.x][f.y].wall(0);
					r.floors.splice(r.floors.indexOf(f),1);
				}
			}
		}
	} 
	//人、敵、階段、アイテムなどを設置
	private function setParts():void{
		GameUtil.setItems(this,rank);
		GameUtil.setEnemys(this,rank);
		
		//主人公は0番の部屋に配置
		var x:int = rooms[0].x + rooms[0].width * Math.random(); 
		var y:int = rooms[0].y + rooms[0].height * Math.random(); 
		data[x][y] =  5;
		man.init( x, y, this);
		
		//階段は最後のの部屋に配置
		var l:int = rooms.length-1;
		x = rooms[l].x + rooms[l].width * Math.random(); 
		y = rooms[l].y + rooms[l].height * Math.random(); 
		data[x][y] =  6;
		floors[x][y].stair();
	}
	//階段を下りる
	public function down():void{
		rank++;
		if(rank > GameData.DEPTH ){rank = 0;}
		makeFloor();
		view.floorUpdate();
	}
	
	//敵の行動などを1つ進める
	public function step():void{
		for each( var enemy:Enemy in enemys ){
			enemy.walk();
		}
		if(view.load){view.update();}
		update();
	}
	
	//textFieldから現在の状態を出力
	public function output():void{
		var str:String = "";
		var f:Floor = floors[man.x][man.y];
		
		str += "現在地:  B" + (rank+1) + "階";
		str += "  x," + man.x;
		str += "  y," + man.y;
		str += "  " + f.name + f.index +"\n";
		str += "\n近くの敵:\n";
		
		for each(var e:Enemy in enemys){
			var ef:Floor = floors[e.x][e.y];
			if(ef.name == f.name && ef.index == f.index){
				str += e.data.name;
				str += "   life:" + e.life + "/" + e.maxLife;
				str += "   walkType:" + e.data.walkType +"\n";
			}
		}
		textField.width = 400;
		textField.text = str;
	}
	
	
	
	//bitmapを更新します。
	public function update():void{
		output();
		
		var bitmapData:BitmapData = bitmap.bitmapData;
		bitmapData.lock();
		for(var i:int=0; i<width; i++ ){
			for(var j:int=0; j<height; j++ ){
				var color:uint = 0x3300FF00;
				switch(data[i][j]){
					case 0:
						color = 0x00000000; 
						break;
					case 1:
						if(floors[i][j].visit){color = 0xFF00FF00;}
						break;
					case 2:
						if(floors[i][j].visit){color = 0xFF00FF00;}
						break;
					case 3:
						if(floors[i][j].visit){color = 0xFF0000FF;}
						break;
					case 4:
						if(floors[i][j].visit){color = 0xFFFF0000;}
						break;
					case 5:
						color = 0xFFFF00FF; 
						break;
					case 6:
						if(floors[i][j].visit){color = 0xFF00FFFF;}
						break;
				}
				bitmapData.setPixel32(i,j,color);
			}
		}
		bitmapData.unlock();
	}
}



//部屋のクラス
class Room{
	public var x:int;
	public var y:int;
	public var width:int;
	public var height:int;
	public var index:int;
	public var map:Map;
	
	
	public var exits:Vector.<Route> = new Vector.<Route>();

	
	public function Room(xx:int,yy:int,w:int,h:int,i:int,m:Map):void{
		x=xx;
		y=yy;
		width=w;
		height=h;
		index=i;
		map=m;
	}
	
	
	//この部屋とつながっている部屋を返します
	public function getConnect( v:Vector.<int> = null ):Vector.<int>{
		if(v == null){v = new Vector.<int>();}
		if(v.indexOf(index)== -1){ v.push(index);}
		for each(var route:Route in exits){
			v = route.getConnect(v);
		}
		return v;
	}
	
	//この部屋を通ったことがあるところとして設定
	public function visit():void{
		for (var i:int = x; i<x+width; i++){
			for (var j:int = y; j<y+height; j++){
				map.floors[i][j].visit = true ;
			}
		}
	}
}
//道のクラス
class Route{
	//通り道{x,y,visit}
	public var floors:Vector.<Floor> = new Vector.<Floor>();
	//つながっている部屋のリスト。
	public var rooms:Vector.<Room> = new Vector.<Room>();
	public var index:int;
	public function Route(i:int){
		index = i;
	}
	//Routeを接続します。
	public function connect(r:Route):void{
		floors.concat(r.floors);
		rooms.concat(r.rooms);
		for each(var room:Room in r.rooms){
			room.exits.push(this);
		}
		for each(var floor:Floor in r.floors){
			floor.index = index;
		} 
	}
	public function getConnect( v:Vector.<int> = null ):Vector.<int>{
		for each(var room:Room in rooms){
			if(v.indexOf(room.index) == -1){ v= room.getConnect(v) }
		}	
		return v;
	}
}
class Floor{
	public var x:int;	
	public var y:int;
	public var map:Map;
	
	public var name:String="undefined";
	public var data:int=0;
	public var index:int = 0;
	public var visit:Boolean=false;
	public var routeable:Boolean=true;
	public var roomable:Boolean=true;
	public var isStair:Boolean=false;
	
	public function Floor(xx:int,yy:int,m:Map){
		x = xx;
		y = yy;
		map = m;
	}
	//この床を壁として初期化
	public function wall(i:int):void{
		name = "wall";
		index = i;
		data = 0;
		routeable = true;
		roomable = true;
	} 
	//この床を部屋として初期化
	public function room(i:int):void{
		name = "room";
		index = i;
		data = 1;
		routeable = false;
		roomable = false;
	} 
	//この床を道として初期化
	public function route(i:int):void{
		name = "route";
		index = i;
		data = 2;
		routeable = false;
		roomable = false;
	}
	
	//この床を階段にする
	public function stair():void{
		isStair = true;
		data = 6;
	} 
	
	//この床を通ったことがある場所として設定.
	public function over():void{
		if(visit == false){
			if(name == "room"){
				map.rooms[index].visit();
			}else{
				visit = true;
			}
		}
	} 
}

//床に落ちているアイテムのクラス
class DropItem{
	public var x:int = 0;
	public var y:int = 0;
	public var name:String = "item";//itemのクラス
}

//キャラクターのクラス
//キャラクターには敵や自分が含まれます。
class Charactor{
	public var alive:Boolean = true;
	public var x:int = 0;
	public var y:int = 0;
	public var map:Map;		//このキャラクターが配置されているマップ
	public var life:int = 100;
	public var maxLife:int = 100;
	public var name:String = "chara";
	public var motion:Motion;
	public var shadow:Plane = new Plane( new BitmapMaterial( new DropShadow() ) ,50,50, 4, 4);
}

//主人公のクラス
class Man extends Charactor{
	public var dx:int = 0;
	public var dy:int = 0;
	public var moving:Boolean = false;
	public function init(xx:int, yy:int, m:Map):void{
		x=xx; y=yy; map=m;
		name = "man";
		motion = new Motion(name,x,y);
		
		map.floors[x][y].over();
	}
	public function onFrame(e:Event):void{
		if(moving){move(dx,dy)}
	}
	public function onKeyDown(e:KeyboardEvent):void{
		if(e.keyCode == 	Keyboard.DOWN){ move(0,-1); }
		else if(e.keyCode == 	Keyboard.UP){ move(0,1); }
		else if(e.keyCode == 	Keyboard.LEFT){ move(-1,0); }
		else if(e.keyCode == 	Keyboard.RIGHT){ move(1,0); }
		else if(e.keyCode ==	65){ move(0,0) }
		else if(e.keyCode ==	Keyboard.SPACE && map.floors[x][y].isStair){ map.down(); }
	}
	public function move(ddx:int,ddy:int):Boolean{
		dx = ddx; dy=ddy;
		if(motion.update()){
			moving = true;
		}else{
			moving = false;
			var data:int = map.data[x+dx][y+dy];
			if( data == 0 || data == 4 ){
				return false;
			}else{
				motion.walk(x,y,x+dx,y+dy);
				map.data[x][y] = map.floors[x][y].data;
				x+=dx; y+=dy;
				map.data[x][y] = 5;
				map.floors[x][y].over();
				map.step();
			}
		}
		return moving == false;
	}
}

class Enemy extends Charactor{
	public var data:Object;
	public function Enemy(xx:int, yy:int, m:Map,n:String){
		x=xx; y=yy; map=m;
		name = n;
		data = GameData.ENEMY_DATA[n];
		life = data.life;
		maxLife = life;
		motion = new Motion(name,x,y);
	}
	public function walk():void{
		var c:int = 0;
		while(c < 6){
			switch(data.walkType){
				case "chase": 
				if(map.floors[map.man.x][map.man.y].name == "room" && map.floors[map.man.x][map.man.y].index == map.floors[x][y].index){
						if( chase() ){break;}
					}else{
						if( walkRandom() ){break;}
					}
					break;
				case "random":
					if( walkRandom() ){break;}
					break;
			}
			c++;
		}
	}
	public function walkRandom():Boolean{
		var d:int = Math.random()*2;
		var dx:int;var dy:int;
		if(d==0){
			dx = 0;
			d = Math.random()*2;
			dy = d*2-1;
		}else{
			dy = 0;
			d = Math.random()*2;
			dx = d*2-1;
		}
		return move(dx,dy);
	}
	
	public function chase():Boolean{
		var d:int = Math.random()*2;
		var dx:int;var dy:int;
		if(d==0){   if(map.man.x == x){d=1;}  }
		else{   if(map.man.y == y){d=0;}    }
		
		if(d==1){
			dx = 0;
			if(map.man.y > y){dy=1;}
			else{dy=-1}
		}else{
			dy = 0;
			if(map.man.x > x){dx=1;}
			else{dx=-1}
		}
		return move(dx,dy);
	}
	
	public function move(dx:int,dy:int):Boolean{
		if(motion.update()){
			return false;
		}else{
			var d:int = map.data[x+dx][y+dy];
			if( d == 0 || d == 2 || d == 4 || d == 5){
				return false;
			}else{
				motion.walk(x,y,x+dx,y+dy);
				map.data[x][y] = map.floors[x][y].data;
				x+=dx; y+=dy;
				map.data[x][y] = 4;
			}
		}
		return true;
	}
}

class Motion{
	//モーションが稼働しているか
	public var moving:Boolean = false;
	
	//モーションの名前
	public var name:String = "";
	public var page:int = 0;		//モーション画像の番号
	public var numPage:int = 2;	//モーション画像の数
	
	//動作主の名前
	public var parent:String;
	
	public var x:Number;
	public var y:Number;
	
	//モーションの始点
	public var startX:Number;
	public var startY:Number;
	
	//モーションの終点
	public var endX:Number;
	public var endY:Number;
	
	public var length:Number;	//モーションの継続時間(ミリ秒)
	public var time:Number;	//モーション開始からの経過時間
	
	private var startTime:Number;	//モーションを開始した時刻
	
	public function Motion(p:String,xx:Number,yy:Number){
		x=xx; y=yy; parent = p;
	}
	
	//モーションを開始します
	public function start():void{
		moving = true;
		startTime = getTimer();
		time = 0;
		x=startX;
		y=startY;
	}
	//モーションを終了します
	public function stop():void{
		moving = false;
		x=endX;
		y=endY;
	}
	//モーションの状態を更新します
	public function update():Boolean{
		if(moving){
			time = getTimer() - startTime;
			if(time > length){
				stop();
			}else{
				var def:Number = length - time;
				x = ( startX*def + endX*time )/ length ;
				y = ( startY*def + endY*time )/ length ;
			}
		}
		return moving;
	}
	
	public function walk( sx:Number,sy:Number,ex:Number,ey:Number ):void{
		startX = sx; startY = sy; 
		endX = ex; endY = ey; 
		name = "walk";
		numPage = 2;		//2枚絵
		length = 150;	//モーション時間	0.1s
		start();
	}
}









//敵、画像、アイテム、技、などのデータが収められている静的クラス
class GameData{
	public static const SWF_WIDTH:int = 465;
	public static const SWF_HEIGHT:int = 465;
	
	public static const ROOM_WIDTH:int = 5;
	public static const ROOM_HEIGHT:int = 5;
	public static const DEPTH:int = 1;
	public static const IMAGE_URL:String = "http://assets.wonderfl.net/images/related_images/e/e2/e28e/e28ec27a4090eceef922d5334823a19768f2941d";
	
	
	//画像の位置データ===========================================
	public static var IMAGE_ARRAY:Array = [
		{name:"floor",x:50,y:0,w:50,h:50},
		{name:"wall",x:0,y:0,w:50,h:50},
		{name:"staire",x:100,y:0,w:50,h:50},
		{name:"roof",x:150,y:0,w:50,h:50}
	];
	//(画像の位置データ)=============================================
	


	//各階のデータ=============================================
	public static var RANK_ARRAY:Array =[
		{//0階
			minEnemy:1,
			maxEnemy:2,
			enemy:["mosamosa","fusafusa"]
		},
		{//1階
			minEnemy:1,
			maxEnemy:2,
			enemy:["mosamosa","fusafusa"]
		}
	];
	//(各階のデータここまで)=============================================
	
	
	
	
	
	
	
	
	
	//敵のデータ==============================================
	public static var ENEMY_DATA:Object = {
		mosamosa:{//もさもさ
			name:"もさもさ",
			life:60,
			walkType:"chase"
		},
		fusafusa:{
			name:"ふさふさ",
			life:50,
			walkType:"random"
		}
	}
	//(敵のデータここまで)====================================
}

class GameUtil{
	//その階層に見合ったアイテムを配置
	public static function setItems(map:Map,rank:int):void{}

	//その階層に見合った敵を配置
	public static function setEnemys(map:Map,rank:int):void{
		for (var i:int=1;i<map.rooms.length;i++){
			var room:Room = map.rooms[i];
			var max:int = GameData.RANK_ARRAY[rank].maxEnemy;
			var min:int = GameData.RANK_ARRAY[rank].minEnemy;
			var c:int = min + (max-min+1) * Math.random();
			while(c>0){
				var x:int = room.x + room.width * Math.random(); 
				var y:int = room.y + room.height * Math.random(); 
				var e:Array = GameData.RANK_ARRAY[rank].enemy;
				var l:int = e.length*Math.random();
				var name:String = e[l];
				
				map.data[x][y] = 4;
				map.enemys.push( new Enemy(x,y,map,name) );
				c--;
			}
		}
	}
}