/** * 景観マップエディタ * 昔, AmigaのDeluxe Paintの機能をうまく使うと地図を作れたのでその再現。 * なぜフラクタル的になるのか理論的なことはよくわからない。 * 大小の円で高さを増減することでそれっぽい地図データを作成できます。 * ↑: 陸作成 ↓:陸削除 マウスボタン ↑↓の逆 * ←:サイズ縮小 →:サイズ拡大 * z:ランダムモード切替 */ package { import flash.display.*; public class LandscapeMapEditor extends Sprite { public function LandscapeMapEditor() { initialize(this); } } } import flash.display.*; import flash.geom.*; import flash.filters.*; import flash.events.*; var main:Sprite; var w:int = 465; var h:int = 465; var texture:BitmapData = new BitmapData(w, h, false, 0); var hmap:BitmapData = new BitmapData(w, h, false, 0); var bitmap:Bitmap = new Bitmap(texture); var render:Shape = new Shape(); function initialize(sprite:Sprite):void { main = sprite; new Key(main.stage); main.addChild(bitmap); main.addChild(render); main.addEventListener("enterFrame", update); // height map hmap.perlinNoise(w*0.5, h*0.5, 10, Math.random()*0xffffffff, true, false, 0, true); hmap.colorTransform(hmap.rect, new ColorTransform(1.5, 1.5, 1.5, 1, -64, -64, -64, 0)); var mat:Matrix = new Matrix(); mat.createGradientBox(256,1,0,0,0); render.graphics.clear(); var gradation:* = { color:[0x000080,0x0066ff,0xcc9933,0x00cc00,0x996600,0xffffff], alpha:[100, 100, 100, 100, 100, 100], ratio:[0, 96, 96, 128, 168, 224] }; render.graphics.beginGradientFill("linear", gradation.color, gradation.alpha, gradation.ratio, mat); render.graphics.drawRect(0,0,256,1); render.graphics.endFill(); gmap.draw(render); for (var i:int=0; i<256; i++) { var col:uint = gmap.getPixel(i, 0); mapR[i] = col & 0xff0000; mapG[i] = col & 0x00ff00; mapB[i] = col & 0x0000ff; } // gmap.dispose(); mat.identity(); } var gmap:BitmapData = new BitmapData(256,1,false,0); var mapR:Array=new Array(256); var mapG:Array=new Array(256); var mapB:Array=new Array(256); var smap:BitmapData = new BitmapData(w, h, false, 0); var colorTransform:ColorTransform = new ColorTransform(4, 4, 4, 1, 160, 160, 160, 0); var convolutionFilter:ConvolutionFilter = new ConvolutionFilter(3,3,[-1,-1,0,-1,0,1,0,1,1],1,0,true,true); var size:int = 100; var add:Boolean = true; var random:Boolean = true; function update(e:Event):void { if(Key["left"]) size -= 10; if(Key["right"]) size += 10; if(Key["up"]) add = true; if(Key["shot"]) random = !random; if(Key["down"]) add = false; circle(bitmap.mouseX, bitmap.mouseY, add, size); texture.paletteMap(hmap, hmap.rect, hmap.rect.topLeft, mapR, mapG, mapB); // shading smap.applyFilter(hmap, hmap.rect, hmap.rect.topLeft, convolutionFilter); texture.draw(smap, null, colorTransform, "multiply"); } /** * @param int x x座標 * @param int y y座標 * @param int add 追加する値 1 or -1をとりあえず使う * @param int r 半径 */ function circle(x:int, y:int, add:Boolean, r:int):void { if(random) { x += Math.random()*r*2-r; y += Math.random()*r*2-r; } render.graphics.clear(); render.graphics.beginFill(0x010101); render.graphics.drawCircle(x,y, r); render.graphics.endFill(); if(!Key["mouse"] && !Key["up"] && !Key["down"]) { return; } if(int(add) ^ int(Key["mouse"])){ hmap.draw(render,null,null,"add"); } else { hmap.draw(render,null,null,"subtract"); } render.graphics.clear(); } class Key { function Key(stage:Stage) { var kmap:Object = {37:"left", 38:"up",39:"right",40:"down",90:"shot",13:"start"}; for each(var i:String in kmap) Key[i]=false; Key["mouse"]=false; stage.addEventListener("mouseDown",function(e:MouseEvent):void { Key["mouse"]=true; Key["click"]=true; }); stage.addEventListener("mouseUp",function(e:MouseEvent):void { Key["mouse"]=false; }); stage.addEventListener("keyDown",function(e:KeyboardEvent):void { if(e.keyCode in kmap) Key[kmap[e.keyCode]] = true; }); stage.addEventListener("keyUp",function(e:KeyboardEvent):void { if(e.keyCode in kmap) Key[kmap[e.keyCode]] = false; }); } } LandscapeMapEditor