2008-10-26 メタボールにチャンレジしてみたよ(2)
2008-10-23 メタボールにチャレンジしてみたよ
■[as3][flash]メタボールにチャレンジしてみたよ
Tweenerを使って動きを作っていくとシャキーンという感じの動きを簡単に作れるのですが、
慣れてくると少し有機的な動きを取り入れてみたいという衝動に駆られます。
ということで、今回は「メタボール」に挑戦してみました。
メタボールって言葉自体はあまり馴染みがないかもしれませんが、ボールが滑らかにくっついたり離れたりするデモを見た事ある人は結構いるのではないかと思います。
今回チャレンジしたのは2Dメタボールです。3Dは実装が大変そうなのでやめました。
参考にしたのは、mysketch.blog 炎の作成(1):メタボールの作成という記事です。
というか実装の方針は、ほとんどそのままです。
作成したサンプルではマウスを追跡するボールを時間差で動かしています。ボール自体は中心から外側に向かってアルファ値を滑らかに変化させており、このボールをメタボールとして描画しています。
描画の方法はいたって単純で、アルファが閾値以下の場合は白、閾値以上の場合は黒に色の置き換えをするだけです。この置き換えは、BitmapDataのpaletteMap()で実現できます。
今回は、メタボールの基本的な実装方法を確認しただけで終わりましたが次回以降では、メタボールを使って少し凝った表現を何か作ってみたいと思います。
参考
2008-09-07 BitmapDataを使ったモザイクエフェクト
■[as3][actionscript] BitmapDataを使ったモザイクエフェクト
最近仕事で忙殺されていて、趣味のプログラムを全然書いてなかったので久しぶりに書いてみました。
作ってみたのは、スライドショーに使えそうなモザイクエフェクトです。
まず、画像を縮小コピーします。縮小コピーするとその縮小率に応じて元画像より画素が減ります。これを元の大きさに拡大すると減った分の画素が縮小した時に残った画素で埋められるためモザイク状の画像になります。
ソースコード
以下、コードです。Main.asがスライドショー本体で、MozaicEffect.asがモザイクエフェクトのコードです。
//Main.as package { import flash.display.*; import flash.geom.*; import flash.events.*; import flash.utils.*; import flash.ui.*; [SWF(width="600", height="600", backgroundColor="#000000", frameRate="30")] public class Main extends Sprite { [Embed(source="sample1.png")] public var Sample1:Class; [Embed(source="sample2.png")] public var Sample2:Class; private var currentBitmap:Bitmap; private var imageList:Array; private var currentIndex:int; private var showEffect:MozaicEffect; private var hideEffect:MozaicEffect; public function Main() { stage.addEventListener(KeyboardEvent.KEY_DOWN, handlerKeydown); stage.addEventListener(MouseEvent.CLICK, handlerClick); initImageList(); currentBitmap = new Bitmap(); addChild(currentBitmap); // init effects hideEffect = new MozaicEffect(); hideEffect.useTimer = false; showEffect = new MozaicEffect(); showEffect.reverse = true; showEffect.useTimer = false; // show the first image showNextImage(); } private function initImageList():void { imageList = [new Sample1(), new Sample2()]; currentIndex = -1; } private function showNextImage():void { var prev:BitmapData = currentImageData; currentIndex = (currentIndex + 1) % imageList.length; var next:BitmapData = currentImageData; var self:Main = this; showEffect.source = next; showEffect.addEventListener(Event.COMPLETE, function(e:Event):void { self.currentBitmap.bitmapData = next; if ( self.contains(hideEffect) ) { self.removeChild(hideEffect); } if ( self.contains(showEffect) ) { self.removeChild(showEffect); } }); if ( prev != null ) { hideEffect.source = prev; addChild(hideEffect); hideEffect.addEventListener(Event.COMPLETE, function(e:Event):void { self.addChild(showEffect); showEffect.play(); }); hideEffect.play(); } else { addChild(showEffect); showEffect.play(); } } private function get currentImageData():BitmapData { if ( 0 <= currentIndex && currentIndex < imageList.length ) { return imageList[currentIndex].bitmapData; } return null; } private function handlerKeydown(e:KeyboardEvent):void { if ( e.keyCode == Keyboard.SPACE ) { showNextImage(); } } private function handlerClick(e:MouseEvent):void { showNextImage(); } } }
// MozaicEffect.as package { import flash.events.*; import flash.display.*; import flash.geom.*; import flash.utils.*; public class MozaicEffect extends Sprite { public var endCount:int; public var reverse:Boolean; public var interval:uint; public var useTimer:Boolean; private var counter:int; private var _bgColor:uint; private var _source:BitmapData; private var buffer:Bitmap; private var timer:Timer; public function MozaicEffect() { endCount = 12; counter = 0; reverse = false; bgColor = 0x000000; useTimer = true; interval = 100; } public function play():void { if ( source != null ) { counter = 0; var bmpData:BitmapData = new BitmapData(source.width, source.height, false, 0x000000); if ( !reverse ) { bmpData.copyPixels(source, new Rectangle(0, 0, source.width, source.height), new Point(0, 0)); } buffer = new Bitmap(bmpData); addChild(buffer); if ( useTimer ) { timer = new Timer(interval, 0); timer.addEventListener(TimerEvent.TIMER, updateDisplay); timer.start(); } else { addEventListener(Event.ENTER_FRAME, updateDisplay); } } } public function stop():void { if ( hasEventListener(Event.ENTER_FRAME) ) { removeEventListener(Event.ENTER_FRAME, updateDisplay); } if ( useTimer ) { timer.removeEventListener(TimerEvent.TIMER, updateDisplay); timer.stop(); } } public function get bgColor():uint { return _bgColor; } public function set bgColor(color:uint):void { color = _bgColor; } public function get source():BitmapData { return _source; } public function set source(data:BitmapData):void { _source = data; } private function mozaic(src:BitmapData, scale:uint):void { var mtrx:Matrix = new Matrix(); mtrx.scale(1.0 / (scale * scale), 1.0 / (scale * scale)); var half:BitmapData = new BitmapData(src.width / scale, src.height / scale, false, 0x000000); half.draw(src, mtrx); var double:uint = scale * scale; mtrx.scale(double * double, double * double); src.draw(half, mtrx); half.dispose(); } private function updateDisplay(e:Event):void { var bmpData:BitmapData = buffer.bitmapData; if ( counter > endCount ) { stop(); if ( !reverse ) { bmpData.fillRect(new Rectangle(0, 0, source.width, source.height), bgColor); } var event:Event = new Event(Event.COMPLETE); dispatchEvent(event); } else { bmpData.copyPixels(source, new Rectangle(0, 0, source.width, source.height), new Point(0, 0)); if ( reverse ) { mozaic(bmpData, endCount - counter + 1); } else { mozaic(bmpData, counter + 1); } } counter++; } } }
2008-08-25 AdvancedDataGridのヘッダに表示される縦線を消す方法
■[flex][as3] AdvancedDataGridのヘッダに表示される縦線を消す方法
AdvancedDataGridのデフォルト設定だと、ヘッダがイケテなくて困った人は多いと思います。

とくに、並び替え機能が不要なときにsorter領域の縦線が消したくなった人は多いと思います。
普通に考えると、sortableColumnsというプロパティをfalseに設定する、もしくはAdvancedDataGridColumnのsortableプロパティをfalseにすれば並び替えができなくなる代わりに縦線は消えるだろうと思います。しかし、この縦線は並び替えを無効にしても残ります。
では、どうすれば良いのか?
ここでのやり取りを追ってみると、AdvancedDataGridのsortExpertModeプロパティを「true」にすれば良いらしいことがわかります。確かに、これを設定すると、

という感じで縦線が消えます。ちなみに、このプロパティをtrueにするとctrl(macではcommand)キーで複数列の並び替えが出来るようになります。つまりAdobe的には、(ctrl押しながらクリック出来る人) = (エキスパート)ということなんでしょうね。
以下余談です。
つい最近、Flex Builder3を入手したのでFlexを触り始めました。起動がもっさりするのが気になりますが概ね快適です。
Flexを触り始めて思ったのが、色々とできそうなんだけど具体的にどうやればいいのかを調べるのが非常に面倒だと感じました。
特に日本語の情報源が乏しく、嵌まった場合にWEBを検索してもあまり有益な情報を得られないのが初心者にはつらい気がします。(FxUGが頼みの綱って感じですね)
というわけで、これからはFlexのTips的な記事も少しずつ書いていきたいなと思います。
サンプルコード
<?xml version="1.0"?>
<!-- charts/AxisRendererStrokes.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Bindable]
private var dataList:Array = [
{col1: 100, col2:200, col3:500},
{col1: 100, col2:200, col3:400},
{col1: 200, col2:200, col3:300},
{col1: 200, col2:200, col3:200},
{col1: 300, col2:200, col3:100}
];
]]>
</mx:Script>
<mx:AdvancedDataGrid designViewDataType="flat" sortableColumns="false" sortExpertMode="true" dataProvider="{dataList}" id="adg1">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="列 1" dataField="col1"/>
<mx:AdvancedDataGridColumn headerText="列 2" dataField="col2"/>
<mx:AdvancedDataGridColumn headerText="列 3" dataField="col3"/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:Application>




