Cylinder 横にしてみた。
ここのところAS3.0の勉強ができなかったので、
* 復習がてら作成しました。
* テスト用の変数だとか、数値を残したままなので、
* ソースはほんと汚いです
* また、負荷が結構高いのでご注意ください。
*
* 【操作方法】
* マウスドラッグ → 回転、移動
* 白枠をダブルクリック → 等倍拡大
*
/**
* Copyright code ( http://wonderfl.net/user/code )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/u09W
*/
// forked from code's Cylinder
/*
* ここのところAS3.0の勉強ができなかったので、
* 復習がてら作成しました。
* テスト用の変数だとか、数値を残したままなので、
* ソースはほんと汚いです
* また、負荷が結構高いのでご注意ください。
*
* 【操作方法】
* マウスドラッグ → 回転、移動
* 白枠をダブルクリック → 等倍拡大
*
*/
package
{
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import org.libspark.betweenas3.*;
[SWF(width="512",height="512", frameRate="30",backgroundColor="0x000000")]
public class Main extends Sprite
{
//変数
private var centerBase:Sprite;
private var base:Sprite;
private var myWorld:Matrix3D;
private var pictures:Array;
private var PIC_NUM:uint;
private const RADIUS:uint = 500;
private const MARGIN:uint = 20;
private var isMouseDown:Boolean = false;
private var mouseDownX:Number;
private var mouseDownY:Number;
private var degree:Number = 0;
private var cant:Number = 0;
//コンストラクタ
public function Main()
{
//初期化処理
Init();
//ループ処理
addEventListener(Event.ENTER_FRAME, loopHandler);
//リサイズ処理
//マウス処理
stage.addEventListener(MouseEvent.MOUSE_UP, isMouseUpHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, isMouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_MOVE, isMouseMoveHandler);
}
//初期化処理
private function Init():void
{
//ステージの初期化
stage.quality = StageQuality.MEDIUM;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
//消失点・視野角設定
var projection:PerspectiveProjection = this.transform.perspectiveProjection;
projection.projectionCenter = new Point(stage.stageWidth / 2, stage.stageHeight / 2);
projection.fieldOfView = 70;
// projection.focalLength = 500;
//各インスタンスの生成
createWorld();
createPictrues();
}
//3D表現のための空間作成
private function createWorld():void
{
//基準点変更
centerBase = new Sprite();
centerBase.x = stage.stageWidth;
centerBase.y = stage.stageHeight/2;
centerBase.z = 0;
addChild(centerBase);
//3D空間表現のためのオブジェクト
base = new Sprite();
base.x = 0;
base.y = 0;
base.z = 0;
centerBase.addChild(base);
myWorld = base.transform.matrix3D;
}
private function createPictrues():void
{
//読み込む写真の数
PIC_NUM = 207;
//pictureインスタンスを格納する配列の初期化。
pictures = [];
//写真の縦、横の最大値 今は暫時設定しておく → 後で消去
var picW:uint = 320;
var picH:uint = 240;
//面倒な計算とか変数とか用意しておく。
var unit:uint = (RADIUS * 2 * Math.PI / (picH+MARGIN)) >> 0;
var unitRadian:Number = Math.PI * 2 / unit;
var p:picture;
var u:uint;
var v:uint;
var chc:Boolean;
//写真を生成 サンプルとしてspriteを登録するだけにする。
for (var i:uint = 0; i < PIC_NUM; i++)
{
pictures[i] = new picture();
//座標計算
p = pictures[i];
u = i % unit;
v = (i / unit) | 0;
//座標代入
p.x = (-picW-MARGIN)* v;
p.y = RADIUS * Math.cos(unitRadian * u);
p.z = RADIUS * Math.sin(unitRadian * u);
p.rotationX = unitRadian * u / Math.PI * 180+90;
//プロパティへ代入
p.pos = new Vector3D(p.x, p.y, p.z,p.rotationX);
//いったん非表示で登録
p.visible = false;
base.addChildAt(p,i);
//ダブルクリックリスナー登録
p.addEventListener(MouseEvent.DOUBLE_CLICK, PictureClickHandler);
p.doubleClickEnabled = true;
p.useHandCursor = true;
}
}
//ループ処理
private function loopHandler(e:Event):void
{
var p:picture;
var chcPos:Vector3D;
for (var i:uint = 0; i < PIC_NUM; i++)
{
p= pictures[i];
//画面外は表示しない。
chcPos = p.transform.getRelativeMatrix3D(this).position;
if (chcPos.z <-100 || chcPos.x<-600 || chcPos.x>stage.stageWidth+600){
p.visible = false;
}else {
p.visible = true;
}
}
//傾斜角
cant *=0.95;
if (Math.abs(cant) < 0.01) {
cant = 0;
}
//ローテーション
base.rotationX -= (degree+base.rotationX) / 20;
base.x -= cant*2;
centerBase.rotationY = -cant;
}
//
private function PictureClickHandler(e:MouseEvent):void
{
var prePic:picture;
for (var i:uint =0; i <PIC_NUM;i++)
{
prePic = pictures[i] as picture;
if(prePic.isView){
BetweenAS3.tween(prePic,
{z:prePic.pos.z,y:prePic.pos.y,rotationX:prePic.pos.w}, null, 1, null).play();
prePic.isView = false;
}
}
var targetPic:picture = e.currentTarget as picture;
//最前面へ
base.setChildIndex(targetPic, PIC_NUM - 1);
var offsetR:Number = base.rotationX % 360;
BetweenAS3.tween(targetPic,
{y:0, z:0,rotationX:-offsetR},null, 1, null).play();
targetPic.isView = true;
BetweenAS3.tween(base,
{x:-targetPic.pos.x-stage.stageWidth/2}, null, 1, null).play();
}
private function isMouseUpHandler(e:MouseEvent):void
{
isMouseDown = false;
}
private function isMouseDownHandler(e:MouseEvent):void
{
isMouseDown = true;
mouseDownX = mouseX;
mouseDownY = mouseY;
}
private function isMouseMoveHandler(e:MouseEvent):void
{
if(isMouseDown){
degree += ( mouseY - mouseDownY)/100;
cant = -(mouseX - mouseDownX) / stage.stageWidth * 30;
}
}
}
}
import flash.display.*;
import flash.geom.Vector3D;
class picture extends Sprite
{
//プロパティ
public var bmd:BitmapData;
public var pos:Vector3D;
public var isView:Boolean;
//写真の幅はloaderから設定する
//今は暫時設定
private const picW:uint = 320;
private const picH:uint = 240;
//コンストラクタ
public function picture()
{
loadImage();
}
private function loadImage():void
{
//とりあえずグラフィック作るだけ
var pic:Shape = new Shape();
var g:Graphics = pic.graphics;
g.lineStyle(1, 0x000000);
g.beginFill(0xffffff);
g.drawRoundRect(0, 0, picW, picH,10,10);
g.endFill();
//bmd.draw(pic);
addChild(pic);
//基準点を中心へ
pic.x = -picW / 2;
pic.y = -picH / 2;
}
}