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作る step4-(主人公のモーションを作る)

LIVE CODING 2010/04/27    20:27-23:27
wonderflでがんばってダンジョンRPGを作ってます。
主人公モーションひとまず完成
絵は24枚
操作方法
移動:方向キー
足踏み: A
攻撃: Z
びっくり: Y
階段を下りる: 階段上でSpace
マップ
緑:部屋 または 通路
赤:敵
ピンク:主人公
水色:階段
通ったことのない場所の階段,敵は見えません
English
I make a RPG.

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

// forked from shohei909's 本気でダンジョンRPG作る step3-(マップを立体化する)
package{
    //LIVE CODING 2010/04/27    20:27-23:27
    
    //wonderflでがんばってダンジョンRPGを作ってます。
    
   
    
    
    
    
    
    
    //主人公モーションひとまず完成
    //絵は24枚
    
    
    
    
    
    
    
    
    
    
    //操作方法
    
    //移動:方向キー
    //足踏み: A
    //攻撃: Z
    //びっくり: Y
    //階段を下りる: 階段上でSpace
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    //マップ
    //    緑:部屋 または 通路
    //    赤:敵
    //    ピンク:主人公
    //    水色:階段
    //通ったことのない場所の階段,敵は見えません
    
    
    
    
    
    
    
    
    //English
    
    // I make a RPG.
    // 
    // step2:  move charactors
    
    // walk: arrow keys
    // step in place: A
    // attack: Z
    // go down stairs: Space
    
    // map
    //    green: room or passage
    //    red: Enemy
    //    pink: player
    //    light blue: staire
    

    
    
    //制作過程を残していきたいのでforkを重ねて制作してます。
    
    //PREVIOUS http://wonderfl.net/c/t3qt
    //NEXT http://wonderfl.net/c/rhcZ/
    
    //前のステップの差分は,上の[diff()]をクリックするとみることができます
    
    import flash.display.*;
    import net.hires.debug.Stats;
    
    [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 Stats() );
               
        }
    }
}
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.objects.*;
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.addChild(map.textField);
        
        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 manPlane:Plane;
    public var enemyPlanes:Vector.<Plane>;
    public var cameraTarget:DisplayObject3D;
    
    public var viewW:int = 11;
    public var viewH:int = 11;
    
    public var centerX:int = 5;
    public var centerY:int = 4;
    
    
    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,0x00000000);
            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 );
            
            manPlane = map.man.plane;
            manPlane.material = new BitmapMaterial(images["man_left_walk0"]);
            manPlane.useOwnContainer = true;
            manPlane.rotationX = -20;
            manPlane.z = -40;
            scene.addChild( manPlane );
            
            cameraTarget = new DisplayObject3D();
            camera.target = cameraTarget;
            
            cameraX = 0;
            cameraY = -200;
            camera.z = -400;
            camera.zoom = 70;
            
            load = true;
            floorUpdate();
            addEventListener(Event.ENTER_FRAME, onFrame);
    }
    
    public function onFrame(evt:Event):void{
        map.man.action();    //このイベントの呼び出しに合わせて主人公を動かす
        map.man.motion.nextFrame();
        
        for each(var e:Enemy in map.enemys){
            if(e.shadow.visible){
                e.motion.nextFrame();
                e.shadow.x = 50 * ( e.motion.x - map.man.x );
                e.shadow.y = 50 * ( e.motion.y - map.man.y )-7;
            }
        }
        

        
        manShadow.x = 50 * ( map.man.motion.x - map.man.x );
        manShadow.y = 50 * ( map.man.motion.y - map.man.y )-7;
        manPlane.x = 50 * ( map.man.motion.x - map.man.x );
        manPlane.y = 50 * ( map.man.motion.y - map.man.y )-7;
        cameraTarget.x = 50 * ( map.man.motion.x - map.man.x );
        cameraTarget.y = 50 * ( map.man.motion.y - map.man.y );
        
        if(map.man.motion.change){
             manPlane.material = new BitmapMaterial(images[ map.man.motion.toImageName() ]);
            map.textField.text = map.man.motion.page+"";
        }
        
        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, 1, 1);
    public var plane:Plane = new Plane( new BitmapMaterial() ,48,48, 1, 1);
    
}

//主人公のクラス
import flash.accessibility.Accessibility;
class Man extends Charactor{
    public var dx:int = 0;
    public var dy:int = 0;
    public var camera:Boolean = false; //カメラの中心に置くか?
    public var moving:Boolean = false;
    private var keyEvents:Vector.<KeyboardEvent>;
    public function init(xx:int, yy:int, m:Map):void{
        x=xx; y=yy; map=m;
        name = "man";
        camera = true;
        motion = new Motion(name,x,y);
        keyEvents = new Vector.<KeyboardEvent>();
        
        map.floors[x][y].over();
    }
    public function onFrame(e:Event):void{
        if(moving){move(dx,dy)}
    }
    public function onKeyDown(e:KeyboardEvent):void{
        keyEvents.push(e);
    }
    public function action():void{
        for each(var e:KeyboardEvent in keyEvents){ 
            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 ==    90){ attack(); }
            else if(e.keyCode ==    88){ surprised(); }
            else if(e.keyCode ==    Keyboard.SPACE && map.floors[x][y].isStair){ move(0,0);map.down(); }
        }
        keyEvents = new Vector.<KeyboardEvent>();
    }
    public function move(ddx:int,ddy:int):Boolean{
        if(motion.moving){
            moving = false;
        }else{
            camera = true;
            dx = ddx; dy=ddy;
            moving = true;
            var data:int = map.data[x+dx][y+dy];
            if( data == 0 || data == 4 ){
                motion.walk(x,y,x,y,2,4);
                motion.setDir(ddx,ddy);
                return false;
            }else{
                motion.walk(x,y,x+dx,y+dy,2,4);
                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;
    }
    
    public function attack():void{
        //toDo 攻撃モーション
        motion.attack(x,y,6,14);
    }
    public function surprised():void{
        //toDo 攻撃モーション
        motion.surprised(x,y,6,14);
    }
}


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.moving){
            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,2,2);
                map.data[x][y] = map.floors[x][y].data;
                x+=dx; y+=dy;
                map.data[x][y] = 4;
            }
        }
        return true;
    }
}

class Motion extends EventDispatcher{
    //モーションが稼働しているか
    public var moving:Boolean = false;
    
    //モーションの名前
    public var name:String = "stop" ;
    
    public var change:Boolean = true;        //前回の表示から画像の変化があったか?
    public var page:int = 0;        //モーション画像の番号
    public var numPage:int = 1;    //モーション画像の数
    public var interval:int = 2;    //モーション画像の変更間隔
    
    //動作主の名前
    public var parent:String;
    
    public var x:Number = 0;
    public var y:Number = 0;
    
    //モーションの始点
    public var startX:Number = 0;
    public var startY:Number = 0;
    
    //モーションの終点
    public var endX:Number = 0;
    public var endY:Number = 0;
    
    public var frameLength:int=-1;    //モーションの継続時間(フレーム)
    public var frame:int=0;    //モーション開始からの経過時間
    
    public var dir:String = "down";

    
    
    public function Motion(p:String,xx:Number,yy:Number){
        x=xx; y=yy; parent = p;
    }
    
    //モーションを開始します
    public function start():void{
        moving = true;
        x=startX;
        y=startY;        
        frame = 0;
    }
    
    //モーションを終了します
    public function stop():void{
        moving = false;
        change = true;
        frameLength = 200000;
        name = "stop";
        numPage = 1;
        frame = 0;
        x=endX;
        y=endY;
    }
    
    public function walk( sx:Number,sy:Number,ex:Number,ey:Number,p:int,l:int):void{
        startX = sx; startY = sy; 
        endX = ex; endY = ey;
        setDir(ex - sx,ey - sy);
        name = "walk";
        interval = p;        //4枚絵
        numPage = 4;        //4枚絵
        frameLength = l;    //モーション時間    0.16s
        change = true;
        if(page%2 == 0){nextPage();}
        start();
    }
    
    public function attack( sx:Number,sy:Number,p:int,l:int):void{
        startX = sx; startY = sy; 
        endX = sx; endY = sy;
        name = "attack";
        interval = p;        
        numPage = 2;        //2枚絵
        frameLength = l;    //モーション時間    0.16s
        change = true;
        start();
        page=0;
        frame=4;
    }
    
     public function surprised( sx:Number,sy:Number,p:int,l:int):void{
        startX = sx; startY = sy; 
        endX = sx; endY = sy;
        name = "surprised";
        interval = p;        
        numPage = 1;        //1枚絵
        frameLength = l;    //モーション時間    0.16s
        change = true;
        start();
        page=0;
        frame=0;
    }
   
    
    
    public function toImageName():String{
        change = false;
        var str:String = ""; 
        var p:int = page%numPage;
        if(parent == "man"){
            if(name == "walk" && (p==1||p==3) ){str = parent +"_"+ dir + "_stop0";        }
            else{str = parent  +"_"+ dir +"_"+ name + p;    }
            
        }
        return str;
    }
    public function setDir( cx:Number,cy:Number):void{
        var d:Number = Math.atan2(cx, cy);
        if(cx==0 &&  cy==0){  }
        else if(-3/4*Math.PI<=d && d<=-1/4*Math.PI && 0>=cx){ dir="left"; }
        else if(-1/4*Math.PI<d && d<1/4*Math.PI) { dir="up"; }
        else if(1/4*Math.PI<=d && d<=3/4*Math.PI){ dir="right"; }
        else { dir="down"; };
    }
    public function nextFrame():void{
        if(frame % interval == 0){ nextPage(); }
        frame++;
        if(moving){
            if(frame == frameLength){
                stop();
            }else{
                var f:int =  frame%frameLength;
                var def:Number = frameLength - f;
                x = ( startX*def + endX*f )/ frameLength ;
                y = ( startY*def + endY*f )/ frameLength ;
            }
        }
    }
    //nextPage
    public function nextPage():void{
        page++;
        change = true;
    }
    //x,yを更新する
    public function update():void{
        page++;
        change = true;
    }
}



//敵、画像、アイテム、技、などのデータが収められている静的クラス
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/6/6d/6d9c/6d9cc63c6b7fcfd0d81ce6915dadb1e444317d38";
    
    //画像の位置データ===========================================
    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},
        {name:"man_left_walk0",    y:50,x:0,w:24,h:24},
        {name:"man_left_walk2",    y:50,x:25,w:24,h:24},
        {name:"man_right_walk0",y:50,x:50,w:24,h:24},
        {name:"man_right_walk2",y:50,x:75,w:24,h:24},
        {name:"man_down_walk0",    y:50,x:100,w:24,h:24},
        {name:"man_down_walk2",    y:50,x:125,w:24,h:24},
        {name:"man_up_walk0",    y:50,x:150,w:24,h:24},
        {name:"man_up_walk2",    y:50,x:175,w:24,h:24},
        {name:"man_left_stop0",    y:75,x:0,w:24,h:24},
        {name:"man_right_stop0",y:75,x:25,w:24,h:24},
        {name:"man_down_stop0",    y:75,x:50,w:24,h:24},
        {name:"man_up_stop0",    y:75,x:75,w:24,h:24},
        {name:"man_left_attack1",    y:75,x:100,w:24,h:24},
        {name:"man_right_attack1",    y:75,x:125,w:24,h:24},
        {name:"man_down_attack1",    y:75,x:150,w:24,h:24},
        {name:"man_up_attack1",        y:75,x:175,w:24,h:24},
        {name:"man_left_attack0",    y:100,x:100,w:24,h:24},
        {name:"man_right_attack0",    y:100,x:125,w:24,h:24},
        {name:"man_down_attack0",    y:100,x:150,w:24,h:24},
        {name:"man_up_attack0",        y:100,x:175,w:24,h:24},
        {name:"man_left_surprised0",    y:100,x:0,w:24,h:24},
        {name:"man_right_surprised0",    y:100,x:25,w:24,h:24},
        {name:"man_down_surprised0",    y:100,x:50,w:24,h:24},
        {name:"man_up_surprised0",    y:100,x:75,w:24,h:24}
    ];
    //(画像の位置データ)=============================================
    


    //各階のデータ=============================================
    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--;
            }
        }
    }
}