スポンサーサイト

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

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

画像をタイル状に分割する

一枚の画像をタイル状に分割するサンプルです。
横/縦の分割数を入力して「分割」ボタンを押すと、画像が分割されます。




分割した画像は、ちょっとクリアっぽい加工をしたムービークリップにして、マウスでドラッグできるよーになってマス。

分割元となる画像はムービークリップとしてステージに配置しています。画像のクリッピングは、bitmap#draw()を使ってマス。

このサンプルのActionScriptはこんなカンジです。

import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.geom.ColorTransform;
import flash.filters.BevelFilter;

// 分割数の初期値
col_txt.text = "12";
row_txt.text = "9";
// 分割ボタン
split_btn.onRelease = doSplit;
// 分割したムービークリップの配列
var tileArray:Array = new Array();
// クリッピング用オブジェクト
var ct:ColorTransform = new ColorTransform();
var rect:Rectangle = new Rectangle(0, 0, 0, 0);
var mtx:Matrix = new Matrix();

// 分割したムービークリップを全消去します。
function clearImages() {
for (var i:String in tileArray) {
tileArray[i].removeMovieClip();
}
tileArray = new Array();
// 元画像のアルファを戻す
image_mc._alpha = 100;
}
// 画像をタイル状に分割します。
function doSplit() {
// 分割ムービークリップの削除
clearImages();
// 分割数
var colCnt:Number = col_txt.text;
var rowCnt:Number = row_txt.text;
// 分割ムービークリップの幅/高さ
var w:Number = image_mc._width / colCnt;
var h:Number = image_mc._height / rowCnt;
// グラデーション用マトリックス
var go:Number = 1;
var gw:Number = w - 2 * go;
var gh:Number = h - 2 * go;
var gMtx:Matrix = new Matrix();
gMtx.createGradientBox(gw, gh, Math.PI / 2);
// ハイライト用マトリックス
var ho:Number = 1;
var hw:Number = w - 2 * ho;
var hh:Number = Math.round(h * 0.4);
var hMtx:Matrix = new Matrix();
hMtx.createGradientBox(hw, hh, Math.PI / 2);
// 分割処理
for (var iy:Number = 0; iy < rowCnt; iy++) {
for (var ix:Number = 0; ix < colCnt; ix++) {
// 画像データの切り出し
var bitmap:BitmapData = clip(image_mc,
w * ix,
h * iy,
w,
h);
// ムービークリップ作成
var d:Number = _root.getNextHighestDepth();
var mc:MovieClip
= _root.createEmptyMovieClip("tile_" + d, d);
// 切り出した画像をムービークリップに描画
mc.beginBitmapFill(bitmap);
mc.moveTo(0, 0);
mc.lineTo(0, h);
mc.lineTo(w, h);
mc.lineTo(w, 0);
mc.lineTo(0, 0);
mc.endFill();
// グラデーション
mc.beginGradientFill("linear",
[0x000000, 0xFFFFFF, 0xFFFFFF],
[60, 0, 60],
[0, 127, 255],
gMtx);
mc.moveTo(go, go);
mc.lineTo(go, go + gh);
mc.lineTo(go + gw, go + gh);
mc.lineTo(go + gw, go);
mc.lineTo(go, go);
mc.endFill();
// ハイライトの描画
mc.beginGradientFill("linear",
[0xFFFFFF, 0xFFFFFF],
[95, 20],
[0, 255],
hMtx);
mc.moveTo(ho, ho);
mc.lineTo(ho, ho + hh);
mc.lineTo(ho + hw, ho + hh);
mc.lineTo(ho + hw, ho);
mc.lineTo(ho, ho);
mc.endFill();
// 位置
mc._x = image_mc._x + w * ix;
mc._y = image_mc._y + h * iy;
// ドラッグ可能にする
mc.onPress = function() {
this.startDrag();
}
mc.onRelease = mc.onReleaseOutside = function() {
this.stopDrag();
}
// 作成したムービークリップを配列に追加
tileArray.push(mc);
}
}
// 元画像のアルファを変更する
image_mc._alpha = 25;
}
// 指定した位置/サイズで画像をクリッピングします。
function clip(src:Object,
x:Number,
y:Number,
w:Number,
h:Number):BitmapData {
// 切り取る矩形
rect.x = 0;
rect.y = 0;
rect.width = w;
rect.height = h;
// 元画像を移動
mtx.tx = -x;
mtx.ty = -y;
// 切り取り
var bitmap:BitmapData = new BitmapData(w, h, true);
bitmap.draw(src, mtx, ct, "normal", rect, true);
return bitmap;
}
image_mcというのが元画像のムービークリップで、col_txt, row_txt, split_btnは、2つの入力欄と「分割」ボタンです。

一番下のclipメソッドは、指定したムービークリップ(やら画像やら)を任意の位置/サイズで切り出します。戻り値はBitmapDataオブジェクトです。ココでBitmapData#drawを使ってます。Matrixで平行移動して(位置あわせ)、Rectangleでdrawするサイズを設定ってカンジですね。

doSplit()が、「分割」ボタンを押したときに呼び出されるメソッドで、for文使って次々とclipを呼び出して画像を分割して、ムービークリップ作って、画像貼り付けて、ってやってマス。

単にタイル状に分割したムービークリップを作るだけなら、clip()でBitmapData作った後はMovieClip#attachBitmap使った方がラクそうですが、グラデーションやらハイライトやらつけたいのでココではMovieClip#bitmapFill使ってマス。2つのMovieClip#beginGradientFillは、タイルっぽく見せるための加工デス。

作ったムービークリップのonPressでstartDrag()、onReleaseでstopDrag()をすることで、マウスでつかめるよーにしています。

スポンサーサイト

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

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

円筒っぽい画像表示

四枚の画像を円筒(円柱?)に貼り付けたように表示するサンプルを作ってみました。




画像をスライスして変形させるエントリと同じように、元の画像をスライスしたムービークリップを作って、それらの位置とサイズを調整してソレっぽくしています。

使ってる画像は、画像をスライスして変形させるエントリと同じものですが、今回は縦にスライスしています。

今回は見え方的にはカタチが変わらないので位置とサイズ(線ムービークリップの高さ)はあらかじめ計算しておいて、回転を表現するために線ムービークリップの配列から表示する部分を取り出して、ソレにあてはめるという方法でやっています。

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 line_array:Array = createLineImagesArray(imageIdArray);
// 表示位置
var oX:Number = 200;
var t:Number = 50;
// 視点からの距離
var d:Number = 300;
// 回転速度係数
var speed:Number = 0.05;
// 表示開始インデックス
var index:Number = 0;
// 表示位置情報配列
var info_array:Array = createInfoArray();
// 表示
showImage();
// フレーム毎の処理
function onEnterFrame() {
var len:Number = line_array.length;
var dX:Number = _xmouse - oX;
index += Math.round(dX * speed);
if (index < 0) {
index = len + index;
}
if (index >= len) {
index -= len;
}
showImage();
}
// 画像を表示します。
function showImage() {
// いったんすべて非表示にする
hideImage();
// 表示する線ムービークリップの配列
var mc_array:Array = getLineArray(index, info_array.length);
var range:Number = mc_array.length;
for (var i:Number = 0; i < range; i++) {
// 表示位置情報にしたがって線ムービークリップを表示
var info:Object = info_array[i];
var mc:MovieClip = mc_array[i];
mc._x = info.x;
mc._height = info.height;
mc._y = info.y;
mc._visible = true;
}
}
// 表示位置情報の配列を生成し、戻します。
function createInfoArray():Array {
var array:Array = new Array();
var tt:Number = t;
var td:Number = d;
var toX:Number = oX;
// 円周
var len:Number = line_array.length;
// 半径
var r:Number = len / (2 * Math.PI);
// 開始角度
var startRad:Number = Math.asin(r / (d + r));
// 表示角度
var rangeRad:Number = Math.PI - 2 * startRad;
// 表示長
var range:Number = len * rangeRad / (2 * Math.PI );
// オリジナルの高さ
var orgH:Number = line_array[0]._height;
// オリジナルの幅
var orgW:Number = line_array[0]._width;
// 角度ごとの表示位置とサイズ
for (var i:Number = 0; i < range; i++) {
var info:Object = new Object();
// 角度
var rad:Number = startRad + 2 * Math.PI * i / len;
// スクリーンからの奥行き
var z:Number = r - r * Math.sin(rad);
// 縮小率
var s:Number = td / (td + z);
// x座標
info.x = Math.round(toX - r * Math.cos(rad) * s - orgW / 2);
// 高さ
info.height = orgH * s;
// y座標
info.y = tt + (orgH - info.height) / 2;
array.push(info);
}
return array;
}
// 画像を非表示にします。
function hideImage() {
for (var i:String in line_array) {
var mc:MovieClip = line_array[i];
mc._visible = false;
}
}
// 指定したインデックスから、線画像の配列を戻します。
function getLineArray(idx:Number, len:Number):Array {
var maxLength:Number = line_array.length;
var array:Array = new Array();
var endIndex:Number = idx + len;
if (endIndex > maxLength) {
endIndex = maxLength;
}
for (var i:Number = idx; i < endIndex; i++) {
array.push(line_array[i]);
}
if (array.length < len) {
endIndex = len - array.length;
for (var i:Number = 0; i < endIndex; i++) {
array.push(line_array[i]);
}
}
return array;
}
// 指定した識別子の配列から、短冊状にした画像の配列を戻します。
function createLineImagesArray(idArray:Array):Array {
var lineMCArray:Array = new Array();
for (var i:Number = 0; i < idArray.length; i++) {
// ビットマップデータをロード
var bitmap:BitmapData = BitmapData.loadBitmap(idArray[i]);
// 線ムービークリップの配列を結果に追加
lineMCArray
= lineMCArray.concat(createVerticalLineArray(bitmap));
}
return lineMCArray;
}
// 指定したビットマップから垂直線ムービークリップの配列を戻します。
function createVerticalLineArray(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, 1, src.height);
for (var i:Number = 0; i < src.width; i++ ) {
// 縦1ピクセルのBitmapDataを切り出す
var bitmap:BitmapData = new BitmapData(1, src.height);
matrix.tx = -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.orgH = line_mc._height;
line_mc._visible = false;
line_mc._width = 1;
// 配列にムービークリップを追加
mcArray.push(line_mc);
}
return mcArray;
}
imageIdArrayにセットしている"flower.png", "pudding.png", "bag.png", "egg.png"は、表示する画像の識別子デス。

画像のスライスは、createLineImageArrayメソッドとcreateVerticalLineArrayメソッドでやっています。createLineImageArrayで、imageIdArrayにセットされてる識別子の画像をひとつずつ読み込んで、createVerticalLineArrayで各画像を縦線ムービークリップにスライスしています。

スライスしたムービークリップ数(=全画像を横に並べたときの幅)を円筒の円周としているので、ソレを2πで割ったものが円筒の半径デス。

変数dが視点から円筒の一番手前までの距離で、dと半径から表示する線ムービークリップの数や線ムービークリップの位置と高さが求まりマス。
そのへんは、createInfoArrayメソッドで計算して、info_arrayにセットしています。info_arrayはObjectの配列で、x座標、高さ、y座標を持たせています。

onEnterFrameで、マウスカーソルのx座標から表示開始インデックス(一番左に表示される線ムービークリップのインデックス)を決定して、showImageメソッドで、さきほどのinfo_arrayを使ってそれぞれの位置と高さを設定しています。

画像が円状につながってるようにしたいので、4番目の画像の右に一番目の画像がくるようにgetLineArrayで配列から表示する分だけ切り出しています。

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

2007.05.13 | | Comments(1) | Trackback(0) | Flash/ActionScript

ブラーを使った奥行き表現

ムービークリップの奥行きにあわせてブラーの強さを変えて遠近感を出すサンプルを作ってみました。




マウスのボタン押下でズームイン、離すとズームアウトします。あと、マウスカーソルの位置に合わせて、x座標/y座標も変化します。
再配置ボタンを押すとムービークリップをテキトーにちらかして置き直します。

ムービークリップの配置ですが、x座標/y座標に関しては乱数をつかってテキトーに散らばせています。z座標は、(仮想の)スクリーンからの最大距離(サンプルでは20)と階層の数(サンプルでは6階層)から等間隔に決めています。

そんで、depthをイロイロする手間をはぶくために奥のヤツからgetNextHighestDepth()とattachMovieを使ってムービークリップを作っています。

遠近処理のほーは、各ムービークリップのz座標から位置と大きさとブラーの強さを決定して適用しています。また、視点に近づきすぎたムービークリップは非表示にしています。

スクリプトのほーはこんなカンジです。

import flash.filters.BlurFilter;
// 同階層に置くムービークリップ数
var mcCnt:Number = 2;
// 階層数
var layerCnt:Number = 6;
// ムービークリップの配列
var mc_array:Array = new Array();
// スクリーンまでの距離
var d:Number = 20;
// スクリーンからの最大深度
var maxZ:Number = 20;
// ブラー係数
var blur:Number = 0.5;
// 原点
var oX:Number = Stage.width / 2;
var oY:Number = Stage.height / 2;
// ズーム処理をするか?
var zooming:Boolean = false;
// ズーム値
var zoom:Number = 0;
// フレーム毎の処理
function onEnterFrame() {
// ズーム
zoom += zooming ? 1 : -1;
if (zoom < 0) {
zoom = 0;
} else if (zoom > maxZ) {
zoom = maxZ;
}
// マウスカーソルにあわせて移動
var dx:Number = _xmouse - Stage.width / 2;
var dy:Number = _ymouse - Stage.height / 2;
for (var i:Number = 0; i < mc_array.length; i++) {
var mc:MovieClip = mc_array[i];
mc.tX = -dx;
mc.tY = -dy;
mc.tZ = -zoom;
}
// 遠近処理
perspective();
}

// 初期化
init();
// クリックイベント用スクリーン
var screen_mc:MovieClip
= _root.createEmptyMovieClip("screen_mc",
_root.getNextHighestDepth());
screen_mc.beginFill(0x000000, 0);
screen_mc.moveTo(0, 0);
screen_mc.lineTo(0, Stage.height);
screen_mc.lineTo(Stage.width, Stage.height);
screen_mc.lineTo(Stage.width, 0);
screen_mc.lineTo(0, 0);
screen_mc.endFill();
screen_mc.onPress = function() {
zooming = true;
}
screen_mc.onRelease = function() {
zooming = false;
}
screen_mc.onReleaseOutside = function() {
zooming = false;
}
// 再配置ボタン
var reset_btn:MovieClip
= _root.attachMovie("RESET_BTN",
"reset_btn",
_root.getNextHighestDepth());
reset_btn._x = 10;
reset_btn._y = 10;
reset_btn.onRelease = init;
// 初期化処理
function init():Void {
for (var i:Number = 0; i < mc_array.length; i++) {
var mc:MovieClip = mc_array[i];
mc.removeMovieClip();
}
mc_array = new Array();
// z座標を持つムービークリップを生成する。
var dz:Number = maxZ / (layerCnt - 1);
for (var i:Number = layerCnt - 1; i >= 0; i--) {
// z座標
var z:Number = i * dz;
// 階層内にムービークリップ生成
for (var j:Number = 0; j < mcCnt; j++) {
var depth:Number = _root.getNextHighestDepth();
var mc:MovieClip
= _root.attachMovie("JIEN_MC", "mc_" + depth, depth);
// 座標設定
mc.orgZ = z;
mc.orgX = Math.random() * Stage.width * 1.5
- Stage.width / 3.0;
mc.orgY = Math.random() * Stage.height * 1.5
- Stage.height / 3.0;
mc.tX = 0;
mc.tY = 0;
mc.tZ = 0;
mc_array.push(mc);
}
}
// 遠近処理
perspective();
}
// 遠近処理
function perspective() {
for (var i:String in mc_array) {
var mc:MovieClip = mc_array[i];
var z:Number = mc.orgZ + mc.tZ;
if (z > -d + 1) {
var s:Number = d / (d + z);
// 位置
mc._x = (mc.orgX + mc.tX - oX) * s + oX;
mc._y = (mc.orgY + mc.tY - oY) * s + oY;
// 大きさ
mc._xscale = s * 100;
mc._yscale = s * 100;
// ブラー
var b:Number = Math.abs(z * blur);
var filter:BlurFilter = new BlurFilter(b, b);
mc.filters = [filter];
mc._visible = true;
} else {
mc._visible = false;
}
}
}
init()メソッドに、ムービークリップを生成して3次元空間上に配置する処理を記述しています。すでに配置済みだったらソレを消去して、layerCntで指定された階層の奥のほーからムービークリップを生成します。"JIEN_MC"は配置するムービークリップシンボルの識別子です。

orgX, orgY, orgZというのが3次元空間上の座標です。orgZは何階層目のムービークリップかで決定しています。orgX/orgYは、ステージの1.5倍の広さにランダムで配置します。
tX, tY, tZというのは、マウスの動きやクリックでの変化量です。init()内ではいずれの値も0です。
生成したムービークリップはmc_arrayという配列に保持しています。

perspective()メソッドが遠近感をつける処理です。
dは視点からスクリーンまでの距離で、ムービークリップのz座標が視点から1以下になったら非表示にしています。

奥行きによる拡大/縮小は
d / (d + z)
で計算しています。位置に関しては、ステージの中心からの拡大/縮小、大きさは_xscale/_yscaleプロパティを設定しています。

ブラーは、BlurFilterを使っています。BlurFilterに設定する値をz座標に比例するようにしています。

移動処理はonEnterFrameでやってます。ズームイン/アウトはtZを変化させて、マウスカーソルにあわせた動きはtX, tYを変化させて、先ほどのperspective()メソッドを呼んでいます。

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

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

«  | HOME |  »

プロフィール

HundredthMonkey

Author:HundredthMonkey
プログラマ。

ブロとも申請フォーム

この人とブロともになる

メールフォーム

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

ブログ内検索


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