スポンサーサイト

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

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

円筒っぽい画像表示

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




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

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

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

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

コメント

修正しました。

かなり重かったので若干修正しました。

2007-05-19 土 00:51:11 | URL | HundredthMonkey #ZJmJft5I [ 編集]

コメントの投稿


秘密にする

«  | HOME |  »

プロフィール

HundredthMonkey

Author:HundredthMonkey
プログラマ。

ブロとも申請フォーム

この人とブロともになる

メールフォーム

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

ブログ内検索


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