スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--.--.-- | | スポンサー広告

画像をスライスして変形させる

スライスした画像に対して、揺れ/振幅/回転の3種類の変形をするサンプルです。




harayokiさんのバスキュールサイトのツボの所エントリに、スライスしたムービークリップを使って変形するテクニックが解説してあって面白そうだったのでマネしてみました。
といっても、オレが作ったサンプルはかなり泥臭い書き方になってますケド…。

いずれの変形も、元の画像(ムービークリップ)を高さ1のムービークリップに分解してonEnterFrameで位置や幅を変えています。

揺れは、各ムービークリップがサインカーブを描くように_xプロパティを設定しています。フレーム毎に角度を変えて、画像が波打ってるように見せています。

振幅は、揺れとだいたい似たようなカンジなんですが、こっちは幅を変えています。

回転は、表示中の画面の上辺と、次に表示する画像の下辺が90度の角度で接してると仮定して、ソレがグルっと下向きに回転するように変形させています。その際、スライスしたそれぞれのムービークリップの奥行きにあわせて位置と幅を縮小することでパースをつけています。
2枚の画像が接してる辺の奥行きが常に0となるように計算してるので、回転軸は角度によって前後するようなカンジになってます。

今回のサンプルのActionScriptは以下のようなカンジです。

import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.geom.ColorTransform;
import flash.geom.Rectangle;
// 画像の識別子
var imageIdArray:Array = ["flower.png",
"pudding.png",
"bag.png",
"egg.png"];
// 表示位置
var l:Number = 100;
var t:Number = 80;
// 短冊状にした画像の配列
var lineImagesArray:Array = createLineImagesArray(imageIdArray);
// 表示画像インデックス
var index:Number = 0;
// 揺れ速度
var wSpeed:Number = 20;
// 揺れ振幅
var wAmp:Number = 10;
// 振幅速度
var aSpeed:Number = 20;
// 振幅
var aAmp:Number = 50;
// 回転速度
var tSpeed:Number = 3;
// 視点からの距離
var v:Number = 300;

// 回転角
var d:Number = 0;
// ゆれ角度
var wR:Number = 0;
// 振幅角度
var aR:Number = 0;

// 初期表示
showImage();

// 画像選択用ムービークリップ
flower_mc.onRelease = function() {
delete onEnterFrame;
hideImage();
index = 0;
showImage();
}
pudding_mc.onRelease = function() {
delete onEnterFrame;
hideImage();
index = 1;
showImage();
}
bag_mc.onRelease = function() {
delete onEnterFrame;
hideImage();
index = 2;
showImage();
}
egg_mc.onRelease = function() {
delete onEnterFrame;
hideImage();
index = 3;
showImage();
}
// 揺れボタン
wave_btn.onRelease = function() {
_root.onEnterFrame = doWave;
hideImage();
showImage();
}
// 振幅ボタン
amp_btn.onRelease = function() {
_root.onEnterFrame = doAmp;
hideImage();
showImage();
}
// 回転ボタン
turn_btn.onRelease = function() {
d = 0;
_root.onEnterFrame = doTurn;
}

// 揺れ
function doWave() {
var mcArray:Array = lineImagesArray[index];
for (var i:Number = 0; i < mcArray.length; i++) {
var line_mc:MovieClip = mcArray[i];
line_mc._x = line_mc.orgX
+ Math.sin((wR + i) * Math.PI / 180) * wAmp;
}
wR += wSpeed;
if (wR >= 360) {
wR = 0;
}
}

// 振幅
function doAmp() {
var mcArray:Array = lineImagesArray[index];
for (var i:Number = 0; i < mcArray.length; i++) {
var line_mc:MovieClip = mcArray[i];
var dx:Number = Math.sin((aR + i) * Math.PI / 180) * aAmp;
var w:Number = line_mc.orgW - dx;
line_mc._xscale = 100 * (w / line_mc.orgW);
line_mc._x = line_mc.orgX + dx / 2;
}
aR += aSpeed;
if (aR >= 360) {
aR = 0;
}
}

// 回転
function doTurn() {
// 下側画像
var mcArray1:Array = lineImagesArray[index];
// 上側画像
var mcArray2:Array = lineImagesArray[getNextIndex()];
// 回転の原点y座標
var oY:Number = mcArray1[Math.floor(mcArray1.length / 2)].orgY;
// 頂点の回転半径
var r:Number = Math.sqrt(2) * mcArray1.length / 2;
// 角度を加算
d += tSpeed;
// 頂点y座標
var sY:Number = oY - r * Math.cos((d + 45) * Math.PI / 180);
// 余弦/正弦
var c:Number = Math.cos(d * Math.PI / 180);
var s:Number = Math.sin(d * Math.PI / 180);
// 下側画像の高さ
var l1:Number = mcArray1.length;
// 上側画像の高さ
var l2:Number = mcArray2.length;
// 下側
for (var i:Number = 0; i < l1; i++) {
var line_mc1:MovieClip = mcArray1[i];
// 縮小率
var curt1:Number = v / (v + i * s);
// 位置/幅の調整
line_mc1._y = sY +(i * c * curt1);
line_mc1._width = line_mc1.orgW * curt1;
line_mc1._x = line_mc1.orgX
+ (line_mc1.orgW - line_mc1._width) / 2;
}
// 上側
for (var i:Number = 0; i < l2; i++) {
var line_mc2:MovieClip = mcArray2[l2 - 1 - i];
// 縮小率
var curt2:Number = v / (v + i * c);
// 位置/幅の調整
line_mc2._y = sY - (i * s * curt2);
line_mc2._width = line_mc2.orgW * curt2;
line_mc2._x = line_mc2.orgX
+ (line_mc2.orgW - line_mc2._width) / 2;
line_mc2._visible = true;
}
// 90度回転したら次の画像
if (d > 90) {
_root.showNext();
d = 0;
}
}

// 画像を表示します。
function showImage() {
var mcArray:Array = lineImagesArray[index];
for (var i:String in mcArray) {
var line_mc:MovieClip = mcArray[i];
// 状態を初期化
line_mc._x = line_mc.orgX;
line_mc._y = line_mc.orgY;
line_mc._width = line_mc.orgW;
// 表示
line_mc._visible = true;
}
}

// 次の画像のインデックスを戻します。
function getNextIndex():Number {
var idx:Number = index + 1;
if (idx >= lineImagesArray.length) {
idx = 0;
}
return idx;
}

// 次の画像を表示します。
function showNext() {
hideImage();
index = getNextIndex();
showImage();
}

// 画像を消去します。
function hideImage() {
for (var i:String in lineImagesArray) {
var mcArray:Array = lineImagesArray[i];
for (var j:String in mcArray) {
mcArray[j]._visible = false;
}
}
}

// 指定した識別子の配列から、短冊状にした画像の配列を戻します。
function createLineImagesArray(idArray:Array):Array {
var lineImagesArray:Array = new Array();
for (var i:Number = 0; i < idArray.length; i++) {
// ビットマップデータをロード
var bitmap:BitmapData = BitmapData.loadBitmap(idArray[i]);
// 線ムービークリップの配列を結果に追加
var lineMCArray:Array = createHorizontalLineArray(bitmap);
lineImagesArray.push(lineMCArray);
}
return lineImagesArray;
}

// 指定したビットマップから水平な線ムービークリップの配列を戻します。
function createHorizontalLineArray(src:BitmapData):Array {
var mcArray:Array = new Array();
var matrix:Matrix = new Matrix();
var ct:ColorTransform = new ColorTransform();
var rect:Rectangle = new Rectangle(0, 0, src.width, 1);
for (var i:Number = 0; i < src.height; i++ ) {
// 縦1ピクセルのBitmapDataを切り出す
var bitmap:BitmapData = new BitmapData(src.width, 1);
matrix.ty = -i;
bitmap.draw(src, matrix, ct, "normal", rect, false);
// 切り出したBitmapDataのムービークリップを作成
var depth:Number = _root.getNextHighestDepth();
var line_mc:MovieClip =
_root.createEmptyMovieClip("line_" + depth, depth);
line_mc.attachBitmap(bitmap, 1);
line_mc._x = l;
line_mc.orgX = line_mc._x;
line_mc._y = t + i;
line_mc.orgY = line_mc._y;
line_mc.orgW = line_mc._width;
line_mc._visible = false;
// 配列にムービークリップを追加
mcArray.push(line_mc);
}
return mcArray;
}
imageIdArrayに設定しているのが、ライブラリに入ってる4つの画像の識別子です。ココで指定した識別子の画像を下の方のcraeteLineImagesArrayというメソッドでBitmapDataにして、createHorizontalLineArrayで高さ1ピクセルのムービークリップに切り出しています。

揺れ/振幅/回転は、フレーム毎の動作をそれぞれdoWave(),doAmp(),doTurn()に記述していて、ボタンを押したときにボタンにあった処理を_root.onEnterFrameにディスパッチしています。
スポンサーサイト

テーマ:Flash - ジャンル:コンピュータ

2007.04.28 | | Comments(0) | Trackback(0) | Flash/ActionScript

コメント

コメントの投稿


秘密にする

«  | HOME |  »

プロフィール

HundredthMonkey

Author:HundredthMonkey
プログラマ。

ブロとも申請フォーム

この人とブロともになる

メールフォーム

名前:
メール:
件名:
本文:

ブログ内検索


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。