※現在、「wonderfl build flash online」求人コンテンツ制作に関してのアンケートを実施中です!みなさまのお力添えを頂いて、続々とアンケート結果が集まっていますが、まだまだ募集しております。ご協力のほど、どうぞよろしくお願いいたします!

wonderfl運営事務局
→アンケートページ(※ログインしてからお答えいただけるようになっています。)

 notice: Flash editor updated! Join the development! Thanks to MiniBuilder


forked from : osamX's ワンダフルクエスト [diff(405)]

FORKED
  1. // forked from rsakane's ワンダフルクエスト(不思議のダンジョン風に)
  2. // forked from osamX's ワンダフルクエスト
  3. // forked from nengafl's nengafl
  4. /*
  5.  * [遊び方]
  6.  * はじめに、マップをクリックして...
  7.  * ↑ , w :    上に移動
  8.  * ↓ , s :    下に移動
  9.  * ← , a :    左に移動
  10.  * → , d :    右に移動
  11.  * 
  12.  * マップは毎回ランダムに生成されます。
  13.  * 一階層しか探索できません。
  14.  * やり直したいときはリロードしてください。
  15.  * 
  16.  * マップチップ素材
  17.  * http://www.tekepon.net/fsm/
  18.  * 
  19.  * ダンジョン生成参考
  20.  * http://racanhack.sourceforge.jp/rhdoc/index.html
  21.  */
  22. package 
  23. {
  24.     import flash.display.*;
  25.     import flash.events.*;
  26.     import flash.geom.Matrix;
  27.     import flash.geom.Point;
  28.     import flash.geom.Rectangle;
  29.     import flash.net.URLRequest;
  30.     import flash.system.LoaderContext;
  31.     import frocessing.math.Random;
  32.     [SWF(width="465", height="465", frameRate="30", backgroundColor="0x000000")]
  33.     public class Main extends Sprite 
  34.     {
  35.         private const SIZE:Number = 465;//ステージの大きさ
  36.         private const SCALE:Number = 4.0//勇者やフィールドの拡大率
  37.         private const SPEED:Number = 6;    //勇者が歩くスピード FLDSIZEの約数にしてください
  38.         private const MAPSIZE:uint = 50;//マップの横・縦のマスの個数
  39.         private const FLDSIZE:uint = 72;//フィールド(マップ上の1マス)の横・縦のドット数
  40.         
  41.         private const SCALE2:int = 8;
  42.         private var circle:Sprite;
  43.         private var bd:BitmapData;
  44.         private var image:BitmapData;
  45.         private var dark:Bitmap;
  46.         private var bitmap:Bitmap;
  47.         
  48.         private var yuusha:Yuusha;        //勇者
  49.         private var yuushaPos:Point;    //勇者のマップ上の座標
  50.         private var map:Sprite;            //マップ本体 これを動かして勇者が移動しているように見せる
  51.         private var bMapData:Array = [];//フィールドが障害物か否かを記憶
  52.         private var frameCount:Number = 0;    //onEnterFrameで使用
  53.         private var keyFlags:Array = [falsefalsefalsefalse]; //下上左右のキーが押されているか
  54.         private var walkDirection:int = 4;    //歩いていく方向 (0~3:下上左右  4:止)
  55.         private var loaded:int = 0;        //読み込み完了した画像の個数
  56.         private var isInit:Boolean = false;    //初期化されているか onEnterFrameで使用
  57.         private var prgSpr:Sprite;        //ロード画面表示用
  58.         
  59.         /**-----------------------------------------------------
  60.          * マップの1マス(フィールド)のリストです。
  61.          * ここをいじると好きな画像をマップ上に貼ることができます。
  62.          * 画像のサイズは、基本的に16*16ピクセルです。
  63.          * 形式はjpeg,gif,pngのどれかにしてください。
  64.          * Twitterのアイコン画像取得は、こちらのAPIを使わせてもらってます。
  65.          * http://usericons.relucks.org/
  66.          * ----------------------------------------------------- */
  67.         private const fieldList:Array = [
  68.             new Field(32 * 532 * 6true),
  69.             new Field(032 * 6false),
  70.             new Field(032 * 6false),
  71.         ];
  72.         
  73.         /**-----------------------------------------------------
  74.          * マップのデータ(ここが木で、あそこが芝生で...ってやつ)が入ってます。
  75.          * ここをいじると、マップが変わります。上のfieldListのコメント参照。
  76.          * ----------------------------------------------------- */
  77.         private var mapData:Array;
  78.         
  79.         /**-----------------------------------------------------
  80.          * コンストラクタ。 ここが最初に処理されます。
  81.          * ----------------------------------------------------- */
  82.         public function Main():void 
  83.         {    
  84.             var loader:Loader = new Loader();
  85.             loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
  86.             loader.load(new URLRequest("http://assets.wonderfl.net/images/related_images/a/af/affb/affbae7b9d9ae1f2a19c182ef6584acecbfb833a"), new LoaderContext(true));
  87.         }
  88.         
  89.         private function initHandler(event:Event):void
  90.         {
  91.             var loader:Loader = event.currentTarget.loader;
  92.             image = new BitmapData(loader.width, loader.height, false);
  93.             image.draw(loader);
  94.             
  95.             mapData = Map.init(MAPSIZE, MAPSIZE);
  96.             
  97.             prgSpr = new Sprite();//ロード画面
  98.             addChild(prgSpr);
  99.             
  100.             createMap();            //マップを作る
  101.             
  102.             addEventListener(Event.ENTER_FRAME, onEnterFrame);//イベントリスナーの登録
  103.             
  104.             yuusha = new Yuusha();    //勇者を作る
  105.             yuusha.scaleX = yuusha.scaleY = SCALE;    //勇者を拡大表示
  106.             yuusha.x = yuusha.y = (SIZE-FLDSIZE)/2//中央に配置
  107.             
  108.             var points:Array = new Array();
  109.             for (var y:int = 0; y < MAPSIZE; y++)
  110.             {
  111.                 for (var x:int = 0; x < MAPSIZE; x++)
  112.                 {
  113.                     if (mapData[y][x] != Status.WALL) points.push(new Point(x, y)); 
  114.                 }
  115.             }
  116.             points = Random.shake(points);
  117.             yuushaPos = new Point(points[0].x * FLDSIZE, points[0].y * FLDSIZE);//勇者初期位置
  118.             moveMap(yuushaPos);        //マップ移動
  119.         }
  120.         
  121.         /**-----------------------------------------------------
  122.          * 毎フレームの処理。
  123.          * ----------------------------------------------------- */
  124.         private function onEnterFrame(event:Event):void {
  125.             
  126.             //画像読み込み完了後 1回だけ処理
  127.             if (!isInit) {
  128.                 removeChild(prgSpr);//ロード画面非表示
  129.                 prgSpr = null;
  130.                 stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);    //イベントリスナーの登録
  131.                 stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);        //イベントリスナーの登録
  132.                 addChild(map);        //マップ表示
  133.                 addChild(yuusha);    //勇者表示
  134.                 isInit = true;
  135.                 
  136.                 var matrix:Matrix = new Matrix();
  137.                 matrix.createGradientBox(1401400, -70, -70);
  138.                 
  139.                 circle = new Sprite();
  140.                 circle.graphics.beginGradientFill("radial", [0xFFFFFF, 0x0], [0.00.5], [0255], matrix);
  141.                 circle.graphics.drawCircle(0070);
  142.                 circle.graphics.endFill();
  143.                 
  144.                 matrix = new Matrix();
  145.                 matrix.translate(232232);
  146.                 
  147.                 bd = new BitmapData(465465true, 0x0);
  148.                 dark = new Bitmap(bd);
  149.                 dark.alpha = 0.0;
  150.                 bd.draw(circle, matrix);
  151.                 bd.threshold(bd, bd.rect, new Point(), "==", 0x0, 0x7F000000, 0xFFFFFF);
  152.                 addChild(dark);
  153.                 
  154.                 bd = new BitmapData(MAPSIZE, MAPSIZE, true, 0x0);
  155.                 bitmap = new Bitmap(bd);
  156.                 bitmap.scaleX = bitmap.scaleY = SCALE2;
  157.                 bitmap.x = (465 - bitmap.width) / 2;
  158.                 bitmap.y = (465 - bitmap.height) / 2;
  159.                 addChild(bitmap);
  160.                 
  161.                 circle = new Sprite();
  162.                 circle.graphics.beginFill(0xFFFFFF);
  163.                 circle.graphics.drawCircle(444);
  164.                 circle.graphics.endFill();
  165.                 addChild(circle);
  166.             }
  167.             
  168.             if (bitmap)
  169.             {
  170.                 circle.x = bitmap.x + yuushaPos.x / 9;
  171.                 circle.y = bitmap.y + yuushaPos.y / 9;
  172.             }
  173.             
  174.             var px:int = (circle.x - bitmap.x) / SCALE2;
  175.             var py:int = (circle.y - bitmap.y) / SCALE2;
  176.             
  177.             if (mapData[py][px] == Status.ROOM)
  178.             {
  179.                 dark.alpha = 0.0;
  180.                 if (bd.getPixel(px, py) == 0x0)
  181.                 {
  182.                     fill(py, px);
  183.                 }
  184.             }
  185.             else
  186.             {
  187.                 dark.alpha = 1.0;
  188.                 bd.setPixel32(px, py, 0x44FFFFFF);
  189.             }
  190.             
  191.             //15フレーム毎に処理する
  192.             if (frameCount++ > 10) {
  193.                 frameCount = 0;
  194.                 yuusha.walk();
  195.             }
  196.             
  197.             //マップ(勇者)をどの方向に動かすか判定
  198.             if (yuushaPos.x % FLDSIZE == 0 && yuushaPos.y % FLDSIZE == 0) {
  199.                 var mapPosX:int = int(yuushaPos.x / FLDSIZE), mapPosY:int = int(yuushaPos.y / FLDSIZE);
  200.                 walkDirection = 4;         //止まる
  201.                 switch(true) {
  202.                     case keyFlags[0]:    //下
  203.                         if(yuushaPos.y < (MAPSIZE-1)*FLDSIZE && !bMapData[mapPosY+1][mapPosX]) walkDirection=0;
  204.                         yuusha.changeDirection(0);
  205.                         break;
  206.                     case keyFlags[1]:    //上
  207.                         if(yuushaPos.y > 0 && !bMapData[mapPosY-1][mapPosX]) walkDirection=1;
  208.                         yuusha.changeDirection(1);
  209.                         break;
  210.                     case keyFlags[2]:    //左
  211.                         if(yuushaPos.x > 0 && !bMapData[mapPosY][mapPosX-1]) walkDirection=2;
  212.                         yuusha.changeDirection(2);
  213.                         break;
  214.                     case keyFlags[3]:    //右
  215.                         if(yuushaPos.x < (MAPSIZE-1)*FLDSIZE && !bMapData[mapPosY][mapPosX+1]) walkDirection=3;
  216.                         yuusha.changeDirection(3);
  217.                         break;
  218.                 }
  219.             }
  220.             
  221.             //次のマスまで自動的に勇者を歩かせる
  222.             switch(walkDirection) {
  223.                 case 0:
  224.                     yuushaPos.y += SPEED;
  225.                     break;
  226.                 case 1:
  227.                     yuushaPos.y -= SPEED;
  228.                     break;
  229.                 case 2:
  230.                     yuushaPos.x -= SPEED;
  231.                     break;
  232.                 case 3:
  233.                     yuushaPos.x += SPEED;
  234.                     break;
  235.             }
  236.             if (walkDirection < 4) moveMap(yuushaPos);
  237.         }
  238.         
  239.         /**-----------------------------------------------------
  240.          * キーボードのキーが押された時の処理。
  241.          * ----------------------------------------------------- */
  242.         private function onKeyDown(event:KeyboardEvent):void {
  243.             switch(event.keyCode) {
  244.                 case 40case 83:    //↓ s
  245.                     keyFlags[0] = true;
  246.             }
  247.             switch(event.keyCode) {
  248.                 case 38case 87:    //↑ w
  249.                     keyFlags[1] = true;
  250.             }
  251.             switch(event.keyCode) {
  252.                 case 37case 65:    //← a
  253.                     keyFlags[2] = true;
  254.             }
  255.             switch(event.keyCode) {
  256.                 case 39case 68:    //→ d
  257.                     keyFlags[3] = true;
  258.             }
  259.         }
  260.         
  261.         /**-----------------------------------------------------
  262.          * キーボードのキーが離された時の処理。
  263.          * ----------------------------------------------------- */
  264.         private function onKeyUp(event:KeyboardEvent):void {
  265.             switch(event.keyCode) {
  266.                 case 40case 83:    //↓ s
  267.                     keyFlags[0] = false;
  268.             }
  269.             switch(event.keyCode) {
  270.                 case 38case 87:    //↑ w
  271.                     keyFlags[1] = false;
  272.             }
  273.             switch(event.keyCode) {
  274.                 case 37case 65:    //← a
  275.                     keyFlags[2] = false;
  276.             }
  277.             switch(event.keyCode) {
  278.                 case 39case 68:    //→ d
  279.                     keyFlags[3] = false;
  280.             }
  281.         }
  282.         
  283.         /**-----------------------------------------------------
  284.          * マップを作ります。
  285.          * ----------------------------------------------------- */
  286.         private function createMap():void {
  287.             map = new Sprite();
  288.             for (var k:uint = 0; k < MAPSIZE; k++) bMapData[k] = []; //bMapDataを2次元配列にする
  289.             
  290.             var bd:BitmapData = new BitmapData(MAPSIZE * FLDSIZE, MAPSIZE * FLDSIZE);
  291.             var bitmap:Bitmap = new Bitmap(bd);
  292.             
  293.             for (var j:uint = 0; j < MAPSIZE; j++) {
  294.                 for (var i:uint = 0; i < MAPSIZE; i++) {
  295.                     var field:Field = fieldList[mapData[j][i]];
  296.                     
  297.                     if (field.isObstacle) bd.copyPixels(image, new Rectangle(field.x, field.y, 3232), new Point(32 * i, 32 * j));
  298.                     else bd.copyPixels(image, new Rectangle(field.x, (Math.random() < 0.1) ? field.y + 32 : field.y, 3232), new Point(32 * i, 32 * j));
  299.                     bMapData[j][i] = field.isObstacle;
  300.                 }
  301.             }
  302.             bitmap.scaleX = bitmap.scaleY = FLDSIZE / 32;
  303.             map.addChild(bitmap);
  304.         }
  305.         
  306.         /**-----------------------------------------------------
  307.          * マップの座標計算。
  308.          * ----------------------------------------------------- */
  309.         private function moveMap(pos:Point):void {
  310.             map.x = (SIZE-FLDSIZE)/2 - yuushaPos.x;
  311.             map.y = (SIZE-FLDSIZE)/2 - yuushaPos.y;
  312.         }
  313.         
  314.         /**-----------------------------------------------------
  315.          * ロード画面を描く。
  316.          * ----------------------------------------------------- */
  317.         private function drawPrg():void {
  318.             var side:Number = SIZE / MAPSIZE,
  319.                 yy:int = int(loaded / MAPSIZE),
  320.                 xx:int = loaded - yy * MAPSIZE,
  321.                 max:int = MAPSIZE;
  322.             prgSpr.graphics.clear();
  323.             prgSpr.graphics.beginFill(0xFFFFFF);
  324.             prgSpr.graphics.drawRect(00, SIZE, yy * side);
  325.             if(yy%2)prgSpr.graphics.drawRect((MAPSIZE-xx)*side, yy*side, SIZE, side);
  326.             else    prgSpr.graphics.drawRect(0, yy*side, xx*side, side);
  327.             prgSpr.graphics.endFill();
  328.         }
  329.         
  330.         private function fill(py:int, px:int):void
  331.         {
  332.             bd.setPixel32(px, py, 0x44FFFFFF);
  333.             
  334.             if (mapData[py][px] == Status.CORRIDOR) return;
  335.             
  336.             if (0 <= px - 1 && mapData[py][px - 1] != Status.WALL && bd.getPixel(px - 1, py) == 0x0 && mapData[py][px - 1] != Status.WALL) fill(py, px - 1);
  337.             if (px + 1 < MAPSIZE && mapData[py][px + 1] != Status.WALL && bd.getPixel(px + 1, py) == 0x0 && mapData[py][px + 1] != Status.WALL) fill(py, px + 1);
  338.             if (0 <= py - 1 && mapData[py - 1][px] != Status.WALL && bd.getPixel(px, py - 1) == 0x0 && mapData[py - 1][px] != Status.WALL) fill(py - 1, px);
  339.             if (py + 1 < MAPSIZE && mapData[py + 1][px] != Status.WALL && bd.getPixel(px, py + 1) == 0x0 && mapData[py + 1][px] != Status.WALL) fill(py + 1, px);
  340.         }
  341.     }
  342. }
  343. import flash.display.Sprite;
  344. import flash.display.Loader;
  345. import flash.net.URLRequest;
  346. import flash.system.LoaderContext;
  347. class Status
  348. {
  349.     public static const WALL:int = 0;
  350.     public static const ROOM:int = 1;
  351.     public static const CORRIDOR:int = 2;
  352. }
  353. /**-----------------------------------------------------
  354.  * 勇者クラスです。勇者を作ったり、足踏させたり、向きを変えたりします。
  355.  * ----------------------------------------------------- */
  356. class Yuusha  extends Sprite {
  357.     public var direction:int = 0;        //向き (0:前 1:後 2:左 3:右)
  358.     private var walkFlag:Boolean = true;//足踏み用
  359.     private var yuushaImages:Array = [];//勇者の画像集
  360.     
  361.     /**-----------------------------------------------------
  362.      * コンストラクタ。
  363.      * ----------------------------------------------------- */
  364.     public function Yuusha():void {
  365.         for (var i:uint = 0; i < 8; i++) {
  366.             var loader:Loader = new Loader();
  367.             loader.load(new URLRequest(ImageURL[i]), new LoaderContext(true));
  368.             yuushaImages.push(loader);
  369.             if(i) yuushaImages[i].visible = false;
  370.             addChild(yuushaImages[i]);
  371.         }
  372.     }
  373.     
  374.     /**-----------------------------------------------------
  375.      * 勇者の画像のURLリスト
  376.      * ----------------------------------------------------- */
  377.     private const ImageURL:Array = [
  378.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaF1.png",    //前向き1
  379.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaF2.png",    //前向き2
  380.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaB1.png",    //後ろ向き1
  381.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaB2.png",    //後ろ向き2
  382.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaL1.png",    //左向き1
  383.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaL2.png",    //左向き2
  384.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaR1.png",    //右向き1
  385.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaR2.png"        //右向き2
  386.     ];
  387.     
  388.     /**-----------------------------------------------------
  389.      * 足踏みさせます。
  390.      * ----------------------------------------------------- */
  391.     public function walk():void {
  392.         walkFlag = !walkFlag;
  393.         for (var i:uint = 0; i < 8; i++) {
  394.             if (i == 2*direction+int(walkFlag)) yuushaImages[i].visible = true;
  395.             else yuushaImages[i].visible = false;
  396.         }
  397.     }
  398.     
  399.     /**-----------------------------------------------------
  400.      * 向きを変更します。
  401.      * numは勇者の向きを表します。(0~3)
  402.      * ----------------------------------------------------- */
  403.     public function changeDirection(num:int):void {
  404.         direction = num;
  405.         for (var i:uint = 0; i < 8; i++) {
  406.             if (i == 2*direction+int(walkFlag)) yuushaImages[i].visible = true;
  407.             else yuushaImages[i].visible = false;
  408.         }
  409.     }
  410. }
  411. /**-----------------------------------------------------
  412.  * Fieldクラスです。画像のURLと、そのフィールドが障害物か否かを保存します。
  413.  * ----------------------------------------------------- */
  414. class Field {
  415.     public var x:int;
  416.     public var y:int;
  417.     public var isObstacle:Boolean;    //障害物か否か (true:障害物  false:障害物じゃない(歩ける))
  418.     
  419.     public function Field(x:int, y:int, b:Boolean = false):void {
  420.         this.x = x;
  421.         this.y = y;
  422.         isObstacle = b;
  423.     }
  424. }
  425. class Map
  426. {
  427.     private static var WIDTH:int;
  428.     private static var HEIGHT:int;
  429.     private static const MARGIN:int = 8;
  430.     
  431.     private static var dungeon:Array;
  432.     
  433.     public static function init(width:int, height:int):Array
  434.     {
  435.         WIDTH = width;
  436.         HEIGHT = height;
  437.         
  438.         dungeon = new Array(HEIGHT).map(function(...a):* { return new Array(WIDTH).map(function(...a):* { return Status.WALL; } ) } );
  439.         
  440.         var partitions:Array = split(new Rect(00, WIDTH - 1, HEIGHT - 1));
  441.         var rooms:Array = partitions.map(makeRoom);
  442.         makeCorridor(partitions, rooms);
  443.         rooms.map(fill);
  444.         
  445.         return dungeon;
  446.     }
  447.     
  448.     // Math.floor(value / 2)
  449.     private static function half(value:int):int
  450.     {
  451.         return value >> 1;
  452.     }
  453.     
  454.     // 領域の中から適当に部屋を作る
  455.     private static function makeRoom(src:Rect, ...a):Rect
  456.     {
  457.         var dest:Rect = new Rect();
  458.         dest.left     = src.left      + randomRange(2, half(src.right  - src.left) - 0); // -1
  459.         dest.top     = src.top      + randomRange(2, half(src.bottom - src.top)  - 0);
  460.         dest.right  = src.right  - randomRange(2, half(src.right  - src.left) - 0);
  461.         dest.bottom = src.bottom - randomRange(2, half(src.bottom - src.top)  - 0);
  462.         
  463.         return dest;
  464.     }
  465.     
  466.     // min以上、max未満のランダム値を生成
  467.     private static function randomRange(min:int, max:int):int
  468.     {
  469.         if (min > max) throw new Error("min = " + min + " : max = " + max);
  470.         else if (min == max) return min;
  471.         else
  472.         {
  473.             var value:int = Math.floor(Math.random() * (max - min)) + min;
  474.             return value;
  475.         }
  476.     }
  477.     
  478.     // 塗る。部屋、通路用
  479.     private static function fill(rect:Rect, i:int = -1, array:Array = null):void
  480.     {
  481.         var minY:int = Math.min(rect.top, rect.bottom);
  482.         var maxY:int = Math.max(rect.top, rect.bottom);
  483.         
  484.         var minX:int = Math.min(rect.left, rect.right);
  485.         var maxX:int = Math.max(rect.left, rect.right);
  486.         
  487.         for (var y:int = minY; y <= maxY; y++)
  488.         {
  489.             for (var x:int = minX; x <= maxX; x++)
  490.             {
  491.                 if (i != -1) dungeon[y][x] = Status.ROOM;
  492.                 else dungeon[y][x] = Status.CORRIDOR;
  493.             }
  494.         }
  495.     }
  496.     
  497.     // 多次元配列を一次元配列に
  498.     private static function flatten(array:Array):Array
  499.     {
  500.         var src:Array = array.slice();     // 渡された配列のコピー
  501.         var dest:Array = new Array();    // フラットにした返却用配列
  502.      
  503.         while (true)
  504.         {
  505.             var element:* = src.shift(); // 配列から一つだけ値を取り出す
  506.      
  507.             if (element == undefinedbreak// もう配列には要素が無いので終了 
  508.             else if (element is Array) src = src.concat(element); // 要素が配列なら、要素 + srcという形に変換する
  509.             else dest.push(element); // 要素が配列以外なら返却用配列に追加
  510.         }
  511.      
  512.         return dest;
  513.     }
  514.     
  515.     // 通路作成
  516.     private static function makeCorridor(partitions:Array, rooms:Array):void
  517.     {
  518.         var list:Array = new Array();
  519.         
  520.         // 各部屋のペア
  521.         for (var i:int = 0; i < partitions.length - 1; i++)
  522.         {
  523.             list.push([i, i + 1]);
  524.         }
  525.         
  526.         // 一本道にならないように
  527.         for (i = 0; i < partitions.length; i++)
  528.         {
  529.             for (var j:int = i + 1; j < partitions.length; j++)
  530.             {
  531.                 if (randomRange(04) == 0)
  532.                 {
  533.                     if (partitions[i].left == partitions[j].right ||
  534.                         partitions[i].right == partitions[j].left ||
  535.                         partitions[i].top == partitions[j].bottom ||
  536.                         partitions[i].bottom == partitions[j].top)
  537.                     {
  538.                         list.push([i, j]);
  539.                     }
  540.                 }
  541.             }
  542.         }
  543.         
  544.         list.forEach
  545.         (
  546.             function(i:Array, ...a):void
  547.             {
  548.                 connect(partitions[i[0]], partitions[i[1]], rooms[i[0]], rooms[i[1]]);
  549.             }
  550.         );
  551.     }
  552.     
  553.     // 部屋と部屋を繋げる
  554.     private static function connect(p0:Rect, p1:Rect, r0:Rect, r1:Rect):void
  555.     {
  556.         var a:int;
  557.         var b:int;
  558.         
  559.         // 枠Aの下側と枠Bの上側が同じ位置だったら横に分割した事になる
  560.         if (p0.bottom == p1.top)
  561.         {
  562.             // 部屋のどこから通路を出すかを決める
  563.             a = randomRange(r0.left, r0.right);
  564.             b = randomRange(r1.left, r1.right);
  565.             
  566.             fill(new Rect(a, half(p0.top + p0.bottom), a, p0.bottom));
  567.             fill(new Rect(b, half(p1.top + p1.bottom), b, p1.top));
  568.             fill(new Rect(a, p0.bottom, b, p0.bottom));
  569.         }
  570.         // 縦に分割している場合の処理
  571.         else
  572.         {
  573.             // 部屋のどこから通路を出すかを決める
  574.             a = randomRange(r0.top, r0.bottom);
  575.             b = randomRange(r1.top, r1.bottom);
  576.             
  577.             fill(new Rect(half(p0.left + p0.right), a, p0.right, a));
  578.             fill(new Rect(half(p1.left + p1.right), b, p1.left, b));
  579.             fill(new Rect(p0.right, a, p0.right, b));
  580.         }
  581.     }
  582.     
  583.     // 領域分割
  584.     private static function split(rect:Rect, ...a):Array
  585.     {
  586.         if ((rect.right  - rect.left < MARGIN * 2) ||
  587.             (rect.bottom - rect.top < MARGIN * 2))
  588.         {
  589.             return [rect];
  590.         }
  591.         else
  592.         {
  593.             var rectA:Rect;
  594.             var rectB:Rect;
  595.             
  596.             // 1/2の確率で横か縦に分割
  597.             if (randomRange(02) == 0)
  598.             {
  599.                 // 横に分割
  600.                 
  601.                 var height:int = randomRange(rect.top + MARGIN, rect.bottom - MARGIN);
  602.                 
  603.                 rectA = new Rect(rect.left, rect.top, rect.right, height);
  604.                 rectB = new Rect(rect.left, height, rect.right, rect.bottom);
  605.             }
  606.             else
  607.             {
  608.                 // 縦に分割
  609.                 
  610.                 var width:int = randomRange(rect.left + MARGIN, rect.right - MARGIN);
  611.                 
  612.                 rectA = new Rect(rect.left, rect.top, width, rect.bottom);
  613.                 rectB = new Rect(width, rect.top, rect.right, rect.bottom);
  614.             }
  615.             
  616.             return flatten([rectA, rectB].map(split));
  617.         }
  618.     }
  619. }
  620. // 標準で付いてるRectangleだとコンストラクタで右下のPointが指定できないから使いづらい
  621. class Rect
  622. {
  623.     public var left:int;
  624.     public var right:int;
  625.     public var top:int;
  626.     public var bottom:int;
  627.     
  628.     public function Rect(left:int = 0, top:int = 0, right:int = 0, bottom:int = 0):void
  629.     {
  630.         this.left = left;
  631.         this.top = top;
  632.         this.right = right;
  633.         this.bottom = bottom;
  634.     }
  635. }
noswf
  1. // forked from rsakane's ワンダフルクエスト(不思議のダンジョン風に)
  2. // forked from osamX's ワンダフルクエスト
  3. // forked from nengafl's nengafl
  4. /*
  5.  * [遊び方]
  6.  * はじめに、マップをクリックして...
  7.  * ↑ , w :    上に移動
  8.  * ↓ , s :    下に移動
  9.  * ← , a :    左に移動
  10.  * → , d :    右に移動
  11.  * 
  12.  * マップは毎回ランダムに生成されます。
  13.  * 一階層しか探索できません。
  14.  * やり直したいときはリロードしてください。
  15.  * 
  16.  * マップチップ素材
  17.  * http://www.tekepon.net/fsm/
  18.  * 
  19.  * ダンジョン生成参考
  20.  * http://racanhack.sourceforge.jp/rhdoc/index.html
  21.  */
  22. package 
  23. {
  24.     import flash.display.*;
  25.     import flash.events.*;
  26.     import flash.geom.Matrix;
  27.     import flash.geom.Point;
  28.     import flash.geom.Rectangle;
  29.     import flash.net.URLRequest;
  30.     import flash.system.LoaderContext;
  31.     import frocessing.math.Random;
  32.     [SWF(width="465", height="465", frameRate="30", backgroundColor="0x000000")]
  33.     public class Main extends Sprite 
  34.     {
  35.         private const SIZE:Number = 465;//ステージの大きさ
  36.         private const SCALE:Number = 4.0//勇者やフィールドの拡大率
  37.         private const SPEED:Number =9;    //勇者が歩くスピード FLDSIZEの約数にしてください
  38.         private const MAPSIZE:uint = 50;//マップの横・縦のマスの個数
  39.         private const FLDSIZE:uint = 72;//フィールド(マップ上の1マス)の横・縦のドット数
  40.         
  41.         private const SCALE2:int = 8;
  42.         private var circle:Sprite;
  43.         private var bd:BitmapData;
  44.         private var image:BitmapData;
  45.         private var dark:Bitmap;
  46.         private var bitmap:Bitmap;
  47.         
  48.         private var yuusha:Yuusha;        //勇者
  49.         private var yuushaPos:Point;    //勇者のマップ上の座標
  50.         private var map:Sprite;            //マップ本体 これを動かして勇者が移動しているように見せる
  51.         private var bMapData:Array = [];//フィールドが障害物か否かを記憶
  52.         private var frameCount:Number = 0;    //onEnterFrameで使用
  53.         private var keyFlags:Array = [falsefalsefalsefalse]; //下上左右のキーが押されているか
  54.         private var walkDirection:int = 4;    //歩いていく方向 (0~3:下上左右  4:止)
  55.         private var loaded:int = 0;        //読み込み完了した画像の個数
  56.         private var isInit:Boolean = false;    //初期化されているか onEnterFrameで使用
  57.         private var prgSpr:Sprite;        //ロード画面表示用
  58.         
  59.         /**-----------------------------------------------------
  60.          * マップの1マス(フィールド)のリストです。
  61.          * ここをいじると好きな画像をマップ上に貼ることができます。
  62.          * 画像のサイズは、基本的に16*16ピクセルです。
  63.          * 形式はjpeg,gif,pngのどれかにしてください。
  64.          * Twitterのアイコン画像取得は、こちらのAPIを使わせてもらってます。
  65.          * http://usericons.relucks.org/
  66.          * ----------------------------------------------------- */
  67.         private const fieldList:Array = [
  68.             new Field(32 * 532 * 6true),
  69.             new Field(032 * 6false),
  70.             new Field(032 * 6false),
  71.         ];
  72.         
  73.         /**-----------------------------------------------------
  74.          * マップのデータ(ここが木で、あそこが芝生で...ってやつ)が入ってます。
  75.          * ここをいじると、マップが変わります。上のfieldListのコメント参照。
  76.          * ----------------------------------------------------- */
  77.         private var mapData:Array;
  78.         
  79.         /**-----------------------------------------------------
  80.          * コンストラクタ。 ここが最初に処理されます。
  81.          * ----------------------------------------------------- */
  82.         public function Main():void 
  83.         {    
  84.             var loader:Loader = new Loader();
  85.             loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
  86.             loader.load(new URLRequest("http://assets.wonderfl.net/images/related_images/a/af/affb/affbae7b9d9ae1f2a19c182ef6584acecbfb833a"), new LoaderContext(true));
  87.         }
  88.         
  89.         private function initHandler(event:Event):void
  90.         {
  91.             var loader:Loader = event.currentTarget.loader;
  92.             image = new BitmapData(loader.width, loader.height, false);
  93.             image.draw(loader);
  94.             
  95.             mapData = Map.init(MAPSIZE, MAPSIZE);
  96.             
  97.             prgSpr = new Sprite();//ロード画面
  98.             addChild(prgSpr);
  99.             
  100.             createMap();            //マップを作る
  101.             
  102.             addEventListener(Event.ENTER_FRAME, onEnterFrame);//イベントリスナーの登録
  103.             
  104.             yuusha = new Yuusha();    //勇者を作る
  105.             yuusha.scaleX = yuusha.scaleY = SCALE;    //勇者を拡大表示
  106.             yuusha.x = yuusha.y = (SIZE-FLDSIZE)/2//中央に配置
  107.             
  108.             var points:Array = new Array();
  109.             for (var y:int = 0; y < MAPSIZE; y++)
  110.             {
  111.                 for (var x:int = 0; x < MAPSIZE; x++)
  112.                 {
  113.                     if (mapData[y][x] != Status.WALL) points.push(new Point(x, y)); 
  114.                 }
  115.             }
  116.             points = Random.shake(points);
  117.             yuushaPos = new Point(points[0].x * FLDSIZE, points[0].y * FLDSIZE);//勇者初期位置
  118.             moveMap(yuushaPos);        //マップ移動
  119.         }
  120.         
  121.         /**-----------------------------------------------------
  122.          * 毎フレームの処理。
  123.          * ----------------------------------------------------- */
  124.         private function onEnterFrame(event:Event):void {
  125.             
  126.             //画像読み込み完了後 1回だけ処理
  127.             if (!isInit) {
  128.                 removeChild(prgSpr);//ロード画面非表示
  129.                 prgSpr = null;
  130.                 stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);    //イベントリスナーの登録
  131.                 stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);        //イベントリスナーの登録
  132.                 addChild(map);        //マップ表示
  133.                 addChild(yuusha);    //勇者表示
  134.                 isInit = true;
  135.                 
  136.                 var matrix:Matrix = new Matrix();
  137.                 matrix.createGradientBox(1401400, -70, -70);
  138.                 
  139.                 circle = new Sprite();
  140.                 circle.graphics.beginGradientFill("radial", [0xFFFFFF, 0x0], [0.00.5], [0255], matrix);
  141.                 circle.graphics.drawCircle(0070);
  142.                 circle.graphics.endFill();
  143.                 
  144.                 matrix = new Matrix();
  145.                 matrix.translate(232232);
  146.                 
  147.                 bd = new BitmapData(465465true, 0x0);
  148.                 dark = new Bitmap(bd);
  149.                 dark.alpha = 0.0;
  150.                 bd.draw(circle, matrix);
  151.                 bd.threshold(bd, bd.rect, new Point(), "==", 0x0, 0x7F000000, 0xFFFFFF);
  152.                 addChild(dark);
  153.                 
  154.                 bd = new BitmapData(MAPSIZE, MAPSIZE, true, 0x0);
  155.                 bitmap = new Bitmap(bd);
  156.                 bitmap.scaleX = bitmap.scaleY = SCALE2;
  157.                 bitmap.x = (465 - bitmap.width) / 2;
  158.                 bitmap.y = (465 - bitmap.height) / 2;
  159.                 addChild(bitmap);
  160.                 
  161.                 circle = new Sprite();
  162.                 circle.graphics.beginFill(0xFFFFFF);
  163.                 circle.graphics.drawCircle(444);
  164.                 circle.graphics.endFill();
  165.                 addChild(circle);
  166.             }
  167.             
  168.             if (bitmap)
  169.             {
  170.                 circle.x = bitmap.x + yuushaPos.x / 9;
  171.                 circle.y = bitmap.y + yuushaPos.y / 9;
  172.             }
  173.             
  174.             var px:int = (circle.x - bitmap.x) / SCALE2;
  175.             var py:int = (circle.y - bitmap.y) / SCALE2;
  176.             
  177.             if (mapData[py][px] == Status.ROOM)
  178.             {
  179.                 dark.alpha = 0.0;
  180.                 if (bd.getPixel(px, py) == 0x0)
  181.                 {
  182.                     fill(py, px);
  183.                 }
  184.             }
  185.             else
  186.             {
  187.                 dark.alpha = 1.0;
  188.                 bd.setPixel32(px, py, 0x44FFFFFF);
  189.             }
  190.             
  191.             //15フレーム毎に処理する
  192.             if (frameCount++ > 10) {
  193.                 frameCount = 0;
  194.                 yuusha.walk();
  195.             }
  196.             
  197.             //マップ(勇者)をどの方向に動かすか判定
  198.             if (yuushaPos.x % FLDSIZE == 0 && yuushaPos.y % FLDSIZE == 0) {
  199.                 var mapPosX:int = int(yuushaPos.x / FLDSIZE), mapPosY:int = int(yuushaPos.y / FLDSIZE);
  200.                 walkDirection = 4;         //止まる
  201.                 switch(true) {
  202.                     case keyFlags[0]:    //下
  203.                         if(yuushaPos.y < (MAPSIZE-1)*FLDSIZE && !bMapData[mapPosY+1][mapPosX]) walkDirection=0;
  204.                         yuusha.changeDirection(0);
  205.                         break;
  206.                     case keyFlags[1]:    //上
  207.                         if(yuushaPos.y > 0 && !bMapData[mapPosY-1][mapPosX]) walkDirection=1;
  208.                         yuusha.changeDirection(1);
  209.                         break;
  210.                     case keyFlags[2]:    //左
  211.                         if(yuushaPos.x > 0 && !bMapData[mapPosY][mapPosX-1]) walkDirection=2;
  212.                         yuusha.changeDirection(2);
  213.                         break;
  214.                     case keyFlags[3]:    //右
  215.                         if(yuushaPos.x < (MAPSIZE-1)*FLDSIZE && !bMapData[mapPosY][mapPosX+1]) walkDirection=3;
  216.                         yuusha.changeDirection(3);
  217.                         break;
  218.                 }
  219.             }
  220.             
  221.             //次のマスまで自動的に勇者を歩かせる
  222.             switch(walkDirection) {
  223.                 case 0:
  224.                     yuushaPos.y += SPEED;
  225.                     break;
  226.                 case 1:
  227.                     yuushaPos.y -= SPEED;
  228.                     break;
  229.                 case 2:
  230.                     yuushaPos.x -= SPEED;
  231.                     break;
  232.                 case 3:
  233.                     yuushaPos.x += SPEED;
  234.                     break;
  235.             }
  236.             if (walkDirection < 4) moveMap(yuushaPos);
  237.         }
  238.         
  239.         /**-----------------------------------------------------
  240.          * キーボードのキーが押された時の処理。
  241.          * ----------------------------------------------------- */
  242.         private function onKeyDown(event:KeyboardEvent):void {
  243.             switch(event.keyCode) {
  244.                 case 40case 83:    //↓ s
  245.                     keyFlags[0] = true;
  246.             }
  247.             switch(event.keyCode) {
  248.                 case 38case 87:    //↑ w
  249.                     keyFlags[1] = true;
  250.             }
  251.             switch(event.keyCode) {
  252.                 case 37case 65:    //← a
  253.                     keyFlags[2] = true;
  254.             }
  255.             switch(event.keyCode) {
  256.                 case 39case 68:    //→ d
  257.                     keyFlags[3] = true;
  258.             }
  259.         }
  260.         
  261.         /**-----------------------------------------------------
  262.          * キーボードのキーが離された時の処理。
  263.          * ----------------------------------------------------- */
  264.         private function onKeyUp(event:KeyboardEvent):void {
  265.             switch(event.keyCode) {
  266.                 case 40case 83:    //↓ s
  267.                     keyFlags[0] = false;
  268.             }
  269.             switch(event.keyCode) {
  270.                 case 38case 87:    //↑ w
  271.                     keyFlags[1] = false;
  272.             }
  273.             switch(event.keyCode) {
  274.                 case 37case 65:    //← a
  275.                     keyFlags[2] = false;
  276.             }
  277.             switch(event.keyCode) {
  278.                 case 39case 68:    //→ d
  279.                     keyFlags[3] = false;
  280.             }
  281.         }
  282.         
  283.         /**-----------------------------------------------------
  284.          * マップを作ります。
  285.          * ----------------------------------------------------- */
  286.         private function createMap():void {
  287.             map = new Sprite();
  288.             for (var k:uint = 0; k < MAPSIZE; k++) bMapData[k] = []; //bMapDataを2次元配列にする
  289.             
  290.             var bd:BitmapData = new BitmapData(MAPSIZE * FLDSIZE, MAPSIZE * FLDSIZE);
  291.             var bitmap:Bitmap = new Bitmap(bd);
  292.             
  293.             for (var j:uint = 0; j < MAPSIZE; j++) {
  294.                 for (var i:uint = 0; i < MAPSIZE; i++) {
  295.                     var field:Field = fieldList[mapData[j][i]];
  296.                     
  297.                     if (field.isObstacle) bd.copyPixels(image, new Rectangle(field.x, field.y, 3232), new Point(32 * i, 32 * j));
  298.                     else bd.copyPixels(image, new Rectangle(field.x, (Math.random() < 0.1) ? field.y + 32 : field.y, 3232), new Point(32 * i, 32 * j));
  299.                     bMapData[j][i] = field.isObstacle;
  300.                 }
  301.             }
  302.             bitmap.scaleX = bitmap.scaleY = FLDSIZE / 32;
  303.             map.addChild(bitmap);
  304.         }
  305.         
  306.         /**-----------------------------------------------------
  307.          * マップの座標計算。
  308.          * ----------------------------------------------------- */
  309.         private function moveMap(pos:Point):void {
  310.             map.x = (SIZE-FLDSIZE)/2 - yuushaPos.x;
  311.             map.y = (SIZE-FLDSIZE)/2 - yuushaPos.y;
  312.         }
  313.         
  314.         /**-----------------------------------------------------
  315.          * ロード画面を描く。
  316.          * ----------------------------------------------------- */
  317.         private function drawPrg():void {
  318.             var side:Number = SIZE / MAPSIZE,
  319.                 yy:int = int(loaded / MAPSIZE),
  320.                 xx:int = loaded - yy * MAPSIZE,
  321.                 max:int = MAPSIZE;
  322.             prgSpr.graphics.clear();
  323.             prgSpr.graphics.beginFill(0xFFFFFF);
  324.             prgSpr.graphics.drawRect(00, SIZE, yy * side);
  325.             if(yy%2)prgSpr.graphics.drawRect((MAPSIZE-xx)*side, yy*side, SIZE, side);
  326.             else    prgSpr.graphics.drawRect(0, yy*side, xx*side, side);
  327.             prgSpr.graphics.endFill();
  328.         }
  329.         
  330.         private function fill(py:int, px:int):void
  331.         {
  332.             bd.setPixel32(px, py, 0x44FFFFFF);
  333.             
  334.             if (mapData[py][px] == Status.CORRIDOR) return;
  335.             
  336.             if (0 <= px - 1 && mapData[py][px - 1] != Status.WALL && bd.getPixel(px - 1, py) == 0x0 && mapData[py][px - 1] != Status.WALL) fill(py, px - 1);
  337.             if (px + 1 < MAPSIZE && mapData[py][px + 1] != Status.WALL && bd.getPixel(px + 1, py) == 0x0 && mapData[py][px + 1] != Status.WALL) fill(py, px + 1);
  338.             if (0 <= py - 1 && mapData[py - 1][px] != Status.WALL && bd.getPixel(px, py - 1) == 0x0 && mapData[py - 1][px] != Status.WALL) fill(py - 1, px);
  339.             if (py + 1 < MAPSIZE && mapData[py + 1][px] != Status.WALL && bd.getPixel(px, py + 1) == 0x0 && mapData[py + 1][px] != Status.WALL) fill(py + 1, px);
  340.         }
  341.     }
  342. }
  343. import flash.display.Sprite;
  344. import flash.display.Loader;
  345. import flash.net.URLRequest;
  346. import flash.system.LoaderContext;
  347. class Status
  348. {
  349.     public static const WALL:int = 0;
  350.     public static const ROOM:int = 1;
  351.     public static const CORRIDOR:int = 2;
  352. }
  353. /**-----------------------------------------------------
  354.  * 勇者クラスです。勇者を作ったり、足踏させたり、向きを変えたりします。
  355.  * ----------------------------------------------------- */
  356. class Yuusha  extends Sprite {
  357.     public var direction:int = 0;        //向き (0:前 1:後 2:左 3:右)
  358.     private var walkFlag:Boolean = true;//足踏み用
  359.     private var yuushaImages:Array = [];//勇者の画像集
  360.     
  361.     /**-----------------------------------------------------
  362.      * コンストラクタ。
  363.      * ----------------------------------------------------- */
  364.     public function Yuusha():void {
  365.         for (var i:uint = 0; i < 8; i++) {
  366.             var loader:Loader = new Loader();
  367.             loader.load(new URLRequest(ImageURL[i]), new LoaderContext(true));
  368.             yuushaImages.push(loader);
  369.             if(i) yuushaImages[i].visible = false;
  370.             addChild(yuushaImages[i]);
  371.         }
  372.     }
  373.     
  374.     /**-----------------------------------------------------
  375.      * 勇者の画像のURLリスト
  376.      * ----------------------------------------------------- */
  377.     private const ImageURL:Array = [
  378.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaF1.png",    //前向き1
  379.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaF2.png",    //前向き2
  380.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaB1.png",    //後ろ向き1
  381.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaB2.png",    //後ろ向き2
  382.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaL1.png",    //左向き1
  383.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaL2.png",    //左向き2
  384.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaR1.png",    //右向き1
  385.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaR2.png"        //右向き2
  386.     ];
  387.     
  388.     /**-----------------------------------------------------
  389.      * 足踏みさせます。
  390.      * ----------------------------------------------------- */
  391.     public function walk():void {
  392.         walkFlag = !walkFlag;
  393.         for (var i:uint = 0; i < 8; i++) {
  394.             if (i == 2*direction+int(walkFlag)) yuushaImages[i].visible = true;
  395.             else yuushaImages[i].visible = false;
  396.         }
  397.     }
  398.     
  399.     /**-----------------------------------------------------
  400.      * 向きを変更します。
  401.      * numは勇者の向きを表します。(0~3)
  402.      * ----------------------------------------------------- */
  403.     public function changeDirection(num:int):void {
  404.         direction = num;
  405.         for (var i:uint = 0; i < 8; i++) {
  406.             if (i == 2*direction+int(walkFlag)) yuushaImages[i].visible = true;
  407.             else yuushaImages[i].visible = false;
  408.         }
  409.     }
  410. }
  411. /**-----------------------------------------------------
  412.  * Fieldクラスです。画像のURLと、そのフィールドが障害物か否かを保存します。
  413.  * ----------------------------------------------------- */
  414. class Field {
  415.     public var x:int;
  416.     public var y:int;
  417.     public var isObstacle:Boolean;    //障害物か否か (true:障害物  false:障害物じゃない(歩ける))
  418.     
  419.     public function Field(x:int, y:int, b:Boolean = false):void {
  420.         this.x = x;
  421.         this.y = y;
  422.         isObstacle = b;
  423.     }
  424. }
  425. class Map
  426. {
  427.     private static var WIDTH:int;
  428.     private static var HEIGHT:int;
  429.     private static const MARGIN:int = 8;
  430.     
  431.     private static var dungeon:Array;
  432.     
  433.     public static function init(width:int, height:int):Array
  434.     {
  435.         WIDTH = width;
  436.         HEIGHT = height;
  437.         
  438.         dungeon = new Array(HEIGHT).map(function(...a):* { return new Array(WIDTH).map(function(...a):* { return Status.WALL; } ) } );
  439.         
  440.         var partitions:Array = split(new Rect(00, WIDTH - 1, HEIGHT - 1));
  441.         var rooms:Array = partitions.map(makeRoom);
  442.         makeCorridor(partitions, rooms);
  443.         rooms.map(fill);
  444.         
  445.         return dungeon;
  446.     }
  447.     
  448.     // Math.floor(value / 2)
  449.     private static function half(value:int):int
  450.     {
  451.         return value >> 1;
  452.     }
  453.     
  454.     // 領域の中から適当に部屋を作る
  455.     private static function makeRoom(src:Rect, ...a):Rect
  456.     {
  457.         var dest:Rect = new Rect();
  458.         dest.left     = src.left      + randomRange(2, half(src.right  - src.left) - 0); // -1
  459.         dest.top     = src.top      + randomRange(2, half(src.bottom - src.top)  - 0);
  460.         dest.right  = src.right  - randomRange(2, half(src.right  - src.left) - 0);
  461.         dest.bottom = src.bottom - randomRange(2, half(src.bottom - src.top)  - 0);
  462.         
  463.         return dest;
  464.     }
  465.     
  466.     // min以上、max未満のランダム値を生成
  467.     private static function randomRange(min:int, max:int):int
  468.     {
  469.         if (min > max) throw new Error("min = " + min + " : max = " + max);
  470.         else if (min == max) return min;
  471.         else
  472.         {
  473.             var value:int = Math.floor(Math.random() * (max - min)) + min;
  474.             return value;
  475.         }
  476.     }
  477.     
  478.     // 塗る。部屋、通路用
  479.     private static function fill(rect:Rect, i:int = -1, array:Array = null):void
  480.     {
  481.         var minY:int = Math.min(rect.top, rect.bottom);
  482.         var maxY:int = Math.max(rect.top, rect.bottom);
  483.         
  484.         var minX:int = Math.min(rect.left, rect.right);
  485.         var maxX:int = Math.max(rect.left, rect.right);
  486.         
  487.         for (var y:int = minY; y <= maxY; y++)
  488.         {
  489.             for (var x:int = minX; x <= maxX; x++)
  490.             {
  491.                 if (i != -1) dungeon[y][x] = Status.ROOM;
  492.                 else dungeon[y][x] = Status.CORRIDOR;
  493.             }
  494.         }
  495.     }
  496.     
  497.     // 多次元配列を一次元配列に
  498.     private static function flatten(array:Array):Array
  499.     {
  500.         var src:Array = array.slice();     // 渡された配列のコピー
  501.         var dest:Array = new Array();    // フラットにした返却用配列
  502.      
  503.         while (true)
  504.         {
  505.             var element:* = src.shift(); // 配列から一つだけ値を取り出す
  506.      
  507.             if (element == undefinedbreak// もう配列には要素が無いので終了 
  508.             else if (element is Array) src = src.concat(element); // 要素が配列なら、要素 + srcという形に変換する
  509.             else dest.push(element); // 要素が配列以外なら返却用配列に追加
  510.         }
  511.      
  512.         return dest;
  513.     }
  514.     
  515.     // 通路作成
  516.     private static function makeCorridor(partitions:Array, rooms:Array):void
  517.     {
  518.         var list:Array = new Array();
  519.         
  520.         // 各部屋のペア
  521.         for (var i:int = 0; i < partitions.length - 1; i++)
  522.         {
  523.             list.push([i, i + 1]);
  524.         }
  525.         
  526.         // 一本道にならないように
  527.         for (i = 0; i < partitions.length; i++)
  528.         {
  529.             for (var j:int = i + 1; j < partitions.length; j++)
  530.             {
  531.                 if (randomRange(04) == 0)
  532.                 {
  533.                     if (partitions[i].left == partitions[j].right ||
  534.                         partitions[i].right == partitions[j].left ||
  535.                         partitions[i].top == partitions[j].bottom ||
  536.                         partitions[i].bottom == partitions[j].top)
  537.                     {
  538.                         list.push([i, j]);
  539.                     }
  540.                 }
  541.             }
  542.         }
  543.         
  544.         list.forEach
  545.         (
  546.             function(i:Array, ...a):void
  547.             {
  548.                 connect(partitions[i[0]], partitions[i[1]], rooms[i[0]], rooms[i[1]]);
  549.             }
  550.         );
  551.     }
  552.     
  553.     // 部屋と部屋を繋げる
  554.     private static function connect(p0:Rect, p1:Rect, r0:Rect, r1:Rect):void
  555.     {
  556.         var a:int;
  557.         var b:int;
  558.         
  559.         // 枠Aの下側と枠Bの上側が同じ位置だったら横に分割した事になる
  560.         if (p0.bottom == p1.top)
  561.         {
  562.             // 部屋のどこから通路を出すかを決める
  563.             a = randomRange(r0.left, r0.right);
  564.             b = randomRange(r1.left, r1.right);
  565.             
  566.             fill(new Rect(a, half(p0.top + p0.bottom), a, p0.bottom));
  567.             fill(new Rect(b, half(p1.top + p1.bottom), b, p1.top));
  568.             fill(new Rect(a, p0.bottom, b, p0.bottom));
  569.         }
  570.         // 縦に分割している場合の処理
  571.         else
  572.         {
  573.             // 部屋のどこから通路を出すかを決める
  574.             a = randomRange(r0.top, r0.bottom);
  575.             b = randomRange(r1.top, r1.bottom);
  576.             
  577.             fill(new Rect(half(p0.left + p0.right), a, p0.right, a));
  578.             fill(new Rect(half(p1.left + p1.right), b, p1.left, b));
  579.             fill(new Rect(p0.right, a, p0.right, b));
  580.         }
  581.     }
  582.     
  583.     // 領域分割
  584.     private static function split(rect:Rect, ...a):Array
  585.     {
  586.         if ((rect.right  - rect.left < MARGIN * 2) ||
  587.             (rect.bottom - rect.top < MARGIN * 2))
  588.         {
  589.             return [rect];
  590.         }
  591.         else
  592.         {
  593.             var rectA:Rect;
  594.             var rectB:Rect;
  595.             
  596.             // 1/2の確率で横か縦に分割
  597.             if (randomRange(02) == 0)
  598.             {
  599.                 // 横に分割
  600.                 
  601.                 var height:int = randomRange(rect.top + MARGIN, rect.bottom - MARGIN);
  602.                 
  603.                 rectA = new Rect(rect.left, rect.top, rect.right, height);
  604.                 rectB = new Rect(rect.left, height, rect.right, rect.bottom);
  605.             }
  606.             else
  607.             {
  608.                 // 縦に分割
  609.                 
  610.                 var width:int = randomRange(rect.left + MARGIN, rect.right - MARGIN);
  611.                 
  612.                 rectA = new Rect(rect.left, rect.top, width, rect.bottom);
  613.                 rectB = new Rect(width, rect.top, rect.right, rect.bottom);
  614.             }
  615.             
  616.             return flatten([rectA, rectB].map(split));
  617.         }
  618.     }
  619. }
  620. // 標準で付いてるRectangleだとコンストラクタで右下のPointが指定できないから使いづらい
  621. class Rect
  622. {
  623.     public var left:int;
  624.     public var right:int;
  625.     public var top:int;
  626.     public var bottom:int;
  627.     
  628.     public function Rect(left:int = 0, top:int = 0, right:int = 0, bottom:int = 0):void
  629.     {
  630.         this.left = left;
  631.         this.top = top;
  632.         this.right = right;
  633.         this.bottom = bottom;
  634.     }
  635. }
noswf

ワンダフルクエスト(不思議のダンジョン風に) forked from: ワンダフルクエスト(不思議のダンジョン風に) [diff(2)]

  1. // forked from rsakane's ワンダフルクエスト(不思議のダンジョン風に)
  2. // forked from osamX's ワンダフルクエスト
  3. // forked from nengafl's nengafl
  4. /*
  5.  * [遊び方]
  6.  * はじめに、マップをクリックして...
  7.  * ↑ , w :    上に移動
  8.  * ↓ , s :    下に移動
  9.  * ← , a :    左に移動
  10.  *
  11.  * 
  12.  * マップは毎回ランダムに生成されます。
  13.  * 一階層しか探索できません。
  14.  * やり直したいときはリロードしてください。
  15.  * 
  16.  * マップチップ素材
  17.  * http://www.tekepon.net/fsm/
  18.  * 
  19.  * ダンジョン生成参考
  20.  * http://racanhack.sourceforge.jp/rhdoc/index.html
  21.  */
  22. package 
  23. {
  24.     import flash.display.*;
  25.     import flash.events.*;
  26.     import flash.geom.Matrix;
  27.     import flash.geom.Point;
  28.     import flash.geom.Rectangle;
  29.     import flash.net.URLRequest;
  30.     import flash.system.LoaderContext;
  31.     import frocessing.math.Random;
  32.     [SWF(width="465", height="465", frameRate="30", backgroundColor="0x000000")]
  33.     public class Main extends Sprite 
  34.     {
  35.         private const SIZE:Number = 465;//ステージの大きさ
  36.         private const SCALE:Number = 4.0//勇者やフィールドの拡大率
  37.         private const SPEED:Number = 6;    //勇者が歩くスピード FLDSIZEの約数にしてください
  38.         private const MAPSIZE:uint = 50;//マップの横・縦のマスの個数
  39.         private const FLDSIZE:uint = 72;//フィールド(マップ上の1マス)の横・縦のドット数
  40.         
  41.         private const SCALE2:int = 8;
  42.         private var circle:Sprite;
  43.         private var bd:BitmapData;
  44.         private var image:BitmapData;
  45.         private var dark:Bitmap;
  46.         private var bitmap:Bitmap;
  47.         
  48.         private var yuusha:Yuusha;        //勇者
  49.         private var yuushaPos:Point;    //勇者のマップ上の座標
  50.         private var map:Sprite;            //マップ本体 これを動かして勇者が移動しているように見せる
  51.         private var bMapData:Array = [];//フィールドが障害物か否かを記憶
  52.         private var frameCount:Number = 0;    //onEnterFrameで使用
  53.         private var keyFlags:Array = [falsefalsefalsefalse]; //下上左右のキーが押されているか
  54.         private var walkDirection:int = 4;    //歩いていく方向 (0~3:下上左右  4:止)
  55.         private var loaded:int = 0;        //読み込み完了した画像の個数
  56.         private var isInit:Boolean = false;    //初期化されているか onEnterFrameで使用
  57.         private var prgSpr:Sprite;        //ロード画面表示用
  58.         
  59.         /**-----------------------------------------------------
  60.          * マップの1マス(フィールド)のリストです。
  61.          * ここをいじると好きな画像をマップ上に貼ることができます。
  62.          * 画像のサイズは、基本的に16*16ピクセルです。
  63.          * 形式はjpeg,gif,pngのどれかにしてください。
  64.          * Twitterのアイコン画像取得は、こちらのAPIを使わせてもらってます。
  65.          * http://usericons.relucks.org/
  66.          * ----------------------------------------------------- */
  67.         private const fieldList:Array = [
  68.             new Field(32 * 532 * 6true),
  69.             new Field(032 * 6false),
  70.             new Field(032 * 6false),
  71.         ];
  72.         
  73.         /**-----------------------------------------------------
  74.          * マップのデータ(ここが木で、あそこが芝生で...ってやつ)が入ってます。
  75.          * ここをいじると、マップが変わります。上のfieldListのコメント参照。
  76.          * ----------------------------------------------------- */
  77.         private var mapData:Array;
  78.         
  79.         /**-----------------------------------------------------
  80.          * コンストラクタ。 ここが最初に処理されます。
  81.          * ----------------------------------------------------- */
  82.         public function Main():void 
  83.         {    
  84.             var loader:Loader = new Loader();
  85.             loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
  86.             loader.load(new URLRequest("http://assets.wonderfl.net/images/related_images/a/af/affb/affbae7b9d9ae1f2a19c182ef6584acecbfb833a"), new LoaderContext(true));
  87.         }
  88.         
  89.         private function initHandler(event:Event):void
  90.         {
  91.             var loader:Loader = event.currentTarget.loader;
  92.             image = new BitmapData(loader.width, loader.height, false);
  93.             image.draw(loader);
  94.             
  95.             mapData = Map.init(MAPSIZE, MAPSIZE);
  96.             
  97.             prgSpr = new Sprite();//ロード画面
  98.             addChild(prgSpr);
  99.             
  100.             createMap();            //マップを作る
  101.             
  102.             addEventListener(Event.ENTER_FRAME, onEnterFrame);//イベントリスナーの登録
  103.             
  104.             yuusha = new Yuusha();    //勇者を作る
  105.             yuusha.scaleX = yuusha.scaleY = SCALE;    //勇者を拡大表示
  106.             yuusha.x = yuusha.y = (SIZE-FLDSIZE)/2//中央に配置
  107.             
  108.             var points:Array = new Array();
  109.             for (var y:int = 0; y < MAPSIZE; y++)
  110.             {
  111.                 for (var x:int = 0; x < MAPSIZE; x++)
  112.                 {
  113.                     if (mapData[y][x] != Status.WALL) points.push(new Point(x, y)); 
  114.                 }
  115.             }
  116.             points = Random.shake(points);
  117.             yuushaPos = new Point(points[0].x * FLDSIZE, points[0].y * FLDSIZE);//勇者初期位置
  118.             moveMap(yuushaPos);        //マップ移動
  119.         }
  120.         
  121.         /**-----------------------------------------------------
  122.          * 毎フレームの処理。
  123.          * ----------------------------------------------------- */
  124.         private function onEnterFrame(event:Event):void {
  125.             
  126.             //画像読み込み完了後 1回だけ処理
  127.             if (!isInit) {
  128.                 removeChild(prgSpr);//ロード画面非表示
  129.                 prgSpr = null;
  130.                 stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);    //イベントリスナーの登録
  131.                 stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);        //イベントリスナーの登録
  132.                 addChild(map);        //マップ表示
  133.                 addChild(yuusha);    //勇者表示
  134.                 isInit = true;
  135.                 
  136.                 var matrix:Matrix = new Matrix();
  137.                 matrix.createGradientBox(1401400, -70, -70);
  138.                 
  139.                 circle = new Sprite();
  140.                 circle.graphics.beginGradientFill("radial", [0xFFFFFF, 0x0], [0.00.5], [0255], matrix);
  141.                 circle.graphics.drawCircle(0070);
  142.                 circle.graphics.endFill();
  143.                 
  144.                 matrix = new Matrix();
  145.                 matrix.translate(232232);
  146.                 
  147.                 bd = new BitmapData(465465true, 0x0);
  148.                 dark = new Bitmap(bd);
  149.                 dark.alpha = 0.0;
  150.                 bd.draw(circle, matrix);
  151.                 bd.threshold(bd, bd.rect, new Point(), "==", 0x0, 0x7F000000, 0xFFFFFF);
  152.                 addChild(dark);
  153.                 
  154.                 bd = new BitmapData(MAPSIZE, MAPSIZE, true, 0x0);
  155.                 bitmap = new Bitmap(bd);
  156.                 bitmap.scaleX = bitmap.scaleY = SCALE2;
  157.                 bitmap.x = (465 - bitmap.width) / 2;
  158.                 bitmap.y = (465 - bitmap.height) / 2;
  159.                 addChild(bitmap);
  160.                 
  161.                 circle = new Sprite();
  162.                 circle.graphics.beginFill(0xFFFFFF);
  163.                 circle.graphics.drawCircle(444);
  164.                 circle.graphics.endFill();
  165.                 addChild(circle);
  166.             }
  167.             
  168.             if (bitmap)
  169.             {
  170.                 circle.x = bitmap.x + yuushaPos.x / 9;
  171.                 circle.y = bitmap.y + yuushaPos.y / 9;
  172.             }
  173.             
  174.             var px:int = (circle.x - bitmap.x) / SCALE2;
  175.             var py:int = (circle.y - bitmap.y) / SCALE2;
  176.             
  177.             if (mapData[py][px] == Status.ROOM)
  178.             {
  179.                 dark.alpha = 0.0;
  180.                 if (bd.getPixel(px, py) == 0x0)
  181.                 {
  182.                     fill(py, px);
  183.                 }
  184.             }
  185.             else
  186.             {
  187.                 dark.alpha = 1.0;
  188.                 bd.setPixel32(px, py, 0x44FFFFFF);
  189.             }
  190.             
  191.             //15フレーム毎に処理する
  192.             if (frameCount++ > 10) {
  193.                 frameCount = 0;
  194.                 yuusha.walk();
  195.             }
  196.             
  197.             //マップ(勇者)をどの方向に動かすか判定
  198.             if (yuushaPos.x % FLDSIZE == 0 && yuushaPos.y % FLDSIZE == 0) {
  199.                 var mapPosX:int = int(yuushaPos.x / FLDSIZE), mapPosY:int = int(yuushaPos.y / FLDSIZE);
  200.                 walkDirection = 4;         //止まる
  201.                 switch(true) {
  202.                     case keyFlags[0]:    //下
  203.                         if(yuushaPos.y < (MAPSIZE-1)*FLDSIZE && !bMapData[mapPosY+1][mapPosX]) walkDirection=0;
  204.                         yuusha.changeDirection(0);
  205.                         break;
  206.                     case keyFlags[1]:    //上
  207.                         if(yuushaPos.y > 0 && !bMapData[mapPosY-1][mapPosX]) walkDirection=1;
  208.                         yuusha.changeDirection(1);
  209.                         break;
  210.                     case keyFlags[2]:    //左
  211.                         if(yuushaPos.x > 0 && !bMapData[mapPosY][mapPosX-1]) walkDirection=2;
  212.                         yuusha.changeDirection(2);
  213.                         break;
  214.                     case keyFlags[3]:    //右
  215.                         if(yuushaPos.x < (MAPSIZE-1)*FLDSIZE && !bMapData[mapPosY][mapPosX+1]) walkDirection=3;
  216.                         yuusha.changeDirection(3);
  217.                         break;
  218.                 }
  219.             }
  220.             
  221.             //次のマスまで自動的に勇者を歩かせる
  222.             switch(walkDirection) {
  223.                 case 0:
  224.                     yuushaPos.y += SPEED;
  225.                     break;
  226.                 case 1:
  227.                     yuushaPos.y -= SPEED;
  228.                     break;
  229.                 case 2:
  230.                     yuushaPos.x -= SPEED;
  231.                     break;
  232.                 case 3:
  233.                     yuushaPos.x += SPEED;
  234.                     break;
  235.             }
  236.             if (walkDirection < 4) moveMap(yuushaPos);
  237.         }
  238.         
  239.         /**-----------------------------------------------------
  240.          * キーボードのキーが押された時の処理。
  241.          * ----------------------------------------------------- */
  242.         private function onKeyDown(event:KeyboardEvent):void {
  243.             switch(event.keyCode) {
  244.                 case 40case 83:    //↓ s
  245.                     keyFlags[0] = true;
  246.             }
  247.             switch(event.keyCode) {
  248.                 case 38case 87:    //↑ w
  249.                     keyFlags[1] = true;
  250.             }
  251.             switch(event.keyCode) {
  252.                 case 37case 65:    //← a
  253.                     keyFlags[2] = true;
  254.             }
  255.             switch(event.keyCode) {
  256.                 case 39case 68:    //→ d
  257.                     keyFlags[3] = true;
  258.             }
  259.         }
  260.         
  261.         /**-----------------------------------------------------
  262.          * キーボードのキーが離された時の処理。
  263.          * ----------------------------------------------------- */
  264.         private function onKeyUp(event:KeyboardEvent):void {
  265.             switch(event.keyCode) {
  266.                 case 40case 83:    //↓ s
  267.                     keyFlags[0] = false;
  268.             }
  269.             switch(event.keyCode) {
  270.                 case 38case 87:    //↑ w
  271.                     keyFlags[1] = false;
  272.             }
  273.             switch(event.keyCode) {
  274.                 case 37case 65:    //← a
  275.                     keyFlags[2] = false;
  276.             }
  277.             switch(event.keyCode) {
  278.                 case 39case 68:    //→ d
  279.                     keyFlags[3] = false;
  280.             }
  281.         }
  282.         
  283.         /**-----------------------------------------------------
  284.          * マップを作ります。
  285.          * ----------------------------------------------------- */
  286.         private function createMap():void {
  287.             map = new Sprite();
  288.             for (var k:uint = 0; k < MAPSIZE; k++) bMapData[k] = []; //bMapDataを2次元配列にする
  289.             
  290.             var bd:BitmapData = new BitmapData(MAPSIZE * FLDSIZE, MAPSIZE * FLDSIZE);
  291.             var bitmap:Bitmap = new Bitmap(bd);
  292.             
  293.             for (var j:uint = 0; j < MAPSIZE; j++) {
  294.                 for (var i:uint = 0; i < MAPSIZE; i++) {
  295.                     var field:Field = fieldList[mapData[j][i]];
  296.                     
  297.                     if (field.isObstacle) bd.copyPixels(image, new Rectangle(field.x, field.y, 3232), new Point(32 * i, 32 * j));
  298.                     else bd.copyPixels(image, new Rectangle(field.x, (Math.random() < 0.1) ? field.y + 32 : field.y, 3232), new Point(32 * i, 32 * j));
  299.                     bMapData[j][i] = field.isObstacle;
  300.                 }
  301.             }
  302.             bitmap.scaleX = bitmap.scaleY = FLDSIZE / 32;
  303.             map.addChild(bitmap);
  304.         }
  305.         
  306.         /**-----------------------------------------------------
  307.          * マップの座標計算。
  308.          * ----------------------------------------------------- */
  309.         private function moveMap(pos:Point):void {
  310.             map.x = (SIZE-FLDSIZE)/2 - yuushaPos.x;
  311.             map.y = (SIZE-FLDSIZE)/2 - yuushaPos.y;
  312.         }
  313.         
  314.         /**-----------------------------------------------------
  315.          * ロード画面を描く。
  316.          * ----------------------------------------------------- */
  317.         private function drawPrg():void {
  318.             var side:Number = SIZE / MAPSIZE,
  319.                 yy:int = int(loaded / MAPSIZE),
  320.                 xx:int = loaded - yy * MAPSIZE,
  321.                 max:int = MAPSIZE;
  322.             prgSpr.graphics.clear();
  323.             prgSpr.graphics.beginFill(0xFFFFFF);
  324.             prgSpr.graphics.drawRect(00, SIZE, yy * side);
  325.             if(yy%2)prgSpr.graphics.drawRect((MAPSIZE-xx)*side, yy*side, SIZE, side);
  326.             else    prgSpr.graphics.drawRect(0, yy*side, xx*side, side);
  327.             prgSpr.graphics.endFill();
  328.         }
  329.         
  330.         private function fill(py:int, px:int):void
  331.         {
  332.             bd.setPixel32(px, py, 0x44FFFFFF);
  333.             
  334.             if (mapData[py][px] == Status.CORRIDOR) return;
  335.             
  336.             if (0 <= px - 1 && mapData[py][px - 1] != Status.WALL && bd.getPixel(px - 1, py) == 0x0 && mapData[py][px - 1] != Status.WALL) fill(py, px - 1);
  337.             if (px + 1 < MAPSIZE && mapData[py][px + 1] != Status.WALL && bd.getPixel(px + 1, py) == 0x0 && mapData[py][px + 1] != Status.WALL) fill(py, px + 1);
  338.             if (0 <= py - 1 && mapData[py - 1][px] != Status.WALL && bd.getPixel(px, py - 1) == 0x0 && mapData[py - 1][px] != Status.WALL) fill(py - 1, px);
  339.             if (py + 1 < MAPSIZE && mapData[py + 1][px] != Status.WALL && bd.getPixel(px, py + 1) == 0x0 && mapData[py + 1][px] != Status.WALL) fill(py + 1, px);
  340.         }
  341.     }
  342. }
  343. import flash.display.Sprite;
  344. import flash.display.Loader;
  345. import flash.net.URLRequest;
  346. import flash.system.LoaderContext;
  347. class Status
  348. {
  349.     public static const WALL:int = 0;
  350.     public static const ROOM:int = 1;
  351.     public static const CORRIDOR:int = 2;
  352. }
  353. /**-----------------------------------------------------
  354.  * 勇者クラスです。勇者を作ったり、足踏させたり、向きを変えたりします。
  355.  * ----------------------------------------------------- */
  356. class Yuusha  extends Sprite {
  357.     public var direction:int = 0;        //向き (0:前 1:後 2:左 3:右)
  358.     private var walkFlag:Boolean = true;//足踏み用
  359.     private var yuushaImages:Array = [];//勇者の画像集
  360.     
  361.     /**-----------------------------------------------------
  362.      * コンストラクタ。
  363.      * ----------------------------------------------------- */
  364.     public function Yuusha():void {
  365.         for (var i:uint = 0; i < 8; i++) {
  366.             var loader:Loader = new Loader();
  367.             loader.load(new URLRequest(ImageURL[i]), new LoaderContext(true));
  368.             yuushaImages.push(loader);
  369.             if(i) yuushaImages[i].visible = false;
  370.             addChild(yuushaImages[i]);
  371.         }
  372.     }
  373.     
  374.     /**-----------------------------------------------------
  375.      * 勇者の画像のURLリスト
  376.      * ----------------------------------------------------- */
  377.     private const ImageURL:Array = [
  378.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaF1.png",    //前向き1
  379.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaF2.png",    //前向き2
  380.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaB1.png",    //後ろ向き1
  381.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaB2.png",    //後ろ向き2
  382.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaL1.png",    //左向き1
  383.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaL2.png",    //左向き2
  384.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaR1.png",    //右向き1
  385.         "http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaR2.png"        //右向き2
  386.     ];
  387.     
  388.     /**-----------------------------------------------------
  389.      * 足踏みさせます。
  390.      * ----------------------------------------------------- */
  391.     public function walk():void {
  392.         walkFlag = !walkFlag;
  393.         for (var i:uint = 0; i < 8; i++) {
  394.             if (i == 2*direction+int(walkFlag)) yuushaImages[i].visible = true;
  395.             else yuushaImages[i].visible = false;
  396.         }
  397.     }
  398.     
  399.     /**-----------------------------------------------------
  400.      * 向きを変更します。
  401.      * numは勇者の向きを表します。(0~3)
  402.      * ----------------------------------------------------- */
  403.     public function changeDirection(num:int):void {
  404.         direction = num;
  405.         for (var i:uint = 0; i < 8; i++) {
  406.             if (i == 2*direction+int(walkFlag)) yuushaImages[i].visible = true;
  407.             else yuushaImages[i].visible = false;
  408.         }
  409.     }
  410. }
  411. /**-----------------------------------------------------
  412.  * Fieldクラスです。画像のURLと、そのフィールドが障害物か否かを保存します。
  413.  * ----------------------------------------------------- */
  414. class Field {
  415.     public var x:int;
  416.     public var y:int;
  417.     public var isObstacle:Boolean;    //障害物か否か (true:障害物  false:障害物じゃない(歩ける))
  418.     
  419.     public function Field(x:int, y:int, b:Boolean = false):void {
  420.         this.x = x;
  421.         this.y = y;
  422.         isObstacle = b;
  423.     }
  424. }
  425. class Map
  426. {
  427.     private static var WIDTH:int;
  428.     private static var HEIGHT:int;
  429.     private static const MARGIN:int = 8;
  430.     
  431.     private static var dungeon:Array;
  432.     
  433.     public static function init(width:int, height:int):Array
  434.     {
  435.         WIDTH = width;
  436.         HEIGHT = height;
  437.         
  438.         dungeon = new Array(HEIGHT).map(function(...a):* { return new Array(WIDTH).map(function(...a):* { return Status.WALL; } ) } );
  439.         
  440.         var partitions:Array = split(new Rect(00, WIDTH - 1, HEIGHT - 1));
  441.         var rooms:Array = partitions.map(makeRoom);
  442.         makeCorridor(partitions, rooms);
  443.         rooms.map(fill);
  444.         
  445.         return dungeon;
  446.     }
  447.     
  448.     // Math.floor(value / 2)
  449.     private static function half(value:int):int
  450.     {
  451.         return value >> 1;
  452.     }
  453.     
  454.     // 領域の中から適当に部屋を作る
  455.     private static function makeRoom(src:Rect, ...a):Rect
  456.     {
  457.         var dest:Rect = new Rect();
  458.         dest.left     = src.left      + randomRange(2, half(src.right  - src.left) - 0); // -1
  459.         dest.top     = src.top      + randomRange(2, half(src.bottom - src.top)  - 0);
  460.         dest.right  = src.right  - randomRange(2, half(src.right  - src.left) - 0);
  461.         dest.bottom = src.bottom - randomRange(2, half(src.bottom - src.top)  - 0);
  462.         
  463.         return dest;
  464.     }
  465.     
  466.     // min以上、max未満のランダム値を生成
  467.     private static function randomRange(min:int, max:int):int
  468.     {
  469.         if (min > max) throw new Error("min = " + min + " : max = " + max);
  470.         else if (min == max) return min;
  471.         else
  472.         {
  473.             var value:int = Math.floor(Math.random() * (max - min)) + min;
  474.             return value;
  475.         }
  476.     }
  477.     
  478.     // 塗る。部屋、通路用
  479.     private static function fill(rect:Rect, i:int = -1, array:Array = null):void
  480.     {
  481.         var minY:int = Math.min(rect.top, rect.bottom);
  482.         var maxY:int = Math.max(rect.top, rect.bottom);
  483.         
  484.         var minX:int = Math.min(rect.left, rect.right);
  485.         var maxX:int = Math.max(rect.left, rect.right);
  486.         
  487.         for (var y:int = minY; y <= maxY; y++)
  488.         {
  489.             for (var x:int = minX; x <= maxX; x++)
  490.             {
  491.                 if (i != -1) dungeon[y][x] = Status.ROOM;
  492.                 else dungeon[y][x] = Status.CORRIDOR;
  493.             }
  494.         }
  495.     }
  496.     
  497.     // 多次元配列を一次元配列に
  498.     private static function flatten(array:Array):Array
  499.     {
  500.         var src:Array = array.slice();     // 渡された配列のコピー
  501.         var dest:Array = new Array();    // フラットにした返却用配列
  502.      
  503.         while (true)
  504.         {
  505.             var element:* = src.shift(); // 配列から一つだけ値を取り出す
  506.      
  507.             if (element == undefinedbreak// もう配列には要素が無いので終了 
  508.             else if (element is Array) src = src.concat(element); // 要素が配列なら、要素 + srcという形に変換する
  509.             else dest.push(element); // 要素が配列以外なら返却用配列に追加
  510.         }
  511.      
  512.         return dest;
  513.     }
  514.     
  515.     // 通路作成
  516.     private static function makeCorridor(partitions:Array, rooms:Array):void
  517.     {
  518.         var list:Array = new Array();
  519.         
  520.         // 各部屋のペア
  521.         for (var i:int = 0; i < partitions.length - 1; i++)
  522.         {
  523.             list.push([i, i + 1]);
  524.         }
  525.         
  526.         // 一本道にならないように
  527.         for (i = 0; i < partitions.length; i++)
  528.         {
  529.             for (var j:int = i + 1; j < partitions.length; j++)
  530.             {
  531.                 if (randomRange(04) == 0)
  532.                 {
  533.                     if (partitions[i].left == partitions[j].right ||
  534.                         partitions[i].right == partitions[j].left ||
  535.                         partitions[i].top == partitions[j].bottom ||
  536.                         partitions[i].bottom == partitions[j].top)
  537.                     {
  538.                         list.push([i, j]);
  539.                     }
  540.                 }
  541.             }
  542.         }
  543.         
  544.         list.forEach
  545.         (
  546.             function(i:Array, ...a):void
  547.             {
  548.                 connect(partitions[i[0]], partitions[i[1]], rooms[i[0]], rooms[i[1]]);
  549.             }
  550.         );
  551.     }
  552.     
  553.     // 部屋と部屋を繋げる
  554.     private static function connect(p0:Rect, p1:Rect, r0:Rect, r1:Rect):void
  555.     {
  556.         var a:int;
  557.         var b:int;
  558.         
  559.         // 枠Aの下側と枠Bの上側が同じ位置だったら横に分割した事になる
  560.         if (p0.bottom == p1.top)
  561.         {
  562.             // 部屋のどこから通路を出すかを決める
  563.             a = randomRange(r0.left, r0.right);
  564.             b = randomRange(r1.left, r1.right);
  565.             
  566.             fill(new Rect(a, half(p0.top + p0.bottom), a, p0.bottom));
  567.             fill(new Rect(b, half(p1.top + p1.bottom), b, p1.top));
  568.             fill(new Rect(a, p0.bottom, b, p0.bottom));
  569.         }
  570.         // 縦に分割している場合の処理
  571.         else
  572.         {
  573.             // 部屋のどこから通路を出すかを決める
  574.             a = randomRange(r0.top, r0.bottom);
  575.             b = randomRange(r1.top, r1.bottom);
  576.             
  577.             fill(new Rect(half(p0.left + p0.right), a, p0.right, a));
  578.             fill(new Rect(half(p1.left + p1.right), b, p1.left, b));
  579.             fill(new Rect(p0.right, a, p0.right, b));
  580.         }
  581.     }
  582.     
  583.     // 領域分割
  584.     private static function split(rect:Rect, ...a):Array
  585.     {
  586.         if ((rect.right  - rect.left < MARGIN * 2) ||
  587.             (rect.bottom - rect.top < MARGIN * 2))
  588.         {
  589.             return [rect];
  590.         }
  591.         else
  592.         {
  593.             var rectA:Rect;
  594.             var rectB:Rect;
  595.             
  596.             // 1/2の確率で横か縦に分割
  597.             if (randomRange(02) == 0)
  598.             {
  599.                 // 横に分割
  600.                 
  601.                 var height:int = randomRange(rect.top + MARGIN, rect.bottom - MARGIN);
  602.                 
  603.                 rectA = new Rect(rect.left, rect.top, rect.right, height);
  604.                 rectB = new Rect(rect.left, height, rect.right, rect.bottom);
  605.             }
  606.             else
  607.             {
  608.                 // 縦に分割
  609.                 
  610.                 var width:int = randomRange(rect.left + MARGIN, rect.right - MARGIN);
  611.                 
  612.                 rectA = new Rect(rect.left, rect.top, width, rect.bottom);
  613.                 rectB = new Rect(width, rect.top, rect.right, rect.bottom);
  614.             }
  615.             
  616.             return flatten([rectA, rectB].map(split));
  617.         }
  618.     }
  619. }
  620. // 標準で付いてるRectangleだとコンストラクタで右下のPointが指定できないから使いづらい
  621. class Rect
  622. {
  623.     public var left:int;
  624.     public var right:int;
  625.     public var top:int;
  626.     public var bottom:int;
  627.     
  628.     public function Rect(left:int = 0, top:int = 0, right:int = 0, bottom:int = 0):void
  629.     {
  630.         this.left = left;
  631.         this.top = top;
  632.         this.right = right;
  633.         this.bottom = bottom;
  634.     }
  635. }
noswf
Get Adobe Flash Player